import machine
import micropython
import time
from machine import Pin, I2C, Timer, ADC
from logo import dibujar_logo
from ssd1306 import SSD1306_I2C
from oled_utils import (dibujar_barra_estado,
limpiar_area_trabajo,
dibujar_titulo_modo)
from fourier import (modo_ej4, modo_sf1,
modo_ej2, modo_ej_tramos)
micropython.alloc_emergency_exception_buf(100)
# ==============================================================================
# 1. INICIALIZACIÓN DE PERIFÉRICOS
# ==============================================================================
i2c = I2C(0, scl=Pin(1), sda=Pin(0), freq=400_000)
oled = SSD1306_I2C(128, 64, i2c)
oled.fill(0)
oled.text("UMSA", 50, 0)
oled.text("FACULTAD DE", 0, 9)
oled.text("INGENIERIA-ETN", 0, 18)
oled.text("Univ. Cristhian ", 0, 36)
oled.text("D. Cari Uluri", 0, 45)
oled.show()
time.sleep_ms(5000)
dibujar_logo(oled)
time.sleep_ms(5000)
adc_vsys = ADC(29)
btn_next = Pin(18, Pin.IN, Pin.PULL_UP)
btn_prev = Pin(19, Pin.IN, Pin.PULL_UP)
btn_reset = Pin(20, Pin.IN, Pin.PULL_UP)
btn_info = Pin(21, Pin.IN, Pin.PULL_UP)
# ==============================================================================
# 2-A. VARIABLES GLOBALES DE ESTADO
# ==============================================================================
segundos = 0
minutos = 6
horas = 14
MODOS = ["f(x)=e^-x T=0.5", "Cuadrada T=60",
"Ej2 T=4 ", "f tramos T=4pi"]
modo_actual = 0
modo_previo = -1
flag_estado = False
flag_modo = False
flag_info = False
REBOTE_MS = 200
t_ultimo_next = 0
t_ultimo_prev = 0
t_ultimo_reset = 0
t_ultimo_info = 0
# ==============================================================================
# 2-B. ISR
# ==============================================================================
def isr_timer_estado(timer):
global segundos, minutos, horas, flag_estado
segundos += 1
if segundos >= 60:
segundos = 0
minutos += 1
if minutos >= 60:
minutos = 0
horas += 1
if horas >= 24:
horas = 0
flag_estado = True
def isr_btn_next(pin):
global modo_actual, t_ultimo_next, flag_modo
t = time.ticks_ms()
if time.ticks_diff(t, t_ultimo_next) > REBOTE_MS:
modo_actual = (modo_actual + 1) % len(MODOS)
t_ultimo_next = t
flag_modo = True
def isr_btn_prev(pin):
global modo_actual, t_ultimo_prev, flag_modo
t = time.ticks_ms()
if time.ticks_diff(t, t_ultimo_prev) > REBOTE_MS:
modo_actual = (modo_actual - 1) % len(MODOS)
t_ultimo_prev = t
flag_modo = True
def isr_btn_reset(pin):
global modo_actual, t_ultimo_reset, flag_modo
t = time.ticks_ms()
if time.ticks_diff(t, t_ultimo_reset) > REBOTE_MS:
modo_actual = 0
t_ultimo_reset = t
flag_modo = True
def isr_btn_info(pin):
global t_ultimo_info, flag_info
t = time.ticks_ms()
if time.ticks_diff(t, t_ultimo_info) > REBOTE_MS:
t_ultimo_info = t
flag_info = True
# ==============================================================================
# 2-C / 2-D. IRQ + TIMER
# ==============================================================================
btn_next.irq( trigger=Pin.IRQ_FALLING, handler=isr_btn_next)
btn_prev.irq( trigger=Pin.IRQ_FALLING, handler=isr_btn_prev)
btn_reset.irq(trigger=Pin.IRQ_FALLING, handler=isr_btn_reset)
btn_info.irq( trigger=Pin.IRQ_FALLING, handler=isr_btn_info)
timer_hw = Timer()
timer_hw.init(period=1000, mode=Timer.PERIODIC, callback=isr_timer_estado)
# ==============================================================================
# 3. LAZO PRINCIPAL
# ==============================================================================
subprogramas = [modo_ej4, modo_sf1, modo_ej2, modo_ej_tramos]
dibujar_barra_estado(oled, horas, minutos, segundos, adc_vsys)
try:
while True:
# A) Barra de estado (1 vez/s)
if flag_estado:
dibujar_barra_estado(oled, horas, minutos, segundos, adc_vsys)
flag_estado = False
# B) Cambio de modo → actualizar título
if flag_modo or modo_actual != modo_previo:
limpiar_area_trabajo(oled)
dibujar_titulo_modo(oled, MODOS[modo_actual])
oled.show()
modo_previo = modo_actual
flag_modo = False
print("=== Modo:", MODOS[modo_actual].strip(), "===")
# C) btn_info: mostrar nombre del modo 1.5 s
if flag_info:
limpiar_area_trabajo(oled)
dibujar_titulo_modo(oled, MODOS[modo_actual])
oled.show()
time.sleep_ms(1500)
flag_info = False
# D) Reconstrucción Fourier continua con auto-incremento de armónicos
subprogramas[modo_actual](oled)
time.sleep_ms(10)
except KeyboardInterrupt:
timer_hw.deinit()
oled.fill(0)
oled.text("Sistema", 30, 20)
oled.text("detenido.", 24, 32)
oled.show()
print("\nTimer liberado. Sistema detenido.")