
LED cushion… enough to make your heart skip a beat?
I’ve been experimenting over the Christmas period with WS2812 RGB LEDs. I intend to write up these experiments in another post, but having a bit of free time enabled me to try something a little more ambitious.
Connecting RGB LEDs to the Raspberry Pi has been simplified and they are now supported in ScratchGPIO once the Pimoroni unicornhat software is installed. By wiring together a bunch of these, I was able to create a 25 LED matrix.
Control via ScratchGPIO was a little slower than I needed and in addition I wanted to see if I could write text. I’ve done this in the past using figlet and writing the result to a Minecraft screen as a pile of blocks. It seemed it might be possible. I originally intended to go for a set of 8×8 LEDs (Similar to the Unicorn Hat or the Sense Hat from Pimoroni) but with time running short for a demo, I had to opt for just 5×5. The maths is what stings here… 25 LEDs, 3 pieces of wire between each, two ends to strip, twist and solder = 150 joints. For 8×8 this would be…. well, ouch!
In the video below, I present the results of the first set of experiments. I fully intend to solder up the remaining 39 LEDs to make 8×8, but this will take some time. I’ve mounted the LEDs on cardboard inside the cushion and covered them with bubble wrap. I will eventually use something much softer in the final product.
The controlling program is written in Python and uses a slight modification of the Unicorn Hat module. It took me a little while to find where Python modules are stored but I found it in
Here’s the final program:
#!/usr/bin/env python import iprpixel as unicorn import time import datetime import random from mcpi import minecraft import commands #print("Here goes") lookup=[0,1,2,3,4,9,8,7,6,5,10,11,12,13,14,19,18,17,16,15,20,21,22,23,24] unicorn.brightness(0.6) #--------------------- #wr_str = raw_input('What would you like to write? ') # ask the user what they'd like to write at the current position #wr_str = "Hello" def choosecol(): colval=random.randint(0,5) global r_val, g_val, b_val # print "Colour is :",colval if colval==0: #red r_val=255 g_val=0 b_val=0 if colval==1: #green r_val=0 g_val=255 b_val=0 if colval==2: #blue r_val=0 g_val=0 b_val=255 if colval==3: #orange/yellow r_val=128 g_val=128 b_val=0 if colval==4: #cyan r_val=0 g_val=128 b_val=128 if colval==5: #magenta r_val=128 g_val=0 b_val=128 def sparklefill(): for led in range(400): ledpos = random.randint(0,24) r_val = random.randint(64,255) g_val = random.randint(64,255) b_val = random.randint(64,255) unicorn.setapixel(ledpos,r_val,g_val,b_val) unicorn.show() time.sleep(.05) for led in range(400): ledpos = random.randint(0,24) unicorn.setapixel(ledpos,0,255,255) unicorn.show() time.sleep(.05) unicorn.setapixel(ledpos,0,0,0) unicorn.show() # time.sleep(.05) def timestring(): global figletstring, list_line # wr_str= time.strftime('%I:%M %p') wr_str= "Time Now : "+time.strftime('%I:%M %p') figletstring=str(wr_str).upper() cmd = 'figlet -w 400 -f 3x5 '+figletstring # create an operating system command line = commands.getoutput( cmd ) # send cmd as a command to the operating system and receive the result. list_line = line.rstrip().split('\n') # split the result from 'figlet' into separate lines (right strip new line feeds) def ipaddress(): global figletstring, list_line figletstring = commands.getoutput( "hostname -I" ) # print figletstring cmd = 'figlet -w 400 -f 3x5 '+figletstring # create an operating system command line = commands.getoutput( cmd ) # send cmd as a command to the operating system and receive the result. list_line = line.rstrip().split('\n') # split the result from 'figlet' into separate lines (right strip new line feeds) def heart1(): global list_line list_line = [" "," # # ","#####","#####"," ### "," # "] def heart2(): global list_line list_line = [" "," "," # # "," ### "," # "," "] def displayleds(): for startcolumn in range(len(list_line[1])-4): column = 0 rownumber=-1 time.sleep(0.1) for row in list_line: # one row at a time from list_line (the result from figlet) # print row, len(row) if rownumber>-1 and rownumber<5: column=0 # print "working with row",row,"completed" for letter in row[startcolumn:startcolumn+5]: # work along each row - check each character. If it's a '#' then print a block else leave it as air if letter == "#": unicorn.setapixel(lookup.index(column+(rownumber*5)),r_val,g_val,b_val) else: unicorn.setapixel(lookup.index(column+(rownumber*5)),0,0,0) column = column+1 unicorn.show() rownumber=rownumber+1 def boxdraw(): global list_line, r_val, g_val, b_val for boxes in range(6): choosecol() list_line = [" "," "," "," # "," "," "," "] displayleds() time.sleep(0.1) list_line = [" "," "," ### "," # # "," ### "," "] displayleds() time.sleep(0.1) list_line = [" ","#####","# #","# #","# #","#####"] displayleds() time.sleep(0.1) def pacman(): global list_line, r_val, g_val, b_val r_val=255 g_val=255 b_val=0 for bite in range(6): list_line = [" "," ### ","#####","#####","#####"," ### "," "] displayleds() time.sleep(0.5) list_line = [" "," ### ","#####","## ","#####"," ### "," "] displayleds() time.sleep(0.5) def smiley(): global list_line, r_val, g_val, b_val for flashface in range(5): choosecol() list_line = [" ","## ##","## ##"," ","# #"," ### "," "] displayleds() time.sleep(1) def spinner(): global list_line, r_val, g_val, b_val for boxes in range(5): choosecol() for spin in range(4): list_line = [" ","# "," # "," # "," # "," # "] displayleds() time.sleep(0.01) list_line = [" "," # "," # "," # "," # "," # "] displayleds() time.sleep(0.01) list_line = [" "," #"," # "," # "," # ","# "] displayleds() time.sleep(0.01) list_line = [" "," "," ","#####"," "," "] displayleds() time.sleep(0.01) def heartbeat(): global r_val, g_val, b_val for hearts in range(10): r_val=255 g_val=0 b_val=0 heart1() displayleds() time.sleep(1) heart2() displayleds() time.sleep(0.25) for displayip in range(5): choosecol() boxdraw() choosecol() ipaddress() displayleds() time.sleep(1) while True: # pacman() smiley() spinner() boxdraw() heartbeat() choosecol() timestring() displayleds() time.sleep(1) sparklefill()