Recently I was given a Rasberry Pi by Jungle Minds, so I had to do a little project with it.

I followed along with this great tutorial on how to create a 3×3 LED matrix. I didn’ t follow the tutorial to the letter, for instance I used the gpiozero library and made a custom function to write texts.

Proof 🙂

The code

Take a look at the code on BitBucket (might be more recent) or just look at it here :).

```# -*- coding: utf-8 -*-

"""Render text on a 3x3 led matrix on the Raspberry Pi.

Author: Julius huijnk

Heavily inspired on these YouTube videos by Gaven MacDonald:
'Raspberry Piu Project: The LED Matrix'

Gaven MacDonald uses the RPi library, this uses the gpiozero library.
"""

from gpiozero import LED
from time import sleep

anodeLeft = LED(4)     # Left column
anodeMiddle = LED(17)  # Middle column
anodeRight = LED(27)   # Right column

cathodeFront = LED(25)   # Front row
cathodeMiddle = LED(24)  # Middle row
cathodeBack = LED(23)    # Back row

anodes = [anodeLeft, anodeMiddle, anodeRight]
cathodes = [cathodeFront, cathodeMiddle, cathodeBack]

# Frames, based on symbols
f_ = [[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]

f__ = [[0, 0, 0],
[0, 0, 0],
[1, 1, 1]]

f_a = [[0, 1, 0],
[1, 1, 1],
[1, 0, 1]]

f_b = [[1, 1, 0],
[1, 1, 1],
[1, 1, 1]]

f_c = [[1, 1, 1],
[1, 0, 0],
[1, 1, 1]]

f_d = [[1, 1, 0],
[1, 0, 1],
[1, 1, 0]]

f_e = [[1, 1, 1],
[1, 1, 0],
[1, 1, 1]]

f_f = [[1, 1, 1],
[1, 1, 0],
[1, 0, 0]]

f_g = [[1, 1, 0],
[1, 0, 1],
[1, 1, 1]]

f_h = [[1, 0, 1],
[1, 1, 1],
[1, 0, 1]]

f_i = [[1, 1, 1],
[0, 1, 0],
[1, 1, 1]]

f_j = [[0, 0, 1],
[1, 0, 1],
[1, 1, 1]]

f_k = [[1, 0, 1],
[1, 1, 0],
[1, 0, 1]]

f_l = [[1, 0, 0],
[1, 0, 0],
[1, 1, 1]]

f_m = [[1, 1, 1],
[1, 1, 1],
[1, 0, 1]]

f_n = [[1, 1, 1],
[1, 0, 1],
[1, 0, 1]]

f_o = [[1, 1, 1],
[1, 0, 1],
[1, 1, 1]]

f_p = [[1, 1, 1],
[1, 1, 1],
[1, 0, 0]]

f_q = [[1, 1, 1],
[1, 1, 1],
[0, 0, 1]]

f_r = [[1, 1, 1],
[1, 0, 0],
[1, 0, 0]]

f_s = [[0, 1, 1],
[0, 1, 0],
[1, 1, 0]]

f_t = [[1, 1, 1],
[0, 1, 0],
[0, 1, 0]]

f_u = [[1, 0, 1],
[1, 0, 1],
[1, 1, 1]]

f_v = [[1, 0, 1],
[1, 0, 1],
[0, 1, 0]]

f_w = [[1, 0, 1],
[1, 1, 1],
[1, 1, 1]]

f_x = [[1, 0, 1],
[0, 1, 0],
[1, 0, 1]]

f_y = [[1, 0, 1],
[0, 1, 0],
[0, 1, 0]]

f_z = [[1, 1, 0],
[0, 1, 0],
[0, 1, 1]]

symbol_frames = {" ": f_,
"_": f__,
"a": f_a,
"b": f_b,
"c": f_c,
"d": f_d,
"e": f_e,
"f": f_f,
"g": f_g,
"h": f_h,
"i": f_i,
"j": f_j,
"k": f_k,
"l": f_l,
"m": f_m,
"n": f_n,
"o": f_o,
"p": f_p,
"q": f_q,
"r": f_r,
"s": f_s,
"t": f_t,
"u": f_u,
"v": f_v,
"w": f_w,
"x": f_x,
"y": f_y,
"z": f_z}

def make_animation(text):
"""Splits text in symbols and returns list of frames based on each symbol"""
frames = []

# Splits text in separate symbols. For example "hi" becomes ["h", "i"]
symbols = list(text)

for symbol in symbols:
# Retreive frame based on symbol. For example for "e" it adds f_e
frames += [symbol_frames[symbol]]
return frames

def set_cathodes(on=True):
"""Turns on/off all cathodes.
With all anode on, turning off all cathodes would turn all leds on
"""
for cathode in cathodes:
if on:
cathode.on()
else:
cathode.off()

def set_rows(front, middle, back):
"""Assuming the anode for this column is on
Then for every true value a led will turn on
Calling this function, 0 and 1 can be used for True and False values
"""
# First set all led lights off
set_cathodes(on=True)
if front:
cathodeFront.off()   # Turn Led on
if middle:
cathodeMiddle.off()  # Turn Led on
if back:
cathodeBack.off()    # Turn Led on

def setColumn(sleep_time, column_nr, front, middle, back):
"""For every column (anode) the Leds are set on/off
sleep_time sets how long all leds in this column will be on

Since we don"t want user to notice each column being lighted separately,
the sleep_time should be rather short, like 0.001 second
"""
if not front and not middle and not back:
# No Leds will shine. They will be darker if anode is also off
anodes[column_nr].off()
set_cathodes(on=False)
sleep(sleep_time)
else:
# At least one led will shine
anodes[column_nr].on()
set_rows(front, middle, back)
sleep(sleep_time)
anodes[column_nr].off()
set_cathodes(on=False)

def render_frame(s, frame):
"""Goes over very column to display one frame"""
for column_nr, rows in enumerate(frame):
setColumn(sleep_time=s,
column_nr=column_nr,
front=rows,
middle=rows,
back=rows)

def set_frame(frame_time, frame):
"""Makes frame render a (large) number of times, so the user has time to
see it. frame_time sets how long user will see this frame.
"""
# Time spent on each colum is 1/3 of frame_time
# 160 with .002 is roughly a second (0.002 x 3 x 160 = 0.96 sec)
# range needs int, so the float that might occur is converted to int
for _ in range(int(round(160 * frame_time))):
render_frame(.002, frame)

def present_text(text, times=1, frame_time=0.3):
"""Presents the text on a 3x3 led screen."""

# Make frames based on each symbol in the text
word_frames = make_animation(text.lower())

for _ in range(times):
for word_frame in word_frames:
set_frame(frame_time, word_frame)  # Show symbol frame
set_frame(frame_time, f_)          # Empty frame

def test_make_animation():
"""Test for make_animation function"""
assert([f_a, f_b, f_c], make_animation("abc"))
print((make_animation("abc")))

# test_make_animation()

present_text("Super", 3, 0.3)
```

Have fun!