from machine import Pin, SPI
import machine
import neopixel
import time
from ili9341 import Display, color565
from time import sleep
spi = machine.SPI(2, baudrate=32000000, sck=Pin(18), mosi=Pin(23), miso=Pin(19))
display = Display(spi, dc=Pin(33), cs=Pin(5), rst=Pin(32))
display.clear(color565(64, 0, 255)) # Fondo azul oscuro
pin = machine.Pin(21)
NUMERO_PIXELES = 64
np = neopixel.NeoPixel(pin, NUMERO_PIXELES)
colores = {
"rojo": (255, 0, 0),
"verde": (0, 255, 0),
"morado": (200, 0, 255),
"azul": (0, 0, 255),
"negro": (0, 0, 0), # Para apagar el LED
"blanco": (255, 255, 255) # Color blanco para el LED
}
# Variables de control de la animación
puerta_abriendo = False
puerta_cerrando = False
puerta_posicion = 50 # Posición inicial de la puerta
garage_width = 140
garage_height = 100
garage_x = 50
garage_y = 50
step = 5 # Paso de movimiento de la puerta
# Temporizador para actualizar la animación
temporizador_animacion = machine.Timer(-1)
def actualizar_animacion(timer):
global puerta_posicion, puerta_abriendo, puerta_cerrando
if puerta_abriendo:
if puerta_posicion < garage_x + garage_width:
display.fill_rectangle(puerta_posicion, garage_y, step, garage_height, color565(0, 0, 0)) # Borra la parte que se mueve
puerta_posicion += step
else:
puerta_abriendo = False # La animación ha terminado
elif puerta_cerrando:
if puerta_posicion > garage_x:
puerta_posicion -= step
display.fill_rectangle(puerta_posicion, garage_y, step, garage_height, color565(255, 255, 255)) # Dibuja la puerta
else:
puerta_cerrando = False # La animación ha terminado
def iniciar_animacion_abriendo():
global puerta_abriendo, puerta_cerrando
puerta_abriendo = True
puerta_cerrando = False
temporizador_animacion.init(period=100, mode=machine.Timer.PERIODIC, callback=actualizar_animacion)
def iniciar_animacion_cerrando():
global puerta_abriendo, puerta_cerrando
puerta_abriendo = False
puerta_cerrando = True
temporizador_animacion.init(period=100, mode=machine.Timer.PERIODIC, callback=actualizar_animacion)
led_index = 27 # LED que cambiará de color según el botón
led_parpadeante = 0 # LED que parpadea en azul
led_blanco_index = 28 # LED blanco que se encenderá/apagará
# Pines de los botones
boton_subir = machine.Pin(34, machine.Pin.IN, machine.Pin.PULL_UP)
boton_bajar = machine.Pin(35, machine.Pin.IN, machine.Pin.PULL_UP)
boton_apagar = machine.Pin(25, machine.Pin.IN, machine.Pin.PULL_UP)
boton_led_blanco = machine.Pin(26, machine.Pin.IN, machine.Pin.PULL_UP) # Botón para el LED blanco
# Temporizador para regresar al color morado
temporizador = machine.Timer(-1)
# Variables de control
frecuencia_inicial_apagado = 0.8 # Tiempo mayor apagado
tiempo_encendido_corto = 0.2 # Tiempo corto encendido
frecuencia_normal = 0.5 # Frecuencia normal del parpadeo
frecuencia_parpadeo_rapida = 0.2 # Frecuencia cuando el botón se presiona
tiempo_parpadeo = frecuencia_inicial_apagado # Inicializar tiempo de parpadeo
led_blanco_encendido = False # Estado del LED blanco
ultimo_cambio_blanco = 0 # Tiempo del último cambio del LED blanco
debounce_blanco = 0.3 # Tiempo de debounce para el botón del LED blanco
# Variable de estado para controlar si la función bajar está activa
bajar_activo = False
# Función para apagar todos los LEDs
def apagar_neopixels():
for i in range(NUMERO_PIXELES):
np[i] = (0, 0, 0)
np.write()
# Función para actualizar el color del LED a morado (cuando no se presionan botones)
def restaurar_a_morado():
np[led_index] = colores["morado"]
np.write()
# Función para manejar el parpadeo del LED azul
def parpadear_led_azul():
np[led_parpadeante] = colores["azul"]
np.write()
time.sleep(tiempo_encendido_corto)
np[led_parpadeante] = (0, 0, 0)
np.write()
time.sleep(tiempo_parpadeo)
# Funciones de interrupción para los botones
def subir(pin):
global tiempo_parpadeo
color_actual_led = "rojo"
np[led_index] = colores["rojo"]
np.write()
# Cambiar frecuencia a normal durante la acción
tiempo_parpadeo = frecuencia_normal
# Iniciar animación de apertura
iniciar_animacion_abriendo()
# Restaurar color a morado y apagar LED blanco después de 1 segundo
temporizador.init(period=3000, mode=machine.Timer.ONE_SHOT, callback=restaurar_frecuencia_y_color)
def bajar(pin):
global tiempo_parpadeo, bajar_activo
bajar_activo = True # Indica que la función bajar está activa
color_actual_led = "verde"
np[led_index] = colores["verde"]
np.write()
# Cambiar frecuencia a normal durante la acción
tiempo_parpadeo = frecuencia_normal
# Iniciar animación de cierre
iniciar_animacion_cerrando()
# Restaurar color a morado y apagar LED blanco después de 1 segundo
temporizador.init(period=3000, mode=machine.Timer.ONE_SHOT, callback=restaurar_frecuencia_y_color)
def garage_door_animation(display, is_opening):
# Coordenadas y dimensiones del garaje y la puerta
garage_x = 50
garage_y = 50
garage_width = 140
garage_height = 100
step = 5 # Paso de movimiento de la puerta
# Dibuja el marco del garaje (cuadrado)
display.draw_rectangle(garage_x, garage_y, garage_width, garage_height, color565(255, 255, 255)) # Marco blanco del garaje
if is_opening: # Animación de apertura (de izquierda a derecha)
for x in range(garage_x + garage_width, garage_x, -step):
display.fill_rectangle(x, garage_y, step, garage_height, color565(0, 0, 0)) # Borra la parte que se mueve
sleep(0.05)
else: # Animación de cierre (de derecha a izquierda)
for x in range(garage_x, garage_x + garage_width, step):
display.fill_rectangle(x, garage_y, step, garage_height, color565(255, 255, 255)) # Dibujar la puerta
sleep(0.05)
def restaurar_frecuencia_y_color(timer):
global tiempo_parpadeo, bajar_activo
tiempo_parpadeo = frecuencia_inicial_apagado # Restaurar a la frecuencia inicial
restaurar_a_morado() # Cambiar el LED a morado
apagar_led_blanco() # Apagar el LED blanco al final de la función
bajar_activo = False # La función bajar ya no está activa
def encender_led_blanco():
global led_blanco_encendido
np[led_blanco_index] = colores["blanco"] # Enciende el LED blanco
led_blanco_encendido = True
np.write()
def apagar_led_blanco():
global led_blanco_encendido
np[led_blanco_index] = colores["negro"] # Apaga el LED blanco
led_blanco_encendido = False
np.write()
def apagar_led(pin):
global tiempo_parpadeo
if bajar_activo: # Solo ejecutar si la función bajar está activa
np[led_index] = colores["negro"] # Apagar el LED
np.write()
tiempo_parpadeo = frecuencia_parpadeo_rapida # Aumentar la velocidad del parpadeo
else:
if boton_apagar.value() == 0: # Si se presiona el botón
np[led_index] = colores["morado"] # Restaurar el color del LED
np.write()
tiempo_parpadeo = frecuencia_inicial_apagado # Restaurar la frecuencia inicial
def toggle_led_blanco(pin):
global led_blanco_encendido, ultimo_cambio_blanco
current_time = time.time()
# Debounce para el botón del LED blanco
if current_time - ultimo_cambio_blanco >= debounce_blanco:
if led_blanco_encendido:
apagar_led_blanco()
else:
encender_led_blanco()
ultimo_cambio_blanco = current_time # Actualiza el tiempo del último cambio
# Configurar interrupciones para los botones
boton_subir.irq(trigger=machine.Pin.IRQ_FALLING, handler=subir)
boton_bajar.irq(trigger=machine.Pin.IRQ_FALLING, handler=bajar)
boton_apagar.irq(trigger=machine.Pin.IRQ_RISING | machine.Pin.IRQ_FALLING, handler=apagar_led)
boton_led_blanco.irq(trigger=machine.Pin.IRQ_FALLING, handler=toggle_led_blanco) # Control del LED blanco
np[led_index]= colores["morado"]
np.write()
# Bucle principal
while True:
parpadear_led_azul() # LED parpadeante azul siempre activo