# ========= Simplified Multicore RP2040 + OLED + ADC Menu =========
import _thread, time
from machine import Pin, I2C, ADC
from ssd1306 import SSD1306_I2C
# ===================== Hardware Config =====================
# I2C0: GP0=SCL, GP1=SDA (SSD1306 OLED)
i2c = I2C(0, scl=Pin(5), sda=Pin(4), freq=200000)
oled = SSD1306_I2C(128, 64, i2c)
# Binary outputs (10 bits): GP2-GP11
# Salidas binarias (10 bits). Mantengo tu mapeo exacto:
gpio_pins = [2, 3, 6, 7, 8, 9, 10, 11, 12, 13]
OUT_PINS = [Pin(p, Pin.OUT) for p in gpio_pins]
# Controls
ADC_MENU = ADC(Pin(26)) # GP26: Menu selection
BTN = Pin(14, Pin.IN, Pin.PULL_UP) # GP14: Short=select, Long=back
# Instruments (optional)
ADC_VOLT = ADC(Pin(27)) # GP27: Voltage/Current
ADC_OHM = ADC(Pin(28)) # GP28: Resistance divider
VREF = 3.3
ADC_MAX = 65535
# ===================== State =====================
state = {
"menu_opt": 1, # 1-10
"in_menu": True, # True=menu, False=app
"running": True,
"counter": 0,
}
# ===================== Button Handler =====================
def btn_event():
"""Returns: 0=none, 1=short, 2=long"""
if BTN.value(): return 0
press_start = time.ticks_ms()
while not BTN.value():
if time.ticks_diff(time.ticks_ms(), press_start) > 600: # Long press
while not BTN.value(): pass
time.sleep_ms(20)
return 2
time.sleep_ms(20)
return 1
# ===================== Display =====================
def clear():
oled.fill(0)
def draw_menu(opt):
clear()
oled.text("== MENU ==", 24, 0)
labels = [
"1 Contrador Bin",
"2 Contador Dec",
"3 1-Hot Scan",
"4 Patron Espejo",
"5 Codigo Gray",
"6 Voltimetro",
"7 Ohmmetro",
"8 Amperimetro",
"9 About",
"10 Reset"
]
# Show options around current selection
start = max(0, opt-4)
for i in range(start, min(10, start+6)):
marker = ">" if i+1 == opt else " "
oled.text(f"{marker}{labels[i]}", 0, 12 + (i-start)*9)
oled.text("Press:Sel Hold:Back", 0, 56)
oled.show()
def draw_value_screen(title, value, unit="", binary=False):
clear()
oled.text(title, 0, 0)
oled.text(str(value), 0, 20)
if unit: oled.text(unit, 0, 40)
if binary:
oled.text(f"BIN:{value:010b}", 0, 54)
oled.show()
def draw_about():
clear()
oled.text("RP2040 Multicore", 0, 10)
oled.text("GPIO + OLED + ADC", 0, 25)
oled.text("Dr.GermanPereira", 0, 40)
oled.show()
# ===================== Instruments =====================
def read_voltage():
return ADC_VOLT.read_u16() * VREF / ADC_MAX
def read_current():
return read_voltage() / 1.0 # Replace 1.0 with RSHUNT
def read_resistance():
v = ADC_OHM.read_u16() * VREF / ADC_MAX
return 10000.0 * (VREF / max(v, 0.01) - 1) # Replace 10000.0 with RREF
# ===================== Sequences =====================
def get_sequence(opt, k):
k &= 1023 # 10-bit limit
if opt == 1: return k
if opt == 2: return 1023 - k
if opt == 3: return 1 << ((k // 3) % 10)
if opt == 4:
pos = (k // 5) % 18
return 1 << (pos if pos < 10 else 18 - pos)
if opt == 5: return (k ^ (k >> 1)) & 1023
return 0
# ===================== Cores =====================
def core1_loop():
while state["running"]:
if not state["in_menu"] and 1 <= state["menu_opt"] <= 5:
state["counter"] = (state["counter"] + 1) & 1023
val = get_sequence(state["menu_opt"], state["counter"])
for i, pin in enumerate(OUT_PINS):
pin.value((val >> i) & 1)
time.sleep_ms(120)
else:
for pin in OUT_PINS: pin.value(0)
time.sleep_ms(50)
def core0_loop():
while state["running"]:
if state["in_menu"]:
opt = (ADC_MENU.read_u16() * 10 // ADC_MAX) + 1
draw_menu(opt)
event = btn_event()
if event == 1: # Short press
state["menu_opt"] = opt
state["in_menu"] = False
time.sleep_ms(200)
else:
opt = state["menu_opt"]
if 1 <= opt <= 5:
val = state["counter"]
title = ["Binary", "Down", "1-Hot", "Mirror", "Gray"][opt-1]
draw_value_screen(f"SERIE {opt} - {title}", val, binary=True)
elif opt == 6: draw_value_screen("VOLTMETER", f"{read_voltage():.3f}", "V")
elif opt == 7: draw_value_screen("OHMMETER", f"{read_resistance():.0f}", "Ω")
elif opt == 8: draw_value_screen("AMMETER", f"{read_current():.3f}", "A")
elif opt == 9: draw_about()
elif opt == 10:
state["menu_opt"] = 1
state["in_menu"] = True
if btn_event() == 2: # Long press
state["in_menu"] = True
# ===================== Start =====================
def main():
oled.fill(0)
oled.text("RP2040 Starting...", 0, 20)
oled.show()
time.sleep_ms(500)
_thread.start_new_thread(core1_loop, ())
core0_loop()
try:
main()
except:
state["running"] = False
for pin in OUT_PINS: pin.value(0)
oled.fill(0)
oled.text("STOPPED", 0, 20)
oled.show()