# Raspberry Pi with 7-segment display

- tags: cpp, hardware, programming, raspberry pi, rpi-hw - 10 comments

A seven-segment display is a display device that can be used to represent digits and, in some cases, decimal point.

Rpi-hw library provides two classes to manage this type of display, display::s7seg and display::m7seg, that are defined respectively in “rpi-hw/display/s7seg.hpp” and “rpi-hw/display/m7seg.hpp”.

The first class allows you to connect Raspberry Pi to a single seven-segment display. Its constructor method takes the ordered list of GPIO pins used for each segment of the display.

display::s7seg( A, B, C, D, E, F, G )
display::s7seg( A, B, C, D, E, F, G, DP )


For example, you can use the following configuration to display a single-digit counter from 0 to 9:

The code is very simple and doesn’t require much explanation:

// Include Rpi-hw headers
#include <rpi-hw.hpp>
#include <rpi-hw/utils.hpp>
#include <rpi-hw/time.hpp>
#include <rpi-hw/display/s7seg.hpp>

// Use Rpi-hw namespace
using namespace rpihw;

int
main( int argc, char *args[] ) {

// Seven-segment display controller
display::s7seg dev( 1, 4, 18, 15, 14, 0, 17 );

// Counter
size_t i = 0;

// Main loop
for ( ;; ) {

// Set the digit
dev.set( i++ );

// Wait some time
time::msleep( 500 );
}

return 0;
}


To compile it (or any other programs using the library) use the command:

g++ pkg-config --libs --cflags rpi-hw <SOURCE> -o <TARGET>


More interesting is the second class, display::m7seg, with which you can drive multiple displays at once using the multiplexing technique. Its constructor method takes the same parameters as the previous one.

Simply add some NPN transistors to the previous configuration in order to turn on one display at a time, with a frequency high enough to fool the human eye and make it believe that all displays are turned on simultaneously.

So you choose other GPIOs with which to activate the transistors, one for each transistor.

In this tutorial, I chose to use the GPIO pins 21 and 22 as “enablers”.

Here is a picture that shows how to connect two seven-segment displays to Raspberry Pi.

The instance of display::m7seg will update the displays one at a time, writing their position number to an output interface named “enabler”, which is responsible for turning on the display.

You can use different types of output interfaces for this task, but in this context you should use the class iface::decoderOut, defined in “rpi-hw/iface/decoder-out.hpp”.

This class converts the position number of the current display (passed by the display instance) into a single high output directed to its transistor.

The following code show how to drive the two displays:

// Include Rpi-hw headers
#include <rpi-hw.hpp>
#include <rpi-hw/time.hpp>
#include <rpi-hw/iface/decoder-out.hpp>
#include <rpi-hw/display/m7seg.hpp>

// Use Rpi-hw namespace
using namespace rpihw;

int
main( int argc, char *args[] ) {

// Multiple seven-segment display controller
display::m7seg dev( 1, 4, 18, 15, 14, 0, 17, 23 );

// Create the enabler interface
iface::decoderOut enabler( { 21, 22 } );

// Set the number of displays and the enabler interface
dev.setDisplays( 2, enabler );

// Set the updating frequency (Hz)
dev.setFreq( 100.0 );

// Set the format of the display
dev.format( 1, false );

// Counter
float i = 0.0;

// Main loop
for ( ;; ) {

// Set the value of the display
dev.set( i );

// Increment value of the display
i += 0.1;

// Wait some time
time::msleep( 500 );
}

return 0;
}


Similarly, you could have used an hardware decoder with the simpler class iface::output instead of iface::decoderOut. The latter class, in fact, is a software implementation of this device.

You can find more information on the reference manual and on the wiki.

Feel free to send me suggestions, feedbacks, or correct my bad English if necessary!

1. Hi, congratulations for your article! good explanation and clear!
I’m a electronic / Raspberry pi beginner and i would to ask you some information.. my project is to do a raspberry pi clock with 7 segment display. my idea is to send on four 7sd the system datetime (example 12.30) …could you help me? i know arduino code but i don’t know python. Using your multiplexing method (without decoder) how can i say..(loop) read datetime and turn on pins every half second? thanks

Nicola Buillas on Sun, 21 Jul 2013 @ 8:56 am
2. Hi Nicola

All you need to do is split the current time into 4 digits and display it with the multiplexing technique. The refresh rate of the displays must be set to 30-100 hz, but the time can be updated every second.

For now, my library only allows you to represent single numbers (integer or decimal), so if you want to use the class display::m7seg you must first convert the time into a integer value (for example 12:30 => 1230). See the below code:

#include <iostream>
#include <ctime>

int get_time() {

time_t raw = time(0);
struct tm *now = localtime( &raw );

return now->tm_min + 100 * now->tm_hour;
}


So you can rewrite the example in my article into something like the following:

// Include Rpi-hw headers
#include <rpi-hw.hpp>
#include <rpi-hw/time.hpp>
#include <rpi-hw/iface/decoder-out.hpp>
#include <rpi-hw/display/m7seg.hpp>

#include "mytime.hpp" // Function get_time seen above

// Use Rpi-hw namespace
using namespace rpihw;

int
main( int argc, char *args[] ) {

// Create the display controller
display::m7seg dev( 1, 4, 18, 15, 14, 0, 17, 23 );

iface::decoderOut enabler( { 21, 22 } );
dev.setDisplays( 2, enabler );

// Main loop
for ( ;; ) {

// Update the current time
dev.set( get_time() );

// Wait a second
time::sleep(1);
}

return 0;
}


To avoid complicated wiring, I suggest you buy one of these: http://goo.gl/rJQj6

admin on Sun, 21 Jul 2013 @ 12:09 pm
3. Hi. Great blog post, got me thinking.

I was thinking of doing something very similar with some MCP23017 chips, which simply give 16 IC outputs for the Raspberry Pi.

I was going to use 7 outputs per 7-segment display and use 4 of the displays I.e. using 2 MCP23017 chips.

Problem is, when I light up all digits like “8 8 8 8” I fear that the Pi or chip wont be able to handle having all those leds on at once. Multiplexing seems the way to do it, but I can’t get my head around how to do it. I only have a little experience in Python…C feels very alien to me.

Any thoughts?

Average Man on Tue, 10 Sep 2013 @ 1:58 pm
4. Thank you, Average Man..

Actually turn on all the LEDs at once is not recommended because of the voltage drop. Also, you can’t control two MCP23017 chip at once, because of Raspberry Pi has only one I2C port.

Therefore the multiplexing technique is the best approach to do it.

But if you want to use Rpi-hw library and Python for your project, you might consider the following solution:

The Python script launches the first program in a separate process, so you can control the display directly in Python. You will just have to change the GPIO pins before compiling the C++ program.

It’s not the best solution, but at least it’s something.

admin on Tue, 10 Sep 2013 @ 6:07 pm
5. You can use up to 8 MCP23017 chips at once, you just daisy chain the IC connections and give each chip a different address (My blog covers this I think…will check).

Thanks for the suggestion, will give this a try when I get home this weekend.

Average Man on Wed, 11 Sep 2013 @ 7:02 am
6. You’re right.

admin on Wed, 11 Sep 2013 @ 9:59 am
7. hello, i’m approaching the raspberry in those days

please, i have few electronic knowledge: could you say me a transistor npn “model” for allow the multiplexing?
no probs for wiring and dimensioning the resistors, but the trasistor for me is a nightmare

thanks!

Albe on Wed, 18 Dec 2013 @ 11:18 am
8. Hi Albe,

You can use several transistor models. For example, the 2N3904..

admin on Fri, 20 Dec 2013 @ 12:59 pm
9. you done grate job
i wanted to do the same with 4 inch five digits 7 segment display
can you please tell me how to control the high voltage seven segment displays with raspberry pi
in my circuit i am using ULN2803 for give data pins to segments data pins and i given a high voltage 18v to ULN2803 .
and i given common pin of 7 segment to collector of transistor like NOT gate .
it works getting number on display but it not much brighter i wanted to increase the brightness of displays can you give me the suggestions please.
thank you …..

vivekanand goud j on Thu, 20 Mar 2014 @ 6:41 am
10. Hi, I’m having troubles getting the display_ctl.cpp and display.py method to work. the .py seems to be working, it writes “Set value 15\n” to the pipe, I verified it with a program that is opened in place of display_ctl in the python. Is there a special format the data needs to be in to get printed to the displays? (I’m using two 7-segs). If I open display_ctl alone, the 7-segs display “-0” is that to be expected? I realize this is fairly old, but I can’t find a purely python substitute, or even another substitute. If I can’t get this to work my project is sentenced to death! Thanks!

PerfectDirections on Sun, 15 Feb 2015 @ 2:10 am