# 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()