import machine
import ssd1306
import time
import sys
# --- CONFIGURACIÓN DE PERIFÉRICOS ---
i2c = machine.I2C(0, scl=machine.Pin(22), sda=machine.Pin(21))
try:
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
except:
print("Error: Pantalla no detectada.")
# Entradas de simulación
pin_a = machine.Pin(14, machine.Pin.IN)
pin_b = machine.Pin(12, machine.Pin.IN)
led = machine.Pin(2, machine.Pin.OUT)
# Configuración del Teclado (Pines exactos de tu esquema)
filas = [
machine.Pin(19, machine.Pin.OUT),
machine.Pin(18, machine.Pin.OUT),
machine.Pin(5, machine.Pin.OUT),
machine.Pin(17, machine.Pin.OUT)
]
columnas = [
machine.Pin(16, machine.Pin.IN, machine.Pin.PULL_DOWN), # C1
machine.Pin(4, machine.Pin.IN, machine.Pin.PULL_DOWN), # C2
machine.Pin(0, machine.Pin.IN, machine.Pin.PULL_DOWN), # C3
machine.Pin(15, machine.Pin.IN, machine.Pin.PULL_DOWN) # C4
]
# SEGURIDAD INICIAL: Apagamos todas las filas antes de empezar
for f in filas:
f.value(0)
teclas = [
['1','2','3','A'],
['4','5','6','B'],
['7','8','9','C'],
['*','0','#','D']
]
compuertas_map = {
'1': "AND", '2': "OR", '3': "NOT", '4': "NAND",
'5': "NOR", '6': "XOR", '7': "XNOR", '8': "SALIR"
}
def leer_teclado():
"""Escaneo con filtrado de ruido y confirmación de estado."""
for i, f in enumerate(filas):
f.value(1)
for j, c in enumerate(columnas):
if c.value() == 1:
time.sleep(0.05) # Filtro de rebote (debounce)
if c.value() == 1:
res = teclas[i][j]
# Bloqueo hasta que se suelte la tecla para evitar repetición
while c.value() == 1:
time.sleep(0.01)
f.value(0)
return res
f.value(0)
return None
def calcular(tipo, a, b):
if tipo == "AND": return a & b
if tipo == "OR": return a | b
if tipo == "NOT": return 1 if not a else 0
if tipo == "NAND": return 1 if not (a & b) else 0
if tipo == "NOR": return 1 if not (a | b) else 0
if tipo == "XOR": return a ^ b
if tipo == "XNOR": return 1 if a == b else 0
return 0
def mostrar_menu_principal():
oled.fill(0)
oled.text("SELECCIONE (1-8):", 0, 0)
oled.text("1.AND 2.OR", 0, 12)
oled.text("3.NOT 4.NAND", 0, 22)
oled.text("5.NOR 6.XOR", 0, 32)
oled.text("7.XNOR 8.SALIR", 0, 42)
oled.hline(0, 52, 128, 1)
oled.text("Esperando tecla...", 0, 56)
oled.show()
print("\n--- MENU PRINCIPAL ---")
# --- FLUJO PRINCIPAL ---
# PASO CRÍTICO: Esperamos a que el simulador se estabilice antes de leer nada
print("Estabilizando sistema...")
time.sleep(1.0)
mostrar_menu_principal()
activa = None
ultima_tecla = None
while True:
key = leer_teclado()
# Solo procesamos si hay una pulsación nueva y real
if key is not None and key != ultima_tecla:
print(f"Hardware detectó: {key}")
if activa is None and key in compuertas_map:
if key == '8':
oled.fill(0)
oled.text("SISTEMA APAGADO", 5, 30)
oled.show()
sys.exit()
activa = compuertas_map[key]
print(f"Modo seleccionado: {activa}")
elif key == '*':
activa = None
led.value(0)
mostrar_menu_principal()
if key is None:
ultima_tecla = None
else:
ultima_tecla = key
# Lógica de simulación (se ejecuta solo si hay una compuerta elegida)
if activa:
val_a = pin_a.value()
val_b = pin_b.value()
res = calcular(activa, val_a, val_b)
led.value(res)
oled.fill(0)
oled.text(f"MODO: {activa}", 0, 0)
oled.hline(0, 10, 128, 1)
oled.text(f"ENTRADA A: {val_a}", 0, 20)
if activa != "NOT":
oled.text(f"ENTRADA B: {val_b}", 0, 30)
else:
oled.text("ENTRADA B: N/A", 0, 30)
oled.text(f"RESULTADO: {res}", 0, 45)
oled.text("*: Volver Menu", 0, 56)
oled.show()
time.sleep(0.1)