Raspberry Pi with 7-segment display

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

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

7-segment display - Video

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:

7-segment display - Circuit

7-segment display - Circuit

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.

Multiplexing 7-segment displays - Circuit

Multiplexing 7-segment displays - Circuit

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.

Multiplexing 7-segment displays - Animation

Multiplexing 7-segment displays - Animation

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.

Multiplexing two 7-segment displays - Circuit

Multiplexing two 7-segment displays - Circuit

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.

Multiplexing 7-segment display - Animation

Multiplexing 7-segment display - Animation

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! ;)

Did you find this article helpful?

9 comments

  1. 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 user image
  2. Hi Albe,

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

    admin on Fri, 20 Dec 2013 @ 12:59 pm user image
  3. 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 user image
  4. You’re right. ;)
    (https://www.adafruit.com/datasheets/mcp23017.pdf)

    admin on Wed, 11 Sep 2013 @ 9:59 am user image
  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 user image
  6. 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.

    Unfortunately, I couldn’t find anything in Python that could help you..

    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 user image
  7. 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 user image
  8. Hi Nicola ;)

    I’m glad you found my article helpful.

    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 user image
  9. 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 user image

Add a new comment

Please insert the result of the arithmetical operation from the following image:

Please insert the result of the arithmetical operation from this image. =