BBC micro:bit
LED SHIM

Introduction

The LED SHIM is a shiny new Pimoroni accessory for the Raspberry Pi. It has 28 RGB LEDs lined up a row and is a solderless SHIM. Since it uses the IS31FL3731 LED driver that is used on the Scroll pHAT HD, I thought it would be worth a go on the micro:bit.

In the photographs, I have the SHIM on a 4tronix Bit:2:Pi.

micro:bit circuit

The SHIM is designed to fit snugly over the GPIO pins to make the electrical connection. The straight line of LEDs is enough for a 24 hour binary clock or just for some nice visual effects.

Programming

When using boards based on the IS31FL3731 LED driver, you need to know the way that the LEDs have been connected to the driver. On the Adafruit 16x9 matrices that use this driver, the LEDs are connected in order, making the job pretty straightforward. On the Scroll pHAT HD and the Scroll:bit, there is a reasonably quick way to compute the values you need. With this board, you need a lookup table, which is not an issue on a Raspberry Pi, but takes up a little more space on the micro:bit.

Another decision you need to make is whether or not to use a buffer to store the values you want to write to the display. For this program, I followed the thread of the Pimoroni library for the Scroll:bit, took out the code that wasn't needed and added some procedures to control the LEDs. The test code shows how to set all of the LEDs to a colour, light them one-by-one and make a rainbow.

from microbit import *
import math

_b = bytearray(145)

def _w(*args):
    if len(args) == 1: args = args[0]
    i2c.write(117, bytes(args))

def clear():
    global _b
    del _b
    _b = bytearray(145)
    
def show():    
    _w(253, 1)
    _b[0] = 36
    _w(_b)
    _w(253, 11)
    _w(1, 1)
    
def set_pix(n,r,g,b):
    tbl = [118,69,85,
    117,68,101,
    116,84,100,
    115,83,99,
    114,82,98,
    113,81,97,
    112,80,96,
    134,21,37,
    133,20,36,
    132,19,35,
    131,18,34,
    130,17,50,
    129,33,49,
    128,32,48,
    127,47,63,
    121,41,57,
    122,25,58,
    123,26,42,
    124,27,43,
    125,28,44,
    126,29,45,
    15,95,111,
    8,89,105,
    9,90,106,
    10,91,107,
    11,92,108,
    12,76,109,
    13,77,93]
    x = n * 3
    _b[tbl[x]+1]=r
    _b[tbl[x+1]+1]=g
    _b[tbl[x+2]+1]=b

def fill(r,g,b):
    for x in range(28):
        set_pix(x,r,g,b)

def hsv_to_rgb(h, s, v):
    if s == 0.0:
        return (v, v, v)
    i = int(h*6.0)
    f = (h*6.0) - i
    p = v*(1.0 - s)
    q = v*(1.0 - s*f)
    t = v*(1.0 - s*(1.0-f))
    i = i%6
    if i == 0:
        return (v, t, p)
    if i == 1:
        return (q, v, p)
    if i == 2:
        return (p, v, t)
    if i == 3:
        return (p, q, v)
    if i == 4:
        return (t, p, v)
    if i == 5:
        return (v, p, q)

def mc(h):
    hsv = hsv_to_rgb(h,1,0.5)
    r,g,b = hsv
    return (math.floor(r*255),math.floor(g*255),math.floor(b*255))

def rainbow():
    for i in range(28):
        r,g,b = mc(i/28)
        set_pix(i,r,g,b)
    
        
_w(253, 11)
sleep(100)
_w(10, 0)
sleep(100)
_w(10, 1)
sleep(100)
_w(0, 0)
_w(6, 0)
for bank in [1,0]:
    _w(253, bank)
    _w([0] + [255] * 17)
clear()
show()

# Testing
fill(255,0,0)
show()
sleep(3000)
fill(0,255,0)
show()
sleep(3000)
fill(0,0,255)
show()
sleep(3000)
clear()
show()
for i in range(28):
    set_pix(i,255,255,0)
    show()
    sleep(150)
rainbow()
show()