Raspberry Pi Pico
Unicorn HAT
The Unicorn HAT is a Raspberry Pi accessory made by the UK electronics company, Pimoroni. It has 64 WS2812 (Neopixel RGB) LEDs arranged in an 8x8 grid.
In this photograph, I have the Unicorn HAT connected to the Pico using a Waveshare Pico to HAT board.
Since the LEDs are Neopixels, there is a CircuitPython library that makes it easy to drive the LEDs. On the Unicorn HAT, the pixels are connected down,up,down,... in columns, making it a little awkward when you want to work with grid coordinates. I added a subroutine to do that. The other thing I wanted to do was to have text scrolling across the matrix.
You need a library for this project - get the latest .mpy one from here,
I started by taking the font I have used in various projects and making a separate file for it. I saved this as font.py. I can add other fonts to this file and import them when I need them.
font7x5 = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x5f\x00\x00\x00\x07\x00\x07\x00\x14\x7f\x14' b'\x7f\x14\x24\x2a\x7f\x2a\x12\x23\x13\x08\x64\x62\x36\x49\x55\x22\x50\x00' b'\x05\x03\x00\x00\x00\x1c\x22\x41\x00\x00\x41\x22\x1c\x00\x14\x08\x3e\x08' b'\x14\x08\x08\x3e\x08\x08\x00\x50\x30\x00\x00\x08\x08\x08\x08\x08\x00\x60' b'\x60\x00\x00\x20\x10\x08\x04\x02\x3e\x51\x49\x45\x3e\x00\x42\x7f\x40\x00' b'\x42\x61\x51\x49\x46\x21\x41\x45\x4b\x31\x18\x14\x12\x7f\x10\x27\x45\x45' b'\x45\x39\x3c\x4a\x49\x49\x30\x01\x71\x09\x05\x03\x36\x49\x49\x49\x36\x06' b'\x49\x49\x29\x1e\x00\x36\x36\x00\x00\x00\x56\x36\x00\x00\x08\x14\x22\x41' b'\x00\x14\x14\x14\x14\x14\x00\x41\x22\x14\x08\x02\x01\x51\x09\x06\x32\x49' b'\x79\x41\x3e\x7e\x11\x11\x11\x7e\x7f\x49\x49\x49\x36\x3e\x41\x41\x41\x22' b'\x7f\x41\x41\x22\x1c\x7f\x49\x49\x49\x41\x7f\x09\x09\x09\x01\x3e\x41\x49' b'\x49\x7a\x7f\x08\x08\x08\x7f\x00\x41\x7f\x41\x00\x20\x40\x41\x3f\x01\x7f' b'\x08\x14\x22\x41\x7f\x40\x40\x40\x40\x7f\x02\x0c\x02\x7f\x7f\x04\x08\x10' b'\x7f\x3e\x41\x41\x41\x3e\x7f\x09\x09\x09\x06\x3e\x41\x51\x21\x5e\x7f\x09' b'\x19\x29\x46\x46\x49\x49\x49\x31\x01\x01\x7f\x01\x01\x3f\x40\x40\x40\x3f' b'\x1f\x20\x40\x20\x1f\x3f\x40\x38\x40\x3f\x63\x14\x08\x14\x63\x07\x08\x70' b'\x08\x07\x61\x51\x49\x45\x43\x00\x7f\x41\x41\x00\x02\x04\x08\x10\x20\x00' b'\x41\x41\x7f\x00\x04\x02\x01\x02\x04\x40\x40\x40\x40\x40\x00\x01\x02\x04' b'\x00\x20\x54\x54\x54\x78\x7f\x48\x44\x44\x38\x38\x44\x44\x44\x20\x38\x44' b'\x44\x48\x7f\x38\x54\x54\x54\x18\x08\x7e\x09\x01\x02\x0c\x52\x52\x52\x3e' b'\x7f\x08\x04\x04\x78\x00\x44\x7d\x40\x00\x20\x40\x44\x3d\x00\x7f\x10\x28' b'\x44\x00\x00\x41\x7f\x40\x00\x7c\x04\x18\x04\x78\x7c\x08\x04\x04\x78\x38' b'\x44\x44\x44\x38\x7c\x14\x14\x14\x08\x08\x14\x14\x18\x7c\x7c\x08\x04\x04' b'\x08\x48\x54\x54\x54\x20\x04\x3f\x44\x40\x20\x3c\x40\x40\x20\x7c\x1c\x20' b'\x40\x20\x1c\x3c\x40\x30\x40\x3c\x44\x28\x10\x28\x44\x0c\x50\x50\x50\x3c' b'\x44\x64\x54\x4c\x44\x00\x08\x36\x41\x00\x00\x00\x7f\x00\x00\x00\x41\x36' b'\x08\x00\x10\x08\x08\x10\x08\x00\x00\x00\x00\x00')
Here is the program that I used to test things out.
from time import sleep import board import neopixel from random import randint from font import font7x5 def wax_on(rgb, delay): for i in range(num_pixels): pixels[i] = rgb pixels.show() sleep(delay) def wax_off(rgb, delay): for i in range(num_pixels-1, -1, -1): pixels[i] = rgb pixels.show() sleep(delay) def set_pixelxy(x, y, rgb): if x % 2 == 0: i = 8 * x + y else: i = x * 8 + 7 - y pixels[i] = rgb def scroll(txt, delay, rgb): msg = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') for c in txt: msg += bytearray(b'\x00') msg += font7x5[(ord(c)-32)*5:(ord(c)-32)*5+5] msg += bytearray(b'\x00') msg += bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00') for i in range(len(msg)- 8): t = msg[i:i + 8] for x in range(8): for y in range(8): if t[x] >> y & 1: set_pixelxy(x, y, rgb) else: set_pixelxy(x, y, off) pixels.show() sleep(delay) pixel_pin = board.GP18 num_pixels = 64 ORDER = neopixel.GRB pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.2, auto_write=False, pixel_order=ORDER) off = (0, 0, 0) pixels.fill(off) pixels.show() for y in range(8): for x in range(8): set_pixelxy(x, y, (255, 0, 0)) pixels.show() sleep(0.1) sleep(3) pixels.fill(off) pixels.show() scroll("OMG. I can't believe that the scrolling works.", 0.05, (0,0,255)) sleep(3) while True: colour = (randint(0,255),randint(0,255), randint(0,255)) wax_on(colour, 0.1) sleep(0.5) wax_off(off, 0.1) sleep(0.5)