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.

Pico Circuit

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.

Pico Circuit

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)