Google+ Facebook Twitter Pin It Reddit

Working with Seven Segment LED Displays

By Philip Kane

This is s a quick introduction to the basics of using seven segment LED displays with microcontrollers. Be sure to refer to the manufacturer's data sheets for more information about the devices mentioned in this tutorial.

Structure and operation of a seven segment LED display
Figure 1 shows a seven segment LED display. As indicated by the diode equivalent circuit on the left, each segment is an individual LED. This is a Common Cathode (CC) display. All of the cathodes (or negative terminals) of the segment LEDs are connected together.

To turn on a segment, you set its associated pin to HIGH (figure 2).

Seven segment common cathode displayFigure 1: Seven segment common cathode display.
CC display, segment pins b and c set to HIGHFigure 2: CC display, segment pins b and c set to HIGH


In a Common Anode (CA) seven segment display (figure 3) the anodes (positive terminals) of all of the segments are connected together.

Seven segment common anode displayFigure 3: Seven segment common anode display
CA display, segment pins b and c set to LOW.Figure 4: CA display, segment pins b and c set to LOW.


To turn on a segment, you set its associated pin to LOW.

The resistors in the above figures limit the current through each segment to no more than the specified maximum forward current (If).

Part list:

Working with 7-Segment LEDs without Arduino

(1) Arduino Uno R3
(2) Display 7-Segment Red
(20) 220Ω Carbon Film Resistor
(10) 10kΩ Carbon Film Resistor
(10) General Purpose Transistor
(1) 9V Battery Snap
(1) 9V Alkaline Battery
(1) 830-Point Solderless Breadboard
(1) 70-Piece Jumper Wire Kit
(1) BCD to 7 Segment Latch decoder Driver

Working with 7-Segment LEDs with Arduino

Interfacing microcontrollers and seven segment displays
Figure 5 shows a common cathode seven segment display connected to an Arduino Uno single board computer (SBC). You will need a USB-A to B cable to program the Arduino.

Arduino Uno connected to seven segment display.Figure 5: Arduino Uno connected to seven segment display.


It requires 7 digital I/O pins to drive the segments, 8 if the decimal point is included.

Arduino with seven segment display output
Figure 5a: Arduino with seven segment display output


The example code shown in Listing 1 repeatedly displays the digits 0-9 and the decimal point. The main loop calls the function DisplayDigit to display the next number. Function DisplayDigit gets the seven segment pattern for the digit and sets the segment pins accordingly.

Arduino with seven segment display output

Listing 1

// One digit 7 segment LED display demo.
// Displays digit 0 - 9 and decimal point

int segPins[] = {9, 8, 7, 6, 5, 4, 3, 2 };   // { a b c d e f g . )

byte segCode[11][8] = {
//  a  b  c  d  e  f  g  .
  { 1, 1, 1, 1, 1, 1, 0, 0},  // 0
  { 0, 1, 1, 0, 0, 0, 0, 0},  // 1
  { 1, 1, 0, 1, 1, 0, 1, 0},  // 2
  { 1, 1, 1, 1, 0, 0, 1, 0},  // 3
  { 0, 1, 1, 0, 0, 1, 1, 0},  // 4
  { 1, 0, 1, 1, 0, 1, 1, 0},  // 5
  { 1, 0, 1, 1, 1, 1, 1, 0},  // 6
  { 1, 1, 1, 0, 0, 0, 0, 0},  // 7
  { 1, 1, 1, 1, 1, 1, 1, 0},  // 8
  { 1, 1, 1, 1, 0, 1, 1, 0},  // 9
  { 0, 0, 0, 0, 0, 0, 0, 1}   // .
};


void displayDigit(int digit)
{
  for (int i=0; i < 8; i++)
  {
    digitalWrite(segPins[i], segCode[digit][i]);
  }
}

//***************************************************************************
//******************************************************************************
void setup()
{
  for (int i=0; i < 8; i++)
  {
    pinMode(segPins[i], OUTPUT);
  }

 }

//******************************************************************************
//******************************************************************************
void loop()
{
   for (int n = 0; n < 11; n++)    // display digits 0 - 9 and decimal point
  {
     displayDigit(n);
     delay(1000);
  }

}

Multiple digit displays (multiplexing)

The circuit in figure 6 shows an Arduino SBC connected to two seven segment displays. Note that only two additional I/O pins are used to drive the displays. They are used to turn each display on and off. Both displays share the same segment pins but only one display is on at a time. Multiplexing the displays like this enables you to use one set of segment pins to drive multiple displays.

Two digit multiplexed display circuitFigure 6: Two digit multiplexed display circuit

Listing 2 shows the Arduino code for a simple application that repeatedly sends a sequence of numbers, from 0 to 99, to a 2 digit multiplexed display.

Listing 2

// This is the two digit multiplexed display demo.

int segPins[] = {9, 8, 7, 6, 5, 4, 3, 2 };
int displayPins[] = {10, 11};   // pin 10 controls D0, pin 11 controls D1
int displayBuf[2];                 // The display buffer contains the digits to be displayed.
                                      // displayBuf[0] contains the LSD, displayBuf[1] contains the MSD

byte segCode[10][8] = {
// 7 segment code table
//  a  b  c  d  e  f  g  .
  { 1, 1, 1, 1, 1, 1, 0, 0},  // 0
  { 0, 1, 1, 0, 0, 0, 0, 0},  // 1
  { 1, 1, 0, 1, 1, 0, 1, 0},  // 2
  { 1, 1, 1, 1, 0, 0, 1, 0},  // 3
  { 0, 1, 1, 0, 0, 1, 1, 0},  // 4
  { 1, 0, 1, 1, 0, 1, 1, 0},  // 5
  { 1, 0, 1, 1, 1, 1, 1, 0},  // 6
  { 1, 1, 1, 0, 0, 0, 0, 0},  // 7
  { 1, 1, 1, 1, 1, 1, 1, 0},  // 8
  { 1, 1, 1, 1, 0, 1, 1, 0}   // 9
};


void refreshDisplay(int digit1, int digit0)
{
  digitalWrite(displayPins[0], HIGH);  // displays digit 0 (least significant)
  digitalWrite(displayPins[1],LOW );
  setSegments(digit0);
  delay(5);
  digitalWrite(displayPins[0],LOW);    // then displays digit 1
  digitalWrite(displayPins[1], HIGH);
  setSegments(digit1);
  delay(5);
}

void setSegments(int n)
{
  for (int i=0; i < 8; i++)
  {
    digitalWrite(segPins[i], segCode[n][i]);
  }
}

//***************************************************************************
//******************************************************************************
void setup()
{
  for (int i=0; i < 8; i++)
  {
    pinMode(segPins[i], OUTPUT);
  }
  pinMode(displayPins[0], OUTPUT);
  pinMode(displayPins[1], OUTPUT);

  displayBuf[1] = 0;    // initializes the display
  displayBuf[0] = 0;
   }

int i = 0, j = 0;
int startTime = 0;
int endTime;
//******************************************************************************
//******************************************************************************
void loop()
{
    refreshDisplay(displayBuf[1],displayBuf[0]);  // Refreshes the display with the contents of displayBuf
                                                     // each iteration of the main loop.


   endTime = millis();                  // increments the counter approximately once a second
   if ((endTime - startTime) >= 1000)
   {
      if (++i > 9)
      {
        i = 0;
        if (++j > 9) j = 0;
      }
      displayBuf[0] = i;                // send the updated count to the display buffer
      displayBuf[1] = j;
      startTime = endTime;
   }

}
The application stores the digits to be displayed in the array "displayBuf." On each iteration of the main loop, the function "refreshDisplay" updates the seven segment display with the contents of "displayBuf." First, it calls the function "setSegments" to get the seven segment bit pattern for digit D0 (displayBuf[0]) and set the segment pins accordingly. Then it turns on transistor Q0 by setting I/O pin 10 to HIGH. This turns on display D0. After a short delay, it turns off display D0 by setting I/O pin 10 to LOW. It repeats these steps for digit D1 (displayBuf[1]) using I/O pin 11 to turn D1 on and off via Q1. This cycle is repeated so quickly that, due to persistence of vision, the two displays appear to be on at the same time.

Multiplexed display circuit.
Figure 7: Multiplexed display circuit.


LED display driver ICs

chart You can offload the job of driving an LED display to one of a number of ICs designed specifically for the purpose. Two examples are the CD4511 latching Binary Coded Decimal (BCD) to seven segment decoder driver and the MAX7219 Serially Interfaced 8-Digit LED Display Driver.

The MAX7219 has a number of sophisticated features including the ability to drive up to eight LED displays, bar-graph displays, or 64 individual LEDs. It communicates with the host microcontroller through a serial interface.

The circuit in figure 8 uses the much simpler CD4511 to drive a single LED display. The host microcontroller sends a 4 bit BCD digit between 0 and 9 to the CD4511. The CD4511 produces the corresponding seven segment bit pattern (shown in the following table) at its output pins.

Only four microcontroller I/O pins are required to send the data.

Arduino Uno driving a seven segment display via BCD to seven segment decoderFigure 8: Arduino Uno driving a seven segment display via BCD to seven segment decoder


The CD4511 has a latch enable (LE) input that provides the option to store the BCD value on-chip. So, no need to include multiplexing code for a multi-digit display. However, you will need an additional I/O pin for each CD4511 in your output display. This chip does not have an output pin for the decimal point. You can hard wire a fixed decimal point or you can allocate an additional microcontroller I/O pin to connect directly to the seven segment display’s DP pin.

Arduino to BCD to seven segment decoder circuit
Figure 8a: Arduino to BCD to seven segment decoder circuit.


The code in listing 3, below, is the single digit display example (listing 1) modified to drive a single BCD to seven segment display chip.

Listing 3

// One digit BCD to 7 segment LED display demo using CD4511.
// Displays digit 0 - 9 or decimal point

int bcdPins[] = {3, 4, 5, 6};  // {D C B A)
int latchPin = 2;                 // LE (latch enable)

byte bcdCode[10][4] = {
//  D  C  B  A
  { 0, 0, 0, 0},  // 0
  { 0, 0, 0, 1},  // 1
  { 0, 0, 1, 0},  // 2
  { 0, 0, 1, 1},  // 3
  { 0, 1, 0, 0},  // 4
  { 0, 1, 0, 1},  // 5
  { 0, 1, 1, 0},  // 6
  { 0, 1, 1, 1},  // 7
  { 1, 0, 0, 0},  // 8
  { 1, 0, 0, 1}   // 9
};

void displayDigit(int digit)
{
  for (int i=0; i < 4; i++)
  {
    digitalWrite(bcdPins[i], bcdCode[digit][i]);
  }
  digitalWrite(latchPin, HIGH);   // Strobe the 4511 LE input to store bcd value
  delay(10);
  digitalWrite(latchPin, LOW);
}

//***************************************************************************
//******************************************************************************
void setup()
{
  for (int i=0; i < 4; i++)
  {
    pinMode(bcdPins[i], OUTPUT);
  }
  pinMode(latchPin, OUTPUT);
  digitalWrite(latchPin, LOW);   // initialize LE input on 4511 to LOW.
 }

//******************************************************************************
//******************************************************************************
void loop()
{
  for (int n = 0; n < 10; n++)    // display digits 0 - 9
  {
     displayDigit(n);
     delay(1000);
  }

}

For almost two decades, Phil Kane has been a technical writer in the software industry and occasionally authored articles for electronics enthusiast magazines. He has a bachelor's in Electronics Engineering Technology with a minor in Computer Science. Phil has had a life-long interest in science, electronics and space exploration. He enjoys designing and building electronic gadgets, and would very much like to see at least one of those gadgets on its way to the moon or Mars one day.