from machine import Pin, ADC, SPI
import time
class Max7219:
def __init__(self, spi, cs):
self.spi = spi
self.cs = cs
self.cs.init(Pin.OUT, True)
self.write_cmd(0x0F, 0x00) # display test off
self.write_cmd(0x0C, 0x01) # normal mode
self.write_cmd(0x0B, 0x07) # scan limit (8 LEDs)
self.write_cmd(0x09, 0x00) # no decode
self.set_intensity(6)
self.clear()
def write_cmd(self, cmd, data):
self.cs.value(0)
self.spi.write(bytearray([cmd, data]))
self.cs.value(1)
def set_intensity(self, val):
self.write_cmd(0x0A, val)
def clear(self):
for i in range(1, 9):
self.write_cmd(i, 0)
def set_row(self, row, value):
self.write_cmd(row + 1, value)
spi = SPI(0, baudrate=1000000, polarity=0, phase=0,
sck=Pin(2), mosi=Pin(3))
cs = Pin(5)
display = Max7219(spi, cs)
joy_x = ADC(Pin(26))
joy_y = ADC(Pin(27))
joy_btn = Pin(16, Pin.IN, Pin.PULL_UP)
btn_brillo = Pin(17, Pin.IN, Pin.PULL_UP)
btn_demo = Pin(18, Pin.IN, Pin.PULL_UP)
btn_clear = Pin(19, Pin.IN, Pin.PULL_UP)
cursor_x = 0
cursor_y = 0
matriz = [[0]*8 for _ in range(8)]
modo = 0 # 0=dibujo, 1=demo1, 2=demo2
brillo = 6
# imágenes demo
demo1 = [
0b00111100,
0b01000010,
0b10100101,
0b10000001,
0b10100101,
0b10011001,
0b01000010,
0b00111100
]
demo2 = [0xff,0xff,0x99,0x99,0xe7,0xc3,0xc3,0xdb]
# FUNCIONES
def actualizar_display():
for y in range(8):
fila = 0
for x in range(8):
if matriz[y][x]:
fila |= (1 << (7-x))
if y == cursor_y and modo == 0:
fila ^= (1 << (7-cursor_x))
display.set_row(y, fila)
def leer_joystick():
global cursor_x, cursor_y
x_val = joy_x.read_u16()
y_val = joy_y.read_u16()
max_val = 65535
if modo != 0:
return
if x_val > (2*max_val)//3:
cursor_x = min(cursor_x + 1, 7)
elif x_val < (max_val)//3:
cursor_x = max(cursor_x - 1, 0)
if y_val > (2*max_val)//3:
cursor_y = max(cursor_y - 1, 0)
elif y_val < (max_val)//3:
cursor_y = min(cursor_y + 1, 7)
def toggle_pixel():
if modo == 0:
matriz[cursor_y][cursor_x] ^= 1
def borrar_todo():
global modo, matriz
# Reiniciar la matriz a ceros
matriz = [[0]*8 for _ in range(8)]
# Volver al modo dibujo
modo = 0
# Limpiar físicamente el display inmediatamente
display.clear()
def cambiar_brillo():
global brillo
brillo += 3
if brillo > 15:
brillo = 0
display.set_intensity(brillo)
def cambiar_modo():
global modo
modo = (modo + 1) % 3
def mostrar_demo():
if modo == 1:
for i in range(8):
display.set_row(i, demo1[i])
elif modo == 2:
for i in range(8):
display.set_row(i, demo2[i])
last_move = time.ticks_ms()
last_btn = time.ticks_ms()
while True:
if time.ticks_diff(time.ticks_ms(), last_move) > 150:
leer_joystick()
last_move = time.ticks_ms()
if not joy_btn.value():
if time.ticks_diff(time.ticks_ms(), last_btn) > 300:
toggle_pixel()
last_btn = time.ticks_ms()
# BOTÓN BRILLO
if not btn_brillo.value():
if time.ticks_diff(time.ticks_ms(), last_btn) > 300:
cambiar_brillo()
last_btn = time.ticks_ms()
# BOTÓN DEMO
if not btn_demo.value():
if time.ticks_diff(time.ticks_ms(), last_btn) > 300:
cambiar_modo()
last_btn = time.ticks_ms()
# BOTÓN LIMPIAR (CORREGIDO)
if not btn_clear.value():
if time.ticks_diff(time.ticks_ms(), last_btn) > 300:
borrar_todo()
last_btn = time.ticks_ms()
# DISPLAY
if modo == 0:
actualizar_display()
else:
mostrar_demo()
time.sleep(0.05)