NeoMatrix/code.py
2025-02-26 09:08:29 +01:00

599 lines
No EOL
16 KiB
Python

# NeoMatrix 8x8 Status Display
# Made by: Jens Ståhl
# Board: RP2040-Zero
# v1.0: 2025-02-08 (Initial release)
import board
import time
import neopixel
import touchio
from adafruit_debouncer import Button
from adafruit_pixel_framebuf import PixelFramebuffer
from adafruit_led_animation.animation.sparklepulse import SparklePulse
from adafruit_led_animation.animation.rainbow import Rainbow
from adafruit_led_animation.animation.rainbowchase import RainbowChase
from adafruit_led_animation.animation.rainbowcomet import RainbowComet
from adafruit_led_animation.animation.rainbowsparkle import RainbowSparkle
from adafruit_led_animation.sequence import AnimationSequence
from adafruit_led_animation import helper
pixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.03)
pixel_pin = board.GP29
pixel_width = 8
pixel_height = 8
mode = 0
modeMax = 18
auto = False
now = time.monotonic()
touch = touchio.TouchIn(board.GP28)
switch = Button(touch, value_when_pressed = True)
AMBER = 0xFF6400
AQUA = 0x32FFFF
BLACK = 0x000000
BLUE = 0x0000FF
BROWN = 0x5C4033
CYAN = 0x00FFFF
FLESH = 0xFF8683
GOLD = 0xFFDE1E
GREEN = 0x00FF00
JADE = 0x00FF28
MAGENTA = 0xFF00FF
ORANGE = 0xFF2800
PALEPINK = 0xF25AFF
PINK = 0x0FF1493
PURPLE = 0xB400FF
RED = 0xFF0000
TEAL = 0x00FF78
WHITE = 0xFFFFFF
YELLOW = 0xFF9600
pixels = neopixel.NeoPixel(
pixel_pin,
pixel_width * pixel_height,
brightness=0.1,
auto_write=False,
)
pixel_framebuf = PixelFramebuffer(
pixels,
pixel_width,
pixel_height,
alternating=False,
reverse_x=True,
reverse_y=True,
)
pixel_wing_vertical = helper.PixelMap.vertical_lines(
pixels, 8, 8, helper.horizontal_strip_gridmap(8, alternating=False)
)
pixel_wing_horizontal = helper.PixelMap.horizontal_lines(
pixels, 8, 8, helper.horizontal_strip_gridmap(8, alternating=False)
)
sparkle_pulse = SparklePulse(pixels, speed=0.01, period=5, color=JADE)
rainbow = Rainbow(pixels, speed=0.01, period=2)
rainbow_v = Rainbow(pixel_wing_vertical, speed=0.01, period=2)
rainbow_h = Rainbow(pixel_wing_horizontal, speed=0.01, period=2)
rainbow_chase = RainbowChase(pixels, speed=0.1, size=3, spacing=6)
rainbow_comet = RainbowComet(pixels, speed=0.05, tail_length=7, bounce=True)
rainbow_sparkle = RainbowSparkle(pixels, speed=0.1, num_sparkles=15)
animations = AnimationSequence(
sparkle_pulse,
rainbow,
rainbow_chase,
rainbow_comet,
rainbow_sparkle,
advance_interval=7,
auto_clear=True,
)
def displayText(text, bcolor, tcolor):
global mode
i = 0
lastmode = mode
delay = time.monotonic()
while (i <= len(text) * 6 + 10) and mode == lastmode:
checkButton()
if (time.monotonic() - delay) > 0.1:
pixel_framebuf.fill(bcolor)
pixel_framebuf.text(text, 8 - i, 1, tcolor, font_name="font5x8_swedish.bin")
pixel_framebuf.display()
i += 1
delay = time.monotonic()
def animateSmiley():
global mode
i = 0
lastmode = mode
delay = time.monotonic() - 1
smileyFrames = [
"left",
"right",
"left",
"right",
"silly",
"silly",
"center",
"center",
]
while i < len(smileyFrames) and mode == lastmode:
checkButton()
if (time.monotonic() - delay) > 1:
drawSmiley(smileyFrames[i])
i += 1
delay = time.monotonic()
def drawCross(fat, bcolor, ccolor):
pixel_framebuf.fill(bcolor)
if fat: pixel_framebuf.line(0, 1, 6, 7, ccolor); pixel_framebuf.line(1, 0, 7, 6, ccolor); pixel_framebuf.line(6, 0, 0, 6, ccolor); pixel_framebuf.line(7, 1, 1, 7, ccolor)
pixel_framebuf.line(0, 0, 7, 7, ccolor)
pixel_framebuf.line(7, 0, 0, 7, ccolor)
pixel_framebuf.display()
def drawTick(bcolor, ccolor):
pixel_framebuf.fill(bcolor)
pixel_framebuf.line(0, 5, 2, 7, ccolor)
pixel_framebuf.line(2, 7, 7, 2, ccolor)
pixel_framebuf.display()
def drawCircle(bcolor, ccolor):
pixel_framebuf.fill(ccolor)
pixel_framebuf.line(0, 0, 1, 0, bcolor)
pixel_framebuf.line(6, 0, 7, 0, bcolor)
pixel_framebuf.pixel(0, 1, bcolor)
pixel_framebuf.pixel(7, 1, bcolor)
pixel_framebuf.pixel(0, 6, bcolor)
pixel_framebuf.pixel(7, 6, bcolor)
pixel_framebuf.line(6, 7, 7, 7, bcolor)
pixel_framebuf.line(0, 7, 1, 7, bcolor)
pixel_framebuf.display()
def drawHeart(bcolor, ccolor):
pixel_framebuf.fill(bcolor)
pixel_framebuf.line(1, 1, 2, 1, BLACK)
pixel_framebuf.line(5, 1, 6, 1, BLACK)
pixel_framebuf.line(0, 2, 7, 2, BLACK)
pixel_framebuf.line(1, 2, 2, 2, ccolor)
pixel_framebuf.line(5, 2, 6, 2, ccolor)
pixel_framebuf.line(0, 3, 7, 3, BLACK)
pixel_framebuf.line(1, 3, 6, 3, ccolor)
pixel_framebuf.line(0, 4, 7, 4, BLACK)
pixel_framebuf.line(1, 4, 6, 4, ccolor)
pixel_framebuf.line(1, 5, 6, 5, BLACK)
pixel_framebuf.line(2, 5, 5, 5, ccolor)
pixel_framebuf.line(2, 6, 5, 6, BLACK)
pixel_framebuf.line(3, 6, 4, 6, ccolor)
pixel_framebuf.line(3, 7, 4, 7, BLACK)
pixel_framebuf.display()
def drawSmiley(mode):
pixel_framebuf.fill(YELLOW)
pixel_framebuf.pixel(0, 0, BLACK)
pixel_framebuf.pixel(7, 0, BLACK)
pixel_framebuf.pixel(1, 2, WHITE)
pixel_framebuf.pixel(5, 2, WHITE)
pixel_framebuf.pixel(6, 2, WHITE)
pixel_framebuf.pixel(1, 5, BLACK)
pixel_framebuf.pixel(6, 5, BLACK)
pixel_framebuf.line(2, 6, 5, 6, BLACK)
pixel_framebuf.pixel(0, 7, BLACK)
pixel_framebuf.pixel(7, 7, BLACK)
if mode == "silly": pixel_framebuf.pixel(2, 2, BLACK); pixel_framebuf.pixel(1, 3, WHITE); pixel_framebuf.pixel(2, 3, WHITE); pixel_framebuf.pixel(5, 3, BLACK); pixel_framebuf.pixel(6, 3, WHITE)#; pixel_framebuf.pixel(6, 6, FLESH); pixel_framebuf.pixel(5, 7, FLESH); pixel_framebuf.pixel(6, 7, FLESH)
elif mode == "left": pixel_framebuf.pixel(2, 2, WHITE); pixel_framebuf.pixel(1, 3, BLACK); pixel_framebuf.pixel(2, 3, WHITE); pixel_framebuf.pixel(5, 3, BLACK); pixel_framebuf.pixel(6, 3, WHITE)
elif mode == "right": pixel_framebuf.pixel(2, 2, WHITE); pixel_framebuf.pixel(1, 3, WHITE); pixel_framebuf.pixel(2, 3, BLACK); pixel_framebuf.pixel(5, 3, WHITE); pixel_framebuf.pixel(6, 3, BLACK)
elif mode == "center": pixel_framebuf.pixel(2, 2, WHITE); pixel_framebuf.pixel(1, 3, WHITE); pixel_framebuf.pixel(2, 3, BLACK); pixel_framebuf.pixel(5, 3, BLACK); pixel_framebuf.pixel(6, 3, WHITE)
pixel_framebuf.display()
def drawDino():
pixel_framebuf.fill(BLACK)
pixel_framebuf.line(5, 0, 6, 0, GREEN)
pixel_framebuf.pixel(5, 1, GREEN)
pixel_framebuf.pixel(7, 1, GREEN)
pixel_framebuf.line(4, 2, 7, 2, GREEN)
pixel_framebuf.line(3, 3, 5, 3, GREEN)
pixel_framebuf.line(2, 4, 5, 4, GREEN)
pixel_framebuf.line(1, 5, 4, 5, GREEN)
pixel_framebuf.pixel(6, 5, GREEN)
pixel_framebuf.line(0, 6, 2, 6, GREEN)
pixel_framebuf.pixel(4, 6, GREEN)
pixel_framebuf.line(4, 7, 5, 7, GREEN)
pixel_framebuf.display()
def drawStar():
pixel_framebuf.fill(CYAN)
pixel_framebuf.line(3, 0, 4, 0, YELLOW)
pixel_framebuf.line(3, 1, 4, 1, YELLOW)
pixel_framebuf.line(2, 2, 5, 2, YELLOW)
pixel_framebuf.line(0, 3, 7, 3, YELLOW)
pixel_framebuf.pixel(2, 3, BLACK)
pixel_framebuf.pixel(5, 3, BLACK)
pixel_framebuf.line(1, 4, 6, 4, YELLOW)
pixel_framebuf.pixel(2, 4, BLACK)
pixel_framebuf.pixel(5, 4, BLACK)
pixel_framebuf.line(2, 5, 5, 5, YELLOW)
pixel_framebuf.line(1, 6, 2, 6, YELLOW)
pixel_framebuf.line(5, 6, 6, 6, YELLOW)
pixel_framebuf.pixel(1, 7, YELLOW)
pixel_framebuf.pixel(6, 7, YELLOW)
pixel_framebuf.display()
def drawCat():
pixel_framebuf.fill(BLUE)
pixel_framebuf.pixel(1, 0, BLACK)
pixel_framebuf.pixel(6, 0, BLACK)
pixel_framebuf.line(0, 1, 7, 1, BLACK)
pixel_framebuf.pixel(1, 1, PALEPINK)
pixel_framebuf.line(3, 1, 4, 1, BLUE)
pixel_framebuf.pixel(6, 1, PALEPINK)
pixel_framebuf.line(0, 2, 7, 2, BLACK)
pixel_framebuf.pixel(1, 2, PALEPINK)
pixel_framebuf.pixel(2, 2, WHITE)
pixel_framebuf.pixel(5, 2, WHITE)
pixel_framebuf.pixel(6, 2, PALEPINK)
pixel_framebuf.line(0, 3, 7, 3, BLACK)
pixel_framebuf.line(1, 3, 6, 3, WHITE)
pixel_framebuf.line(0, 4, 7, 4, BLACK)
pixel_framebuf.pixel(1, 4, WHITE)
pixel_framebuf.line(3, 4, 4, 4, WHITE)
pixel_framebuf.pixel(6, 4, WHITE)
pixel_framebuf.line(0, 5, 7, 5, WHITE)
pixel_framebuf.pixel(0, 5, BLACK)
pixel_framebuf.line(3, 5, 4, 5, PALEPINK)
pixel_framebuf.pixel(7, 5, BLACK)
pixel_framebuf.line(1, 6, 6, 6, BLACK)
pixel_framebuf.line(2, 6, 5, 6, WHITE)
pixel_framebuf.line(2, 7, 5, 7, BLACK)
pixel_framebuf.display()
def drawCreeper():
pixel_framebuf.fill(GREEN)
pixel_framebuf.line(1, 1, 2, 1, BLACK)
pixel_framebuf.line(5, 1, 6, 1, BLACK)
pixel_framebuf.line(1, 2, 2, 2, BLACK)
pixel_framebuf.line(5, 2, 6, 2, BLACK)
pixel_framebuf.line(3, 3, 4, 3, BLACK)
pixel_framebuf.line(2, 4, 5, 4, BLACK)
pixel_framebuf.line(2, 5, 5, 5, BLACK)
pixel_framebuf.pixel(2, 6, BLACK)
pixel_framebuf.pixel(5, 6, BLACK)
pixel_framebuf.display()
def drawSheep():
pixel_framebuf.fill(WHITE)
pixel_framebuf.line(0, 2, 7, 2, BROWN)
pixel_framebuf.line(0, 3, 7, 3, BROWN)
pixel_framebuf.pixel(1, 3, BLACK)
pixel_framebuf.pixel(2, 3, WHITE)
pixel_framebuf.pixel(5, 3, WHITE)
pixel_framebuf.pixel(6, 3, BLACK)
pixel_framebuf.line(0, 4, 7, 4, BROWN)
pixel_framebuf.line(2, 5, 5, 5, BROWN)
pixel_framebuf.line(2, 6, 5, 6, BROWN)
pixel_framebuf.line(3, 6, 4, 6, PALEPINK)
pixel_framebuf.line(2, 7, 5, 7, BROWN)
pixel_framebuf.line(3, 7, 4, 7, PALEPINK)
pixel_framebuf.display()
def drawPig():
pixel_framebuf.fill(PALEPINK)
pixel_framebuf.pixel(0, 3, BLACK)
pixel_framebuf.pixel(1, 3, WHITE)
pixel_framebuf.pixel(6, 3, WHITE)
pixel_framebuf.pixel(7, 3, BLACK)
pixel_framebuf.line(2, 4, 5, 4, WHITE)
pixel_framebuf.pixel(2, 5, PINK)
pixel_framebuf.pixel(5, 5, PINK)
pixel_framebuf.line(2, 6, 5, 6, WHITE)
pixel_framebuf.display()
def drawSteve():
pixel_framebuf.fill(BLACK)
pixel_framebuf.line(1, 1, 6, 1, FLESH)
pixel_framebuf.line(0, 2, 7, 2, FLESH)
pixel_framebuf.line(0, 3, 7, 3, FLESH)
pixel_framebuf.pixel(1, 3, WHITE)
pixel_framebuf.pixel(2, 3, BLUE)
pixel_framebuf.pixel(5, 3, BLUE)
pixel_framebuf.pixel(6, 3, WHITE)
pixel_framebuf.line(0, 4, 7, 4, FLESH)
pixel_framebuf.line(3, 4, 4, 4, BROWN)
pixel_framebuf.line(0, 5, 7, 5, FLESH)
pixel_framebuf.pixel(1, 5, BLACK)
pixel_framebuf.pixel(6, 5, BLACK)
pixel_framebuf.line(0, 6, 7, 6, FLESH)
pixel_framebuf.line(2, 6, 5, 6, BLACK)
pixel_framebuf.line(0, 7, 7, 7, FLESH)
pixel_framebuf.display()
def drawEnderman():
pixel_framebuf.fill(BLACK)
pixel_framebuf.pixel(0, 3, PALEPINK)
pixel_framebuf.pixel(1, 3, PINK)
pixel_framebuf.pixel(2, 3, PALEPINK)
pixel_framebuf.pixel(5, 3, PALEPINK)
pixel_framebuf.pixel(6, 3, PINK)
pixel_framebuf.pixel(7, 3, PALEPINK)
pixel_framebuf.display()
def drawWither():
pixel_framebuf.fill(BLACK)
pixel_framebuf.line(1, 3, 2, 3, WHITE)
pixel_framebuf.line(5, 3, 6, 3, WHITE)
pixel_framebuf.line(2, 5, 5, 5, WHITE)
pixel_framebuf.display()
def drawSlime():
pixel_framebuf.fill(GREEN)
pixel_framebuf.line(1, 2, 2, 2, BLACK)
pixel_framebuf.line(5, 2, 6, 2, BLACK)
pixel_framebuf.line(1, 3, 2, 3, BLACK)
pixel_framebuf.line(5, 3, 6, 3, BLACK)
pixel_framebuf.pixel(4, 6, BLACK)
pixel_framebuf.display()
def drawSmiley2():
pixel_framebuf.fill(PURPLE)
pixel_framebuf.line(2, 1, 5, 1, YELLOW)
pixel_framebuf.line(1, 2, 6, 2, YELLOW)
pixel_framebuf.pixel(2, 2, BLACK)
pixel_framebuf.pixel(5, 2, BLACK)
pixel_framebuf.line(1, 3, 6, 3, YELLOW)
pixel_framebuf.line(1, 4, 6, 4, YELLOW)
pixel_framebuf.pixel(2, 4, BLACK)
pixel_framebuf.pixel(5, 4, BLACK)
pixel_framebuf.line(1, 5, 6, 5, YELLOW)
pixel_framebuf.line(3, 5, 4, 5, BLACK)
pixel_framebuf.line(2, 6, 5, 6, YELLOW)
pixel_framebuf.display()
def drawRedSwirl():
pixel_framebuf.fill(RED)
pixel_framebuf.line(4, 1, 6, 1, BLACK)
pixel_framebuf.line(4, 2, 5, 2, BLACK)
pixel_framebuf.pixel(1, 3, BLACK)
pixel_framebuf.line(1, 4, 2, 4, BLACK)
pixel_framebuf.line(5, 4, 6, 4, BLACK)
pixel_framebuf.line(1, 5, 2, 5, BLACK)
pixel_framebuf.line(5, 5, 6, 5, BLACK)
pixel_framebuf.pixel(6, 6, BLACK)
pixel_framebuf.display()
def drawChick():
pixel_framebuf.fill(GOLD)
pixel_framebuf.line(0, 0, 2, 0, AQUA)
pixel_framebuf.line(5, 0, 7, 0, AQUA)
pixel_framebuf.pixel(0, 1, AQUA)
pixel_framebuf.pixel(7, 1, AQUA)
pixel_framebuf.pixel(2, 3, BLACK)
pixel_framebuf.pixel(5, 3, BLACK)
pixel_framebuf.line(3, 4, 4, 4, YELLOW)
pixel_framebuf.line(3, 5, 4, 5, AMBER)
pixel_framebuf.pixel(0, 7, AQUA)
pixel_framebuf.pixel(7, 7, AQUA)
pixel_framebuf.display()
def drawColorCircle():
pixel_framebuf.rect(0, 0, 8, 8, RED)
pixel_framebuf.rect(1, 1, 6, 6, YELLOW)
pixel_framebuf.rect(2, 2, 4, 4, GREEN)
pixel_framebuf.rect(3, 3, 2, 2, BLUE)
#pixel_framebuf.rect(1, 1, 6, 6, BLUE)
pixel_framebuf.display()
def drawRainbow(vertical):
if vertical:
pixel_framebuf.line(0, 0, 0, 7, RED)
pixel_framebuf.line(1, 0, 1, 7, ORANGE)
pixel_framebuf.line(2, 0, 2, 7, YELLOW)
pixel_framebuf.line(3, 0, 3, 7, GREEN)
pixel_framebuf.line(4, 0, 4, 7, AQUA)
pixel_framebuf.line(5, 0, 5, 7, BLUE)
pixel_framebuf.line(6, 0, 6, 7, PURPLE)
pixel_framebuf.line(7, 0, 7, 7, PINK)
else:
pixel_framebuf.line(0, 0, 7, 0, RED)
pixel_framebuf.line(0, 1, 7, 1, ORANGE)
pixel_framebuf.line(0, 2, 7, 2, YELLOW)
pixel_framebuf.line(0, 3, 7, 3, GREEN)
pixel_framebuf.line(0, 4, 7, 4, AQUA)
pixel_framebuf.line(0, 5, 7, 5, BLUE)
pixel_framebuf.line(0, 6, 7, 6, PURPLE)
pixel_framebuf.line(0, 7, 7, 7, PINK)
pixel_framebuf.display()
def fillDisplay(bcolor):
pixel_framebuf.fill(bcolor)
pixel_framebuf.display()
def clearDisplay():
pixel_framebuf.fill(BLACK)
pixel_framebuf.display()
pixel_wing_vertical.fill(0)
pixel_wing_horizontal.fill(0)
def checkButton():
global mode
global auto
switch.update()
if switch.long_press and switch.short_count == 1:
displayText("Jens Ståhl 2025", PALEPINK, BLUE)
elif switch.long_press:
auto = not auto
elif switch.short_count == 1:
if mode < modeMax: mode += 1
else: mode = 0; clearDisplay()
elif switch.short_count == 2:
if mode == modeMax: clearDisplay()
if mode > 0: mode -= 1
else: mode = modeMax; clearDisplay()
while True:
checkButton()
if mode == 0:
if not auto: pixel[0] = RED
drawCross(False, BLACK, RED)
elif mode == 1:
if not auto: pixel[0] = GREEN
drawTick(BLACK, GREEN)
elif mode == 2:
drawHeart(BLUE, RED)
elif mode == 3:
animateSmiley()
elif mode == 4:
drawDino()
elif mode == 5:
drawStar()
elif mode == 6:
drawCat()
elif mode == 7:
drawCreeper()
elif mode == 8:
drawSheep()
elif mode == 9:
drawPig()
elif mode == 10:
drawSteve()
elif mode == 11:
drawEnderman()
elif mode == 12:
drawWither()
elif mode == 13:
drawSlime()
elif mode == 14:
drawSmiley2()
elif mode == 15:
drawRedSwirl()
elif mode == 16:
drawChick()
elif mode == 17:
drawColorCircle()
elif mode == 18:
animations.animate()
if not auto and mode > 1: pixel[0] = BLACK
elif auto: pixel[0] = BLUE
if auto and (time.monotonic() - now) > 35:
if mode < modeMax: mode += 1
else: mode = 0; clearDisplay()
now = time.monotonic()