Flotilla Python - display text on Matrix module


#1

Hi there - I am making a radio with a Flotilla interface in Python. I have got the Touch module working to select 4 preset radio stations and the rotary knob working as a volume control. I want to add some visual feedback to show which station is selected - is it possible in the Python API either to latch the LEDs on the Touch switches or to send text / numbers to the Matrix display as you seem to be able to do in Rockpool? (I can address individual pixels on the Matrix using Python, but can I just send it numbers?) Thank you!


#2

Hi,
if you remove all of my flim-flam bells and whistles from the following code you should be able to get scrolling messages going on the matrix!

(I hope the formatting is OK, can’t upload a file at the moment!)

Cheers,
Neil

#!/usr/bin/env python

import sys
import time

import flotilla

if len(sys.argv) == 1: sys.argv[1:] = ["0"]


print("""
Attempting to scroll a message on a matrix module...

Press CTRL+C to exit.
""")

# Looks for the dock, and all of the modules we need
# attached to the dock so we can talk to them.

dock = flotilla.Client()
print("Client connected...")

while not dock.ready:                                                 pass

print("Finding modules...")                                       matrix = dock.first(flotilla.Matrix)
touch = dock.first(flotilla.Touch)
dial = dock.first(flotilla.Dial)
slider = dock.first(flotilla.Slider)
number = dock.first(flotilla.Number)

if matrix is None:
    print("No Matrix module found...")
    dock.stop()
    sys.exit(1)
else:
    print("Found. Running...")

state = True

matrix_font = [
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x18,0x00,0x18,0x18,0x3c,0x3c,0x18],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x6c,0x6c],
    [0x00,0x6c,0x6c,0xfe,0x6c,0xfe,0x6c,0x6c],
    [0x00,0x30,0xf8,0x0c,0x78,0xc0,0x7c,0x30],
    [0x00,0xc6,0x66,0x30,0x18,0xcc,0xc6,0x00],
    [0x00,0x76,0xcc,0xdc,0x76,0x38,0x6c,0x38],
    [0x00,0x00,0x00,0x00,0x00,0xc0,0x60,0x60],
    [0x00,0x18,0x30,0x60,0x60,0x60,0x30,0x18],
    [0x00,0x60,0x30,0x18,0x18,0x18,0x30,0x60],
    [0x00,0x00,0x66,0x3c,0xff,0x3c,0x66,0x00],
    [0x00,0x00,0x30,0x30,0xfc,0x30,0x30,0x00],
    [0x60,0x30,0x30,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00],
    [0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x80,0xc0,0x60,0x30,0x18,0x0c,0x06],
    [0x00,0x7c,0xe6,0xf6,0xde,0xce,0xc6,0x7c],
    [0x00,0xfc,0x30,0x30,0x30,0x30,0x70,0x30],
    [0x00,0xfc,0xcc,0x60,0x38,0x0c,0xcc,0x78],
    [0x00,0x78,0xcc,0x0c,0x38,0x0c,0xcc,0x78],
    [0x00,0x1e,0x0c,0xfe,0xcc,0x6c,0x3c,0x1c],
    [0x00,0x78,0xcc,0x0c,0x0c,0xf8,0xc0,0xfc],
    [0x00,0x78,0xcc,0xcc,0xf8,0xc0,0x60,0x38],
    [0x00,0x30,0x30,0x30,0x18,0x0c,0xcc,0xfc],
    [0x00,0x78,0xcc,0xcc,0x78,0xcc,0xcc,0x78],
    [0x00,0x70,0x18,0x0c,0x7c,0xcc,0xcc,0x78],
    [0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x00],
    [0x60,0x30,0x30,0x00,0x00,0x30,0x30,0x00],
    [0x00,0x18,0x30,0x60,0xc0,0x60,0x30,0x18],
    [0x00,0x00,0xfc,0x00,0x00,0xfc,0x00,0x00],
    [0x00,0x60,0x30,0x18,0x0c,0x18,0x30,0x60],
    [0x00,0x30,0x00,0x30,0x18,0x0c,0xcc,0x78],
    [0x00,0x78,0xc0,0xde,0xde,0xde,0xc6,0x7c],
    [0x00,0xcc,0xcc,0xfc,0xcc,0xcc,0x78,0x30],
    [0x00,0xfc,0x66,0x66,0x7c,0x66,0x66,0xfc],
    [0x00,0x3c,0x66,0xc0,0xc0,0xc0,0x66,0x3c],
    [0x00,0xf8,0x6c,0x66,0x66,0x66,0x6c,0xf8],
    [0x00,0xfe,0x62,0x68,0x78,0x68,0x62,0xfe],
    [0x00,0xf0,0x60,0x68,0x78,0x68,0x62,0xfe],
    [0x00,0x3e,0x66,0xce,0xc0,0xc0,0x66,0x3c],
    [0x00,0xcc,0xcc,0xcc,0xfc,0xcc,0xcc,0xcc],
    [0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x78],
    [0x00,0x78,0xcc,0xcc,0x0c,0x0c,0x0c,0x1e],
    [0x00,0xe6,0x66,0x6c,0x78,0x6c,0x66,0xe6],
    [0x00,0xfe,0x66,0x62,0x60,0x60,0x60,0xf0],
    [0x00,0xc6,0xc6,0xd6,0xfe,0xfe,0xee,0xc6],
    [0x00,0xc6,0xc6,0xce,0xde,0xf6,0xe6,0xc6],
    [0x00,0x38,0x6c,0xc6,0xc6,0xc6,0x6c,0x38],
    [0x00,0xf0,0x60,0x60,0x7c,0x66,0x66,0xfc],
    [0x00,0x1c,0x78,0xdc,0xcc,0xcc,0xcc,0x78],
    [0x00,0xe6,0x66,0x6c,0x7c,0x66,0x66,0xfc],
    [0x00,0x78,0xcc,0x1c,0x70,0xe0,0xcc,0x78],
    [0x00,0x78,0x30,0x30,0x30,0x30,0xb4,0xfc],
    [0x00,0xfc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc],
    [0x00,0x30,0x78,0xcc,0xcc,0xcc,0xcc,0xcc],
    [0x00,0xc6,0xee,0xfe,0xd6,0xc6,0xc6,0xc6],
    [0x00,0xc6,0x6c,0x38,0x38,0x6c,0xc6,0xc6],
    [0x00,0x78,0x30,0x30,0x78,0xcc,0xcc,0xcc],
    [0x00,0xfe,0x66,0x32,0x18,0x8c,0xc6,0xfe],
    [0x00,0x78,0x60,0x60,0x60,0x60,0x60,0x78],
    [0x00,0x02,0x06,0x0c,0x18,0x30,0x60,0xc0],
    [0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x78],
    [0x00,0x00,0x00,0x00,0xc6,0x6c,0x38,0x10],
    [0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00],
    [0x00,0x00,0x00,0x00,0x00,0x18,0x30,0x30],
    [0x00,0x76,0xcc,0x7c,0x0c,0x78,0x00,0x00],
    [0x00,0xdc,0x66,0x66,0x7c,0x60,0x60,0xe0],
    [0x00,0x78,0xcc,0xc0,0xcc,0x78,0x00,0x00],
    [0x00,0x76,0xcc,0xcc,0x7c,0x0c,0x0c,0x1c],
    [0x00,0x78,0xc0,0xfc,0xcc,0x78,0x00,0x00],
    [0x00,0xf0,0x60,0x60,0xf0,0x60,0x6c,0x38],
    [0xf8,0x0c,0x7c,0xcc,0xcc,0x76,0x00,0x00],
    [0x00,0xe6,0x66,0x66,0x76,0x6c,0x60,0xe0],
    [0x00,0x78,0x30,0x30,0x30,0x70,0x00,0x30],
    [0x78,0xcc,0xcc,0x0c,0x0c,0x0c,0x00,0x0c],
    [0x00,0xe6,0x6c,0x78,0x6c,0x66,0x60,0xe0],
    [0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x70],
    [0x00,0xc6,0xd6,0xfe,0xfe,0xcc,0x00,0x00],
    [0x00,0xcc,0xcc,0xcc,0xcc,0xf8,0x00,0x00],
    [0x00,0x78,0xcc,0xcc,0xcc,0x78,0x00,0x00],
    [0xf0,0x60,0x7c,0x66,0x66,0xdc,0x00,0x00],
    [0x1e,0x0c,0x7c,0xcc,0xcc,0x76,0x00,0x00],
    [0x00,0xf0,0x60,0x66,0x76,0xdc,0x00,0x00],
    [0x00,0xf8,0x0c,0x78,0xc0,0x7c,0x00,0x00],
    [0x00,0x18,0x34,0x30,0x30,0x7c,0x30,0x10],
    [0x00,0x76,0xcc,0xcc,0xcc,0xcc,0x00,0x00],
    [0x00,0x30,0x78,0xcc,0xcc,0xcc,0x00,0x00],
    [0x00,0x6c,0xfe,0xfe,0xd6,0xc6,0x00,0x00],
    [0x00,0xc6,0x6c,0x38,0x6c,0xc6,0x00,0x00],
    [0xf8,0x0c,0x7c,0xcc,0xcc,0xcc,0x00,0x00],
    [0x00,0xfc,0x64,0x30,0x98,0xfc,0x00,0x00],
    [0x00,0x1c,0x30,0x30,0xe0,0x30,0x30,0x1c],
    [0x00,0x18,0x18,0x18,0x00,0x18,0x18,0x18],
    [0x00,0xe0,0x30,0x30,0x1c,0x30,0x30,0xe0],
    [0x00,0x00,0x00,0x00,0x00,0x00,0xdc,0x76],
    [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00] ]

try:
    rot = int(str(sys.argv[1]))
    pos = 7
    charcode = 0
    prevcode = 0
    chind = 0
    currchar = 0
    offset = 0
    speed = 1
    brightness = 10
    msg = "Pimoroni Flotilla matrix module scrolling message with controls for brightness, speed and rotation! "
    while True:
        charcode = ord(msg[chind])
        if chind:
            prevcode = ord(msg[chind-1])
        else:
            prevcode = 32
        for module in dock.available.values():
            if module.is_a(flotilla.Touch):
                touch = module
                if touch.one:
                    rot = 0
                if touch.two:
                    rot = 90
                if touch.three:
                    rot = 180
                if touch.four:
                    rot = 270
            if module.is_a(flotilla.Slider):
               slider = module
               speed = slider.position/1023.0*10.0
               speed = max(speed,1.0)
            if module.is_a(flotilla.Dial):
                dial = module
                brightness = max(int((dial.position/1023.0)*100.0),1)
            if module.is_a(flotilla.Matrix):
                matrix.clear()
                matrix.rotation(rot)
                matrix.set_brightness(brightness)
                for row in range(0, 8):
                    for col in range(0, 8):
                      if col+pos > 7:
                          currchar = prevcode
                          offset = col+pos-8
                      else:
                          currchar = charcode
                          offset = col+pos
                      if matrix_font[currchar][row] & (1 << offset):
                          if rot == 90 or rot == 270:
                              matrix.set_pixel(7-col,7-row,1)
                          else:
                              matrix.set_pixel(7-row, 7-col, 1)
                matrix.update();
                if pos > 0:
                    pos -= 1
                else:
                    pos = 7
                    if chind < len(msg)-1:
                        chind += 1
                    else:
                        chind = 0
            if module.is_a(flotilla.Number):
                number = module
                if state:
                    number.set_current_time()
                else:
                    number.set_string("T1ME")
                number.set_brightness(brightness)
                #number.set_apostrophe(1)
                number.update()
        #state = not state
        time.sleep(0.1/speed)

except KeyboardInterrupt:
    if matrix:
        matrix.clear()
        matrix.update()
    if number:
        number.clear()
        number.set_colon(0)
        number.set_apostrophe(0)
        number.update()
    print("Stopping Flotilla...")
    dock.stop()

#3

That looks awesome! Thank you, I will try this later on :)


#4

It works! Thank you so much. Where did you get the alphabet from? I’m thinking of perhaps sending just the 4 numbers I need directly as static images or perhaps little custom graphics, so I’ll need to figure out a way of generating the hex numbers…


#5

I shamelessly stole the alphabet from the Pimoroni rockpool javascript code and converted it to python. Everything should look exactly the as Gadgetoid (Phil Howard) programmed it!


#6

Thanks! I am trying just to display single non-scrolling characters and have sort of got it to work but the letters are offset 1 pixel to the left, wrapped around the display. Admittedly I have no idea what I’m doing… code looks a bit like this:

foo = [0x00,0x78,0xcc,0x0c,0x38,0x0c,0xcc,0x78]
pos = 7
offset = 0

(lines omitted)

        if touch.three:
            matrix.clear()
            for row in range(0, 8):
                for col in range(0, 8):
                    if col+pos > 7:
                          offset = col+pos-8
                    else:
                          offset = col+pos
                    if foo[row] & (1 << offset):
                        matrix.set_pixel(7-col, 7-row, 1)
            matrix.update()

#7

I designed the code for scrolling messages.
If you are just showing single characters you could forget about using the offset and just display the 8 by 8 pixels from the row and col.
Something like:

If foo[row] & (1<< col):
    matrix.set_pixel(7-col, 7-row, 1)

Sorry if that doesn’t work straight away, I’m not near my stash of Pis and Pimoroni stuff at the moment.


#8

That’s a huge help, I will experiment. Thank you :)


#9

Almost perfect - the letters were mirror image, all ok with this tweak, displays digits 1-4 - thank you so much for all your help!

digits = [
    [0x00,0xfc,0x30,0x30,0x30,0x30,0x70,0x30],
    [0x00,0xfc,0xcc,0x60,0x38,0x0c,0xcc,0x78],
    [0x00,0x78,0xcc,0x0c,0x38,0x0c,0xcc,0x78],
    [0x00,0x1e,0x0c,0xfe,0xcc,0x6c,0x3c,0x1c]
    ]

(code omitted)

        if touch.four:
            os.system("mpc play 4")
            matrix.clear()
            for row in range(0, 8):
                for col in range(0, 8):
                    if digits[3][row] & (1 << col):
                        matrix.set_pixel(col, 7-row, 1)
            matrix.update()

#10

Now written up here: http://www.suppertime.co.uk/blogmywiki/2017/07/flotilla-radio/