from machine import Pin, Timer,ADC
import time

# Display 7 segmentos
segment_pins = [Pin(i, Pin.OUT) for i in range(0, 7)]
# Pines de activacion para cada digito
enable_pins = [Pin(i, Pin.OUT) for i in range(7, 11)]
# Boton aumentar
button_up = Pin(11, Pin.IN, Pin.PULL_DOWN)
# Boton restar
button_down = Pin(12, Pin.IN, Pin.PULL_DOWN)

# Boton de inicio
button_start = Pin(14, Pin.IN, Pin.PULL_DOWN)

ventilador_pin = Pin(13, Pin.OUT)  # Pin para controlar el ventilador

# Mapeo para cada digito
digit_to_segments = [
    0b0111111,  # 0
    0b0000110,  # 1
    0b1011011,  # 2
    0b1001111,  # 3
    0b1100110,  # 4
    0b1101101,  # 5
    0b1111101,  # 6
    0b0000111,  # 7
    0b1111111,  # 8
    0b1101111   # 9
]

# Variable para el contador segundos
seconds = 0
# Variable para el contador minut
minutes = 0
# Variable para indicar si el temporizador esta contando
mostrando_temperatura = False

contador=0
# Tiempo de rebote
DEBOUNCE_TIME = 300
# Tiempo limite para soportar el rebote
last_button_up_time = 0
last_button_down_time = 0
temperatura_referencia = 23.0
last_button_start_time = 0


# Funcion para el activador de digitos
# Recibe un array de tamano 4 para activar cada display
# Millares Centenas Decenas Unidades
def enabler(digits):
    for i in range(4):
        enable_pins[i].value(digits[i])

# Funcion para mostrar el display
def show_display(value):
    segments = digit_to_segments[value]
    for i in range(7):
        segment_pins[i].value(not (segments >> i) & 1)

# Funcion del boton para aumentar el contador
def button_up_handler(pin):
    
    # Condicional para evitar el rebote 
    # Rebote: Evitar que el contador avance en valores muy altos
    global seconds, minutes, last_button_up_time, counting,mostrando_temperatura
    # Toma el tiempo actua en el que fue presionado el boton
    current_time = time.ticks_ms()
    # Hace una resta entre el tiempo que fue presionado y el tiempo de presionado la ultima vez
    if time.ticks_diff(current_time, last_button_up_time) > DEBOUNCE_TIME and mostrando_temperatura:
        # Si el tiempo esta dentro del valor permitido y no esta contando
        # Aumenta el contador
        seconds += 50
        if seconds > 99:
            seconds = 0
            minutes += 1
            if minutes > 99:
                minutes = 0
        last_button_up_time = current_time

# Funcion para el boton de disminuir el contador
def button_down_handler(pin):
    global seconds, minutes, last_button_down_time, counting, mostrando_temperatura
    current_time = time.ticks_ms()
    if time.ticks_diff(current_time, last_button_down_time) > DEBOUNCE_TIME and mostrando_temperatura:
        seconds -= 50
        # Disminuye el contador
        if seconds < 0:
            seconds = 50
            if minutes == 0:
                minutes = 99
            else:
                minutes -= 1
        last_button_down_time = current_time
    

# Funcion para el boton de iniciar el timer
def button_start_handler(pin):
    global seconds, minutes, last_button_start_time, mostrando_temperatura, timerM, pause,temperatura_referencia,temperatura,contador
    current_time = time.ticks_ms()
    if time.ticks_diff(current_time, last_button_start_time) > DEBOUNCE_TIME :
        contador = contador + 1;
        mostrando_temperatura = True
        if(contador ==  1):
            temperatura_referencia_str = "{:.2f}".format(temperatura_referencia)
            partes_temperatura_referencia = temperatura_referencia_str.split(".")

            antes_punto_referencia = int(partes_temperatura_referencia[0])
            despues_punto_referencia = int(partes_temperatura_referencia[1])
            minutes = antes_punto_referencia
            seconds = despues_punto_referencia
            timerM.deinit()

        else :
            if (contador == 2):
                time_str = "{}.{}".format(minutes, seconds)
                temperatura_referencia = float(time_str)
                print("Esta es  la nueva temperatura de referencia:", temperatura_referencia)
                timerM.init(period=300, mode=Timer.PERIODIC, callback=temporizador)
                contador = 0
                mostrando_temperatura = False
        last_button_start_time = current_time

def temporizador(timerM):
    global seconds, minutes,mostrando_temperatura
    sensor_temp = ADC(4)  # Sensor interno de temperatura
    factor_16 = 3.3 / 65535
    voltaje = sensor_temp.read_u16() * factor_16
    temperatura = (27 - (voltaje - 0.706) / 0.001721)
    temperatura_str = "{:.2f}".format(temperatura)
    partes_temperatura = temperatura_str.split(".")

    antes_punto = int(partes_temperatura[0])
    despues_punto = int(partes_temperatura[1])

    seconds=despues_punto
    minutes=antes_punto

    print(temperatura_str)
    print("Temperatura de referencia: {:.2f} °C".format(temperatura_referencia))
        
    # Encender o apagar el ventilador según la temperatura y la referencia
    if temperatura >= temperatura_referencia:
        ventilador_pin.value(1)  # Encender ventilador
    elif temperatura < temperatura_referencia - 0.5:
        ventilador_pin.value(0)  # Encender ventilador
    update_display()
    
# Funcion para actualizar el contador 
def update_display():
    # Obtiene el valor actual del contador
    value = seconds
    value2 = minutes
    # Unidades
    # Cuando enabler esta con todo el array en 0: Se desactivan todos los digitos
    enabler([0, 0, 0, 0])
    # Se hace una divison entre 10 para obtener las unidades
    show_display(value%10)
    # Se actualiza el valor correspondiente a la division
    value = value // 10
    # Se activa el primer display para mostrar unidades
    enabler([0, 0, 0, 1])
    time.sleep_ms(5)
    # Decenas
    enabler([0, 0, 0, 0])
    show_display(value%10)
    value = value // 10
    enabler([0, 0, 1, 0])
    time.sleep_ms(5)
    # Centenas
    enabler([0, 0, 0, 0])
    show_display(value2%10)
    value2 = value2 // 10
    enabler([0, 1, 0, 0])
    time.sleep_ms(5)
    # Millares
    enabler([0, 0, 0, 0])
    show_display(value2%10)
    value2 = value2 // 10
    enabler([1, 0, 0, 0])
    time.sleep_ms(5)

# Declaracion de las interrupciones para las entradas de los botones
button_up.irq(trigger=Pin.IRQ_FALLING, handler=button_up_handler)
button_down.irq(trigger=Pin.IRQ_FALLING, handler=button_down_handler)
button_start.irq(trigger=Pin.IRQ_FALLING, handler=button_start_handler)
timerM = Timer()   
timerM.init(period=300, mode=Timer.PERIODIC, callback=temporizador)

while (True):
    update_display()
BOOTSELLED1239USBRaspberryPiPico©2020RP2-8020/21P64M15.00TTT