Arduino 7 Segment Display Interfacing | Multiplexing
In this tutorial we are going to learn how to interface 7 segment displays (common cathode & common anode) with Arduino by using “SevSeg” library and the concept using multiplexing. We will learn how to interface one to four digit-7 segment displays with Arduino.
We will see:
- Understanding the Fundamentals.
- What is Multiplexing?
- How Multiplexing Works?
- Circuit Diagram.
- Program and Explanation.
- Digital Clock Using Arduino and 7 Segment Display.
Understanding the Fundamentals:
Seven segment displays come across our daily life with a finished product like: microwave oven, digital clocks, speedometers etc. Most of them are controlled by some sort of microcontroller; by understanding how it works we can implement it on our own projects in efficient way like reduced cost, power consumption and number of wires that connects to 7 segment displays.
All the commercial products which employees 7 segment display are multiplexed and are either common cathode or common anode type. Multiplexing helps in reducing the power consumption of any battery operated device significantly, with the power consumption of single 7 segment display we can power an array of 7 segment displays.
What are Common Cathode and Common Anode types?
A common cathode 7 segment display whose all the cathode terminals (-) are connected to ground and the anode terminals (+) are controlled individually by an IC or microcontroller. In common anode, all the anodes of the LEDs are connected to (+) 3V and cathode terminals are individually controlled by microcontroller.
Internal Diagram of 7 Segment Display:
What is Multiplexing of 7 Segment Display?
The concept:
Multiplexing is a technique where different data signals are passed through a common path or a common group of wires (called bus) which are shared with different destinations.
For example: Let us assume we have devices A, B and C let these devices be any communication devices and A, B and C need 5 wires each for data communication. Now instead of wiring up 5 + 5 + 5 = 15 wires, we will connect only 5 wires for all the three devices. Now you may wonder since the entire devices share the same 5 wires how do we prevent the wrong data stream entering wrong devices? Good question, this problem is addressed with “select lines”.
Select Lines:
“Select Lines” are the wires which enable or disable the communication to the individual devices, since we have 3 devices here, we will have 3 select lines. When device ‘A’ is selected the B and C device are disabled, we will send a data stream via 5 wires which will reach the destination device ‘A’ and B and C will ignore the data stream. Similarly when device ‘B’ is selected, now A and C are disabled and ‘A’ and ‘C’ will ignore the incoming data stream.
So we just need 5 (data) + 3 (select) = 7 wires instead of 15 wires.
The exact same concept is applied to 7 segment displays. Below is the circuit diagram of 4 digit-7 segment displays which are multiplexed:
Each 7 segment display has 8 data lines (A, B, C, D, E, F, G and one decimal point) which light up 8 individual LEDs, to display four digits we need 8 x 4 = 32 wires when not multiplexed.
Multiplexing of 7 segment display involve connecting each segments together as illustrated in the diagram. The select lines are the common terminals of a single display. Now the wire count reduced to 8 (data lines) + 4 (select lines) = 12 wires instead of 32 wires.
How Multiplexing on 7 segment display is done?
Let’s assume we want to display “9867” on a 4 digit display, to do that the microcontroller applies LOW signal (to common cathode terminal) to the first digit and apply +Ve signals to each segments to light up the LEDs to show digit “9”, after few milliseconds it stop applying LOW signal to the first digit and applies LOW signal to the second digit and also applies +Ve signals to each segments to show digit “8” similarly for 3rd to show digit “6” and 4th digit to show “7” and the cycle repeats.
One important thing to be noted is that at any given instant only one digit lights up and rest of the 3 digits stays OFF, but due to the “persistence of vision” we will perceive that all the four digits are lit up simultaneously as shown below:
Circuit Diagram for multiplexing 7 segment display with Arduino:
If you don’t want to connect 4 individual 7 segment display together with wires as illustrated above, you may purchase ready made 4 digit 7 segment display like shown below:
Now you know how a multiplexed 7 segment display works, now let’s see how to write code for Arduino.
Here we are using “SevSeg” library which will take care of multiplexing.
Download SevSeg Library: Click here
Program code for displaying static digits:
//-------Electronics-project-hub.com---------// #include "SevSeg.h" SevSeg Display; void setup() { byte numDigits = 4; byte digitPins[] = {10, 11, 12, 13}; byte segmentPins[] = {2, 3, 4, 5, 6, 7, 8, 9}; bool resistorsOnSegments = true; bool updateWithDelaysIn = true; byte hardwareConfig = COMMON_CATHODE; Display.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments); Display.setBrightness(100); } void loop() { Display.setNumber(9867); Display.refreshDisplay(); } //-------Electronics-project-hub.com---------//
The above code will display a static number “9867” on a 4 digit-7 segment display.
Now let’s see the explanation for the code:
- To select the number of digits:
byte numDigits = 4;
4 for four digits, 3 for three digits, 2 for two digits and 1 for single-7 segment display.
- Selecting pin numbers for select lines:
byte digitPins[] = {10, 11, 12, 13}; // (D1, D2, D3, D4)
Here the select lines are common terminal of a seven segment display, if you are using only two digits we can write as:
byte digitPins[] = {10, 11}; // (D1, D2)
These pins are user selectable and you can change the pin numbers as per your requirements.
- Selecting pin numbers for data lines, that is: A, B, C, D, E, F, G and DP:
byte segmentPins[] = {2, 3, 4, 5, 6, 7, 8, 9}; // A, B, C, D, E, F, G and DP
- If you are using a common cathode display then,
byte hardwareConfig = COMMON_CATHODE;
- If you are using a common anode display then,
byte hardwareConfig = COMMON_ANODE;
- To set display brightness:
Display.setBrightness(100);
100 is full bright and 0 is lowest brightness.
- The below line will print number to 7 segment display:
Display.setBrightness(100);
- If you want to print floating numbers then,
Display.setNumber(9867, 3);
This will print as 9.876 on 4 digit-7 segment display.
- The below line updates the data on the 7 segment display:
Display.refreshDisplay();
Now let’s see how to make simple 7 segment display counter with 4 digits:
The circuit diagram is same here; we just need to upload a new code:
Program code for counter (0 to 9999):
//-------Electronics-project-hub.com---------// #include "SevSeg.h" SevSeg Display; unsigned int number = 0; const unsigned long period = 250; // in millisecond unsigned long startMillis; unsigned long currentMillis; void setup() { byte numDigits = 4; byte digitPins[] = {10, 11, 12, 13}; byte segmentPins[] = {2, 3, 4, 5, 6, 7, 8, 9}; bool resistorsOnSegments = true; bool updateWithDelaysIn = true; byte hardwareConfig = COMMON_CATHODE; Display.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments); Display.setBrightness(100); } void loop() { currentMillis = millis(); if (currentMillis - startMillis >= period) { number = number + 1; startMillis = currentMillis; } if (number >= 10000) { number = 0; } Display.setNumber(number); Display.refreshDisplay(); } //-------Electronics-project-hub.com---------//
The above code will count from 0 to 9999 and resets to zero and counts again, each count is incremented every 250 milliseconds.
IMPORTANT NOTE:
we should not use Delay() function here, this will interrupt the multiplexing process and will display broken digits. Instead of using Delay(), learn how to use millis() function and how to generate delay for any process without actually pausing the loop.
Digital Clock Using Arduino and 7 Segment Display:
Using this library we can build any 7 segment display projects like this cute little digital clock. Click here for full project in detail.
If you have any question regarding this tutorial feel free to ask us in the comment section, you will get a guaranteed reply from us.
U r all projects very nice
Thanks…
Hi, may i know how about for 3 digit 7 segment connection?
Hi,
Just remove the unused display….
hey bro you can use this code for 3 digits 7segment display
#include “SevSeg.h”
SevSeg Display;
void setup()
{
byte numDigits = 3;
byte digitPins[] = {10, 11, 12};
byte segmentPins[] = {2, 3, 4, 5, 6, 7, 8, 9};
bool resistorsOnSegments = true;
bool updateWithDelaysIn = true;
byte hardwareConfig = COMMON_ANODE;
Display.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments);
Display.setBrightness(100);
}
void loop()
{
Display.setNumber(987);
Display.refreshDisplay();
}
Yes you can!
Hello bro, how can I use this code and library if I use a BCD decoder like CD4511?
No, it won’t work!
hey bro display is repeating the first number in the last like if I have to print 15 it prints 515 please tell me why is it happening
Hi,
There is short circuit between select line D1 and D3 that’s why it is repeating. Also check for any other short in your circuit.
Regards
this happening only in one code if i test display with test code then it is performeinf well
sorry, I could not understand what you said……
Hi Blogthor
Just wondering why only one current limiting resistor is connectet to each display. I guess that it means that only one SEGMENT of the display is “on” at any given time. If not, current in the 220 ohm resistor will change depending on what number is shown, and thereby change the brightness of the display.
Can You elaborate on this? Thanks
Michael
Hi,
Yes you are right! Ideally the current limiting resistor should be connected to all the segments instead of a common terminal. But, there is no perceivable brightness change with any of the display with a common current limiting resistor. I have made a digital clock using the same display diagram and it is just working fine for past 3+ years.
And yes, if this is a production design I would connect 7 current limiting resistors to 4 displays, for DIY solution this is good enough.
Regards
Hi blogthor l need to ask this l am trying to design a 3 digit calculator for a 3- segment display using tinkercad as instructed by my university but the issue is that tinker cad doesn’t have SevSeg.h liabray so can you help because right now l interfaced 4×4 keypad with Arduino uno and l created my code its working well using serial.print but l am supposed to use 3 – 7 segment display
Sorry for the late reply,
I have very limited knowledge in tinkercad, please search for any other 7 segment library and try implement it.
Thanks for yours.
Would you plese show , add the TIP127 (Transistor), TPIC6B595N,SN74HC573AN in case using 7 segments more than 4 digits. Ex I need 12 digits.
Thank you.
We will try to do in future, you may also check out IC4026 if you want to drive huge number of 7 Segment LED displays.
Is it possible to use 6 single 7 segment displays?
Yes, we can!
Thank you for your reply. I’m an absolute noob; Any tips to get me on the way?
How can you drive 6x digits, with only 8 segment pins + the digit pins?
There are no more pins left for digit 5 and 6?
You can use the A0 to A5 as digital output.
Can you please give me a hint or directions on how to wire 6 single digit displays?
There aren’t enough pins, I assume?
(BTW I’m a total newb) 😉
Thanks!
Please use A0 and A1 for additional select lines D5 and D6 for the two new displays and connect non-common pins to 2 to 9.
Also change this in the code:
byte digitPins[] = {10, 11, 12, 13, 14, 15}; //14-A0, 15-A1
Hi,
You are using one resistor per each digit. This is wrong since the current (and the brightness) of the segments will not be identical. Display of 1 (driving two segments) is much brighter than display of 8 (The same current drives 7 segments ) .
Moreover, when you drive more than one diode (led, segment) in parallel, the current is not eaually divided between the diodes.
Please comment on this.
Hi,
Yes, you are right. We did this just for demo purpose so that beginners can understand the concept of multiplexing first.
We also made a 7 segment digital clock using just 4 current limiting resistors just as illustrated and the clock is running for 3 years without any problem or any difference in its brightness. What I am saying is this is “good enough” for a home project, but if we are making for mass production then we must have individual resistors for all segments.
Regards
how about 5 inch seven segments display, which requires 11-12V? I’m about to connect 3 digits.
You can use a buffer IC 7404 from segments A to G to handle higher current and voltage. Please refer the datasheet of 7407.
is this library opensource??
Yes, it is available on github.
Very interested in replicating this for 3 digits. I have 3 common anode type 7 segment displays. Is your code and circuit diagram suitable for common anode or do I need to make changes?
Hi,
Yes, the code is suitable for common anode and cathode, change the following:
byte hardwareConfig = COMMON_CATHODE; to byte hardwareConfig = COMMON_ANODE;
Regards
I am using transistors for buffer stage for driving large seven segment display with pro mini but all segments of all digits are lighting all the time. I can observe very fast flickering. Can I decrease the multiplexing speed in the code and where ?
Hi,
You are correct, even we tried the same and we were not able to drive larger displays. The underlying problem could be because the transistor could not respond as fast as microcontroller. I don’t think we can reduce the speed of multiplexing with the provided library.
Regards