Driving a 7-segment display with a Raspberry Pi (I)

This post will be the first of a series of posts that will describe how to drive a 7-segment display from a Raspberry Pi, without any OS running in it. Today, I will talk about some important characteristics about 7-segment displays, how to wire things up, and another considerations that you ought to take into account before coding anything.

Even though I will describe general aspects and concepts about driving 7-segment displays, I will always use as an example my D323G (you can download the spreadsheet from here).

Common-anode vs common-cathode displays

The first to know about a 7-segment display is that you may have basically two types: common-cathode or common-anode displays. As you may know, each of the segments of a 7-segment display are LEDs, which is a short-hand for Light Emitting Diode. Thus, each of the segments will have an anode and a cathode, as every diode has.

In order to reduce the amount of pins any particular display has, one can connect altogether the anodes or the cathodes of every segment, and use only the cathodes or anodes, respectively as the pins that must be drove in order to lit the corresponding digit.

Common anode schematic.

Figure 1. Common anode schematic. Source: University of Hawaii.

So, in common-anode means that we have to drive HIGH the common-anode and LOW any of the other pins in order to allow for current to flow through that particular LED (aka “segment”). On the other hand, for a common-cathode, we will have to drive LOW the common-cathode and HIGH each of the pins. It is immediate to see that in a common-anode we will have to sink current through each of the pins that enable each segment, and source it through each of the common-anodes, while in a common-cathode we will need to do it in the opposite way. This is very important, as we may have different restrictions in our microcontroller for sinking/sourcing current, so we may be able to choose the most favourable condition.

Forward voltage (VF) and current (IF)

As you know, you need a certain amount of voltage across your diode in order to lit it. Depending on the amount of voltage and current, your LED will be “glow” with a different intensity, or not glow at all, as can be seen in the following figures.

D323G 7-segment display charts.

Figure 2. D323G 7-segment display charts. Please note that all of the values shown are per individual segment.

Top-left image shows the relation between forward voltage and forward current: we will use this chart to select the desired current we want to use to drive our segments, which in the end will led to the selection of an appropriate resistor. We can also see how temperature and duty cycle affect the luminous intensity (note: even though today we will select the set-point based only on the intensity, it is typical to use the duty-cycle as a way of controlling the luminance: this is known as PWM, Pulse Width Modulation).

We will be using those charts, as well as the datasheet of our microcontroller in order to select our adequate set-point.

Selecting the set-point

For the moment, taking into account that, by default, the Raspberry Pi’s GPIOs are configured to source 2mA, we will try to find our resistor in order to sink that amount of current when driving our GPIO to LOW (the common-anode, on the other hand, shalle be HIGH, of course).

It is easy to see that [latex]R_{1} = {{V_{cc}-V_{F}}\over I_{F}}[/latex]. In our particular case, where Vcc = 3V3, and IF=2mA, VF=1.85V, we will need to use a R1=725Ω. If you don’t have one, you can put several resistors in series until you sum up that amount, or just select the closest one: in my case, I will be using a 680Ω, which will led to a slightly higher current.

Schematic for the computation of the correct series resistor to be used with an LED

Figure 3. Schematic for the computation of the correct series resistor to be used with an LED

Creating the circuit

Now that we know what is the resistor that we will be using, we may think about several options to connect our 7-segment display to our microcontroller. For my particular display, D323G, I’ve got 9 pins: two common-anodes to select the digit, and 7 pins for each of the segments of each digit. Bear that in mind:

  • We could wire our resistors as in Figure 3, using only two of them: one for each anode.
  • We could wire seven resistors, one for each of the pins that drives a segment.
  • We could buy an IC that does all the work for us -or even better, design it by ourselves!-.

In either case, we can turn on all of the segments at the same time, or turn them on sequentially, at an enough rate as that due to persistance of vision our eyes see as they are always turned on. In case you put your resistors before the common-anode, if you drive your segments all at a time, you will have only 1/7 of the desired current flowing through them, thus, they will barely light. On the other hand, if you put your resistors before GND, then you will have 7x the desired current flowing through your common-anode: for us, that is close to the maximum allowed current through one single GPIO for the Raspberry Pi, so this is not an option for us.

The only option left is to drive them one at a time, fast enough as to create the illusion as if they were all lit at the same time. We will then need to know the pin-out schematic for our 7-segment display, in order to place the resistors and connect it to our GPIOs: Figure 4 shows the pin-out for my D323G 7-segment display. It was obtained from the datasheet.

D323G pin-out diagram

Figure 4. D323G pin-out diagram. If you do not have this, you can always try to find what is what with the help of a voltimeter, setting it in the “diode mode”, and trying different combinations until you start to get segments lit. This way you will get not only the pin-out but also if you have a common-anode or a common-cathode.

If you do not have a datasheet, you can find the pin-out with the help of a multimeter just by trying different combinations of probes-to-pins in “diode” mode: this mode makes some current flow from anode through cathode, and thus will light-up your segment if you find the adequate combination). One way or another, you will end with something like this:

Figure 5. 7-segment display in a breadboard, ready to be connected to the Raspberry Pi

Figure 5. 7-segment display in a breadboard, ready to be connected to the Raspberry Pi. Reddish cables are for the common-anode of each of the digits, while darkish cables are for the rest of the pins that will lit each individual segment. You can see the two 620Ω resistors that will be used to keep current under safe margins.

The test

This is the moment, guys. We will test out everything we’ve learnt, and see if it was right or if we fucked up. Our test set-up is going to be as simple as possible. We will connect one of the common-anodes to a 3V3 source, and one of the segment’s pins to GND. If we do not blow out our Pi, we will try to measure voltage and current, to see how far we were.

Before proceeding, please beware that to measure voltage you have to put your probes in parallel, and to measure current you have to do so in series. If you do it the other way round you might damage your Pi!

As you can see, we’ve got IF=1800μA, VF=1887mV. Almost perfect!

What’s next?

Now, we can start coding. We will create a mapping between 7-segment pins and GPIOs, to be able to drive each segment as demanded. Then, we will start creating the software in order to drive the 7-segment to drive any desired number. As we do this, we will think about how to use this display to show, for example, information from a temperature sensor, which will lead us to think a bit more about real-time and scheduling deadlines…


Some useful links, as always, to read a bit more about this subject.

Posted in Hardware Tagged with: , , ,

Leave a Reply

Your email address will not be published. Required fields are marked *