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.
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.
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 . 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.
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.
For more detail: Driving a 7-segment display with a Raspberry Pi (I)