Raspberry Pi Pico
5x5 RGB Matrix Breakout
The 5x5 RGB Matrix Breakout is another Pimoroni board from the breakout garden range. The LEDs are connected to the driver in a very similar way to the LED Shim. That made it a quick tweak to get library code running on it. Like the 11x7 matrix, it is a no-solder solution and can be quickly connected to a breadboard.
For the library, I just removed a few entries in the table and added a method to address pixels by coordinates. I saved this as scrollrgb.py.
from time import sleep_ms _f = 0 _b = bytearray(145) class SCROLLRGB: def __init__(self, i2c): self.i2c = i2c self._w(253, 11) sleep_ms(100) self._w(10, 0) sleep_ms(100) self._w(10, 1) sleep_ms(100) self._w(0, 0) self._w(6, 0) for bank in [1,0]: self._w(253, bank) self._w([0] + [255] * 17) self.clear() self.show() def _w(self, *args): if len(args) == 1: args = args[0] self.i2c.writeto(116, bytes(args)) def clear(self): global _b del _b _b = bytearray(145) def fill(self, r, g, b): for i in range(25): self.set_pixel(i, r, g, b) def show(self): global _f _f = not _f self._w(253, _f) _b[0] = 36 self._w(_b) self._w(253, 11) self._w(1, _f) def set_pixelxy(self, x, y, r, g, b): self.set_pixel(x + y * 5, r, g, b) def set_pixel(self, n, r, g, b): global _b tbl = [118,69,85, 117,68,101, 116,84,100, 115,83,99, 114,82,98, 132,19,35, 133,20,36, 134,21,37, 112,80,96, 113,81,97, 131,18,34, 130,17,50, 129,33,49, 128,32,48, 127,47,63, 125,28,44, 124,27,43, 123,26,42, 122,25,58, 121,41,57, 126,29,45, 15,95,111, 8,89,105, 9,90,106, 10,91,107] x = n * 3 _b[tbl[x]+1]=r _b[tbl[x+1]+1]=g _b[tbl[x+2]+1]=b
Here was some basic test code to get you started,
from machine import Pin, I2C from time import sleep from scrollrgb import SCROLLRGB i2c=I2C(0,sda=Pin(4), scl=Pin(5)) display = SCROLLRGB(i2c) # test pixel writing for i in range(25): display.set_pixel(i, 0, 0, 255) display.show() sleep(0.1) # filling sleep(1) display.fill(0, 0, 0) display.show() sleep(1) display.fill(255,0,0) display.show() sleep(1) display.fill(0,255,0) display.show() sleep(1) display.fill(0,0,255) display.show() sleep(1) # pixel writing by xy for y in range(5): for x in range(5): display.set_pixelxy(x, y, 255, 0, 0) display.show() sleep(0.1)
Update
When I first put together the code on this page, I didn't quite manage to get text scrolling working. I have now corrected the situation. I copied the numbers for the 5x5 font used for the BBC micro:bit. It is called pendolino. I then transposed it so that the binary values represented columns instead of rows. I used Python to do all of the processing of the numbers.
The photograph shows the Pimoroni Pico Lipo. This is a pin-for-pin equivalent to the Pico with pin labels, LIPO charging, RGB LED, reset button.
The updated library,
from time import sleep_ms _f = 0 _b = bytearray(145) fnt = [0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 24, 0, 24, 0, 10, 31, 10, 31, 10, 10, 29, 21, 23, 10, 25, 18, 4, 9, 19, 10, 21, 21, 10, 1, 0, 24, 0, 0, 0, 0, 14, 17, 0, 0, 0, 17, 14, 0, 0, 0, 10, 4, 10, 0, 0, 4, 14, 4, 0, 0, 1, 2, 0, 0, 0, 4, 4, 4, 0, 0, 2, 0, 0, 0, 1, 2, 4, 8, 16, 14, 17, 17, 14, 0, 0, 9, 31, 1, 0, 19, 21, 21, 9, 0, 18, 17, 21, 26, 0, 6, 10, 18, 31, 2, 29, 21, 21, 21, 18, 2, 5, 13, 21, 2, 17, 18, 20, 24, 16, 10, 21, 21, 21, 10, 8, 21, 22, 20, 8, 0, 10, 0, 0, 0, 0, 1, 10, 0, 0, 0, 4, 10, 17, 0, 0, 10, 10, 10, 0, 0, 17, 10, 4, 0, 8, 16, 21, 20, 8, 14, 17, 21, 18, 14, 15, 20, 20, 15, 0, 31, 21, 21, 10, 0, 14, 17, 17, 17, 0, 31, 17, 17, 14, 0, 31, 21, 21, 17, 0, 31, 20, 20, 16, 0, 14, 17, 17, 21, 6, 31, 4, 4, 31, 0, 17, 31, 17, 0, 0, 18, 17, 17, 30, 16, 31, 4, 10, 17, 0, 31, 1, 1, 1, 0, 31, 8, 4, 8, 31, 31, 8, 4, 2, 31, 14, 17, 17, 14, 0, 31, 20, 20, 8, 0, 12, 18, 19, 13, 0, 31, 20, 20, 10, 1, 9, 21, 21, 18, 0, 16, 16, 31, 16, 16, 30, 1, 1, 30, 0, 28, 2, 1, 2, 28, 31, 2, 4, 2, 31, 27, 4, 4, 27, 0, 16, 8, 7, 8, 16, 19, 21, 25, 17, 0, 0, 31, 17, 17, 0, 16, 8, 4, 2, 1, 0, 17, 17, 31, 0, 0, 8, 16, 8, 0, 1, 1, 1, 1, 1, 0, 16, 8, 0, 0, 6, 9, 9, 15, 1, 31, 5, 5, 2, 0, 6, 9, 9, 9, 0, 2, 5, 5, 31, 0, 14, 21, 21, 9, 0, 4, 15, 20, 16, 0, 8, 21, 21, 30, 0, 31, 4, 4, 3, 0, 0, 23, 0, 0, 0, 0, 1, 1, 22, 0, 31, 4, 10, 1, 0, 0, 30, 1, 1, 0, 15, 8, 4, 8, 15, 15, 8, 8, 7, 0, 6, 9, 9, 6, 0, 15, 10, 10, 4, 0, 4, 10, 10, 15, 0, 7, 8, 8, 8, 0, 1, 5, 10, 8, 0, 0, 30, 5, 5, 1, 14, 1, 1, 15, 1, 12, 2, 1, 2, 12, 15, 1, 2, 1, 15, 9, 6, 6, 9, 0, 9, 5, 2, 4, 8, 9, 11, 13, 9, 0, 0, 4, 31, 17, 0, 0, 31, 0, 0, 0, 17, 31, 4, 0, 0, 0, 4, 4, 2, 2] class SCROLLRGB: def __init__(self, i2c): self.i2c = i2c self._w(253, 11) sleep_ms(100) self._w(10, 0) sleep_ms(100) self._w(10, 1) sleep_ms(100) self._w(0, 0) self._w(6, 0) for bank in [1,0]: self._w(253, bank) self._w([0] + [255] * 17) self.clear() self.show() def _w(self, *args): if len(args) == 1: args = args[0] self.i2c.writeto(116, bytes(args)) def clear(self): global _b del _b _b = bytearray(145) def fill(self, r, g, b): for i in range(25): self.set_pixel(i, r, g, b) def show(self): global _f _f = not _f self._w(253, _f) _b[0] = 36 self._w(_b) self._w(253, 11) self._w(1, _f) def set_pixelxy(self, x, y, r, g, b): self.set_pixel(x + y * 5, r, g, b) def set_pixel(self, n, r, g, b): global _b tbl = [118,69,85, 117,68,101, 116,84,100, 115,83,99, 114,82,98, 132,19,35, 133,20,36, 134,21,37, 112,80,96, 113,81,97, 131,18,34, 130,17,50, 129,33,49, 128,32,48, 127,47,63, 125,28,44, 124,27,43, 123,26,42, 122,25,58, 121,41,57, 126,29,45, 15,95,111, 8,89,105, 9,90,106, 10,91,107] x = n * 3 _b[tbl[x]+1]=r _b[tbl[x+1]+1]=g _b[tbl[x+2]+1]=b def scroll_msg(self, msg, delay, r, g, b): txt = [0,0,0,0,0] for c in msg: if ord(c)<32 or ord(c)>126: txt += [0,0,0,0,0] else: txt += [0] + fnt[(ord(c)-32)*5:(ord(c)-32)*5+5] txt += [0,0,0,0,0,0] for i in range(0, len(txt)-5): for x in range(5): for y in range(5): n = txt[i+x]>>(4-y)& 1 self.set_pixelxy(x, y, n * r, n* g, n * b) self.show() sleep_ms(delay)
And the test code,
from machine import Pin, I2C from time import sleep from scrollrgb import SCROLLRGB i2c=I2C(0,sda=Pin(4), scl=Pin(5)) display = SCROLLRGB(i2c) display.scroll_msg("OMG! The scrolling works.", 100, 255, 0, 0)