I picked up a 10 pack of these 7 segment red LED displays for less than $5. Since each display requires connecting to a minimum of 8 of the 10 pins (9 if using the decimal point), they aren’t exactly easy to work with. Sure, you can buy these where 2 or 4 displays are already connected in a nice package, controlled with the help of an integrated circuit, but where is the fun in that?
If you need to use more than 1 or 2 displays (at 8-9 pins per display), you’ll quickly run out of pins on your microcontroller or Raspberry Pi. The most common way to work with several of these displays is called multiplexing. It’s a method where you briefly turn on one display, turn it off, turn on the next one, and turn it off. You repeat this through all of your displays and then start over. If you do this fast enough, the human eye thinks all of the displays are on at once. It’s pretty slick!
The advantages of multiplexing are:
- Fewer wires/pins needed to drive the displays.
- Lower power consumption since the LEDs on only one display are lit.
Let’s get our hands dirty, shall we?
Seven of the pins on one of these displays match up to the 7 segments (labeled a through g), one pin is for the decimal point (DP), and the two remaining pins can be used for the common cathode (cc), though you only need to connect one or the other. Over to the right you can see how all of the pins and LED segments are arranged. Pretty straight forward.
I’m using 6 of these displays in a project, so I needed a lot of wires. It got complex and tangled in a hurry, but amazingly, I connected all the wires without a single mistake on my first try. 🙂 For the most part, I based my circuit design off of this schematic…
The end result is something like the Fritzing screenshot below. With so many wires overlapping, it’s not easy to see what’s really going on here. I suggest grabbing wiring.fzz from my GitHub repo and playing around with it in the Fritzing app.
When I went to write my proof of concept code, I decided to use the Gpiozero Python library to simplify working with the LEDs. The library allowed me to set up a couple of arrays for the LED segments and the 6 digits (displays)…
segment_leds =  for i in range( len( segment_pins ) ) : segment_leds.append( LED( segment_pins[i] ) ) digits =  for i in range( len( digit_pins ) ) : digits.append( LED( digit_pins[i] ) )
Then I could easily loop through and toggle the LEDs in a display as necessary…
for i in range( len( digits ) ) : for j in range( 7 ) : if ( numbers[ digit_values[i] ][j] ) : segment_leds[j].on() else : segment_leds[j].off()
To make sure things worked I count up from 999000 and then start back at 000000 after hitting 999999. You can see the full code on GitHub.
Now for some visual proof that I actually got it all working! Here it is running when I keep one digit lit for 5/10,000th of a second before turning it off and lighting the next digit.
You’d never know that only one digit is turned on at a time, would you?
If I change from 0.0005 to 0.05 of a second you can start to see that only one display is on at any point in time.
You may also notice it’s counting up a low slower due to the way this code increments the counter. Don’t worry about that.
When I keep each digit turned on for half of a second you can really see how this works.
An issue I’m running into on a Pi Zero is when the processor gets busy doing other tasks, there is a bit of flicker across the displays. You can see this a couple of seconds in to the first video. I’m guessing the code would perform much better on a Raspberry Pi 3B. For my project it’s not a concern, but I want to mention it in case you follow this for your own project. You may also pick up what looks like random flickering of a single digit here and there but that’s due to video timing; the human eye doesn’t see any of that when it’s in front of you.
If necessary, you can take multiplexing a step further and only light up an individual LED on each display at a time, with a method called charlieplexing. It will use even less power, but due to the speed at which you need to switch from one LED to the next, especially across an array of multiple displays, you lose brightness to the human eye.