By dave | May 4, 2015

On the previous page covering single digit displays, we dealt with driving one 7-segment digit. On this page we’ll use a multi-digit display and assume 4 digits. Just like single devices, multi-digit 7-segment displays have connections for A-G, DP and common, but they have a common pin for each digit, with one set of A-G and DP pins that are shared. So for a 4 digit display there will be four common pins.

Given there is one set of A-G and DP pins and a common for each display, we must multiplex each digit’s common by switching between them in turn changing the A-G and DP segments as we do.

If you’re looking for a quick solution, we also have a library that makes working with 7-segment displays much easier.

## Block diagram and pseudo code for a two digit 7-segment display:

The pseudo code below explains how to render a hexadecimal value onto a two digit display. As we said earlier only ever one digit enabled, but if we interleave between the two at a high enough frequency then it’s no longer possible to see any flicker. We will convert this into Arduino code later in the tutorial.

``````/* PSEUDO CODE TO DRIVE TWO DIGIT DISPLAY (00 - FF) */
INTEGER valueToDisplay
FOREVER
INTEGER digit1 = valueToDisplay / 16;
INTEGER digit2 = valueToDisplay % 16;
writeToDisplay digit1
turn on digit 1
turn off digit 2
delay 1 millisecond
writeToDisplay digit2
turn off digit 1
turn on digit 2
delay 1 millisecond
END
``````

## Components required for this tutorial:

• One 7-segment display with 4 or more digits
• Eight 2k2 resistors
• Arduino board with wire and bread board
• 10K or greater potentiometer

Let’s assume for example that we have a four digit display (if you have more or less digits change variable `noOfDigits` as appropriate), and that we wish to display the analog input reading onto the display. For this we need to start with the circuit on the left. Only now, instead of connecting the common pin to either GND or 5V, we now need to connect each common pin to an Arduino board output pin.

As with the previous example `ledStart` sets the pins on which A-G and DP are connected to the Arduino board, they must be in order and sequential. Common pins must also be connected sequentially for the example - directly following the A-G and DP pins. Don’t forget that each A-G and DP pin MUST have a resistor of 2K2 between the display and the Arduino board.

As an aside, we are going to use the AVR chip output ports in a slightly unusual way; so that it can both turn on and off the segments and control the common return. if you need a refresher on how Arduino outputs work this site explains how outputs work really well.

Connect a potentiometer that allows you to vary the voltage on an analog input. If you’re unfamiliar with how to connect a potentiometer to analog in, see Arduino single 7 segment analog measurement example.

In the code below, we read the analog input and present it onto the multi segment display in decimal. Notice in the program that because we have four digits, we can display the whole number without any scaling.

## Running the code in Arduino IDE

To run the example copy the code below into a new session and change the variables as follows:

• Variable `ledStart` should be set to the pin you started wiring the LED on, (for segment A and all other segments must follow on sequentially)
• Variable `commonHigh` should be true if you connected common to 5V, false if you connected it to GND.
• Variable `analogInput` should be set to the analog input pin the wiper is connected to.
``````
// the start of the pins used for A-G - must be sequential
int ledStart = 30;

// the start of the common pins - must be sequential
int commonStart = 38;

// this code can use either polarity of display.
// true if common is high when ON, otherwise false.
boolean commonHigh = true;

// the number of digits your display has.
int noOfDigits = 4;

void setup() {
// Enable all A-G and DP and outputs,
// set them to OFF
for(int i=0;i<8;++i) {
pinMode(ledStart + i, OUTPUT);
digitalWrite(ledStart + i, commonHigh?1:0);
}

// Setup all the common pins, initially OFF.
for(int i=0;i<noOfDigits;++i) {
pinMode(commonStart + i, OUTPUT);
digitalWrite(commonStart + i, commonHigh?0:1);
}
}

void loop() {
// digits to display it now.

for(int i=(noOfDigits-1);i>=0;--i) {
// find the current digit, which is in the low 4 bits
int digit = amount % 10;

// and write out the representation of the voltage
writeDigitToDisplay(digit);

// enable the right digit for display
digitalWrite(commonStart + i, commonHigh?1:0);

// short delay between changes.
delay(1);
// Turn of the right digit for display
digitalWrite(commonStart + i, commonHigh?0:1);

// get the next digit.
amount = amount / 10;
}
}

// Now we define the bits that are on and off
// for each segment, These are used in the
// function below to turn the right bits on.
int dig = {
// bits     6543210
// digits   abcdefg
0b1111110,//0
0b0110000,//1
0b1101101,//2
0b1111001,//3
0b0110011,//4
0b1011011,//5
0b1011111,//6
0b1110000,//7
0b1111111,//8
0b1111011,//9
0b1110111,//a
0b0011111,//b
0b1001110,//c
0b0111101,//d
0b1001111,//e
0b1000111 //f
};

void writeDigitToDisplay(int digit) {
digit = (digit & 0x0f);
// iterate through each bit
for(int i=0;i<7;++i) {
// isolate the current bit in the loop.
int currentBit = (1<<(6-i));

// check if the bit is on, and invert for
// commonhigh if needed.
int bitOn = (currentBit&dig[digit])!=0;
if(commonHigh) {
bitOn = !bitOn;
}

// and lastly set the bit
digitalWrite(ledStart+i, bitOn);
}
}

``````

Lastly, here’s another example of this sketch running. Yes it looks a bit messy!

Don’t forget we have a library that makes working with 7-segment displays much easier.