In this Tutorial we will make a simple 4x5 matrix using only 5 GPIO pins on your Raspberry Pi. This is done with a Technique called Charlieplexing.
There are A LOT of pages on the interwebs about Charlieplexing and the Python language and how it all works so if you want to know more about it, feel free to use your favorite search engine to look into it more, lets just work on the basis that we switch LEDs on and off very quickly to make it look like we have more lit than we do
Why have I written this tutorial?
Because there is a lot out there but most of it requires a lot of prior knowledge or has incomplete files, or files that need modding, what I have provided is straight forward, and will get you up and running in under an hour
I hope this is so simple you can even enjoy doing it with your kids, if it isn't then let me know where i went wrong.
In this tutorial I am going to assume you have read about and understand the basics of both Charlieplexing and Python, we will concentrate on how to construct the hardware first, then I will give you 2 files containing Python code, 1 with a lot of pre-built functions you can use as a module and expand on, the other with some examples of how we program our display.
After following this tutorial and having a play with the code you will hopefully have a good understanding of Charlieplexing and be able to take the techniques used to move on to the next step, making your display bigger with shift registers!!!
for this tutorial you will need
small cheapo breadboard, trust me you need one of these...
You will need to work out what resistors to use, mine are 83 Ohm, but there is two of them in series for each LED(this will be explained why later), use a calculator to work out what you need and divide it by 2
You will need
20*male - male
5*male - female
It will help if you have 5 cables of 5 different colours, but it is not essential
Well, I may as well state the obvious
Step 1: The Hardware, LEDs
So, you have everything you need and yuo want to start plugging it all in.
Lets go then...
We are going to work the LEDs in pairs, I will put them either side of the split in the middle of the breadboard, 5 rows, 4 columns. First I will add the first column to column C on the breadboard starting at the top and working down you put all the long legs pointing to the top of the board,with the first led in holes 21 and 22
From top to bottom they go, white, blue, green, blue, green..
This time, long leg to the bottom of the board into column E
white, red, yellow, red yellow,
Same order as row 1, put them in column F
Same order as row 2, put them in Column H
So now you should have a nice matrix, just neaten them all up and go on to step 2
Step 2: The Wires... Oh the Mess.......
Lets be honest, there are a lot of cables in charlieplexing, but using colour coding we can make it easier on ourselves...
First the theory.
We want to wire everything up so every possible combination of wires is covered, this is why i used coloured wires.
1st take all your male - male wires in the first colour, I am using green
Put all 4 into row 1 columns A-D
Then take the other end and connect them to column A rows, 30, 28, 26, 24
Now it is time for colour 2
Put all 4, I am using orange into row 2 columns A - D
Now we make our first pair, green/orange so 1 wire into row 29
The rest need to be on there own, so put them into Column A, Row 22, and Column F, Rows 30 and 28
Had enough yet?
Yellow for me, I connect row 3 to Column A rows 27 and 21, and Column F rows 26 and 24....
Over half way! Well done...
Blue here, row 4 on the board to holes A25 J29 J25 and J22
Grey this time, row 5 on the board to the left overs, they should be A23 J27 J23 and J21, if not, something has gone wrong, have a look below as i have included the order we should have
We have now paired up all our LEDs, just for checking from bottom left going clockwise the order should be..
Green, Orange, Green, Yellow, Green, Blue, Green, Grey, Orange, Yellow, Grey, Blue, Grey, Yellow. Blue, Yellow, Grey, Orange, Blue, Orange
if all is in order, lets pop the resistors in!
Step 3: Resistors: Almost Done
Ok, simple step this one, for each of rows 1 - 5 pop a resistor across the middle gap, from Column E to Column D.
Because of the way i have wired these, every time an led is lit i am running the power through 2 resistors, therefor we add the value of them together to get the total resistance, although in practice this may not always be precise, it is close enough for our needs and saves us a lot of headache wiring each led up individually
Although not all the LEDs require the same resistance this will do for this tutorial, the green LEDs are a bit dim and could possibly do with a bit more juice, but, unless we are going to have 1 resistor per LED or massively over complicate our wiring this will do
I will probably give each led its own resistor when i put this project onto a prototype board at a later date
If like me you have left the legs long, make sure none of them are touching.
Now on to hooking up to your Pi
Step 4: Connecting to the Pi
Ok, now we connect up to the following pins:
Row 1 - Pin 7
Row 2 - Pin 11
Row 3 - Pin 12
Row 4 - pin 13
row 5 - Pin 15
YAY!!!! The hardware is done!! give yourself a big pat on the back, tell everyone around you how clever you are and revel in their dismissive eye rolling, gentle sighing, and leaning forward so they can hear the TV over you... After all, you have earned it!
You do not have to use these pins, you can use any GPIO you like but the software has been written to use these pins and will not require any modification if you hook up in this order!
Step 5: Software
Now we have our matrix its time to program it....
Attached are two files
ledfunctions.py and led.py
Go ahead and download them both, they are my present to you for doing such a good job with your hardware build.
If you would like a run down of what the ledfunctions.py file does go ahead and read below, if not then feel free to skip to the next step or just run the led.py file and watch your display jump into life.
OK.. lets have a look at what we have got in ledfunctions.py
Now we could just include everything in this in the main file but there is rather a lot isn't there, and by having it separate there is less chance of accidentally breaking it when modifying the other.
In this file we do a few things, firstly we grab a few modules we will need for the rest of the functions, namely all the GPIO stuff, randint() and sleep().
Then we set the warning off, this stops it telling us every time we try and change a pin state to something it already is, we do this a lot so it would never shut up.
Then we have the list of pin numbers we used.
Then we create a whole load of variables, this makes the rest easier to understand, we do not have to do it but it helps us later, for this list i have used the following format for the names.
LED row column
row is the row the LED is in, counting from the top to the bottom
column is the column counting from left to right
So led11 is led row 1 column 1
led 42 is LED row 4 column 2
Now some more lists, tell it which LEDs are red, green, blue, in row 1, row 2, column 1, column 2 Etc. Etc.
Now its time to create our list of pairs... We could add them all manually but why bother when Python will do it for us?
The next function is very important, this is how we light an led up!!!!
We first switch all the pins to inputs (remember I said we will be getting a lot of warnings if we don't switch them off)
Then we switch the first wire to an output and set it HIGH.
Then it is the second wire, we set that to an output and switch it LOW
This creates a path for the power and we light our LED.
This function is called as much as 100 times a second by the pre built script, you could try and go faster but i only have a model b rev 1 Pi and i don't think it will handle switching much faster than this, infact it sometimes struggles with this!
Built in functions.
Bellow this are a few built in functions.
I will explain these in the next stage.
Step 6: Software Continued, Built in Functions
So what functions do we have to play with?
Firstly, lets open up led.py and you will see at the top a few imports, including our ledfunctions.py, just leave these alone, if you want to add more you can
below is a load of comments, this gives a run down of the functions i have included, and there usage, but for reference here is a quick run down.
Switches all the LEDS off, usefull to use if you want to make sure the board goes dark
Light a single led, time is the time top light it for, led is the led to light in the format ledrowcol, eg led11 is led in row 1 column 1
Start from top left to bottom right, times is complete cycles, for speed the lower the value the faster the cycle
flashallonoff(times, ontime, offtime)
Switches all leds on and then off again,set how many times to flash, how long to be on for and how long to off for
Switch on a random led for the length of speed higher = longer, times is number of random leds to flash
flashrow(ontime, row, speed)
Ontime is higher = longer, row = integar counting from 1-5 from the top, speed = optional argument, how long each stays alight in seconds,if not defined the default is 0.001
flashrows(ontime, row1, row2, row3, row4, row5,)
Used to switch multiple rows on, row arguments are True or False
Ontime is higher = longer, colour = red, green, blue, yellow or white
Runs as flashrow()
flashcols(ontime, col1, col2, col3, col4)
Runs as flashrows()
Charstring is a list of characters to display, in the example script you will see it is 'HELLO WORLD' but you could change this or even use, for example
userinput = input()
showcharstring(userinput, 50) to ask the user to type something and display that a reasonable pace instead,
Time is how long to display each letter
NOTE: Feature currently supports numbers and UPPERCASE letters only
Step 7: Software: Making Some Patterns
The code below all the comments is all commented up as well but here again is a quick run down
try: < Try and do this first, if there is something wrong then it will look for an except, failing that it runs the finally section.
finally: < this is a bit that will always run when the program exits, either through finishing what it is doing, on an error or on an interupt
while True < this creates a loop that runs forever, we can break out of it easily with a keyboard interupt though (CTRL-C)
Now a little look inside the while loop, we have our functions, rather than explaining everything here, have a look at the script, whilst looking at it why not open up a terminal navigate to the folder you saved the scripts in and try running them with
sudo python3 led.py
Watch the lights and try and follow the script, this will give you an understanding of how to program it, how to make it work and how to expand to make your own display patterns
Enjoy your new matrix and if you have any questions please post them below.
Coming soon - creating a LED message runner with several of these matrix and a few shift registers, just waiting for the delivery from China