Seven-Segment Displays

How to use a Four Digit Seven-Segment Display With a chipKITā„¢ Board

Seven-Segment Displays

How to use a Four Digit seven-segment Display With chipKIT™

Introduction

For this project, we will be explaining how to setup a simple multi-digit seven-segment LED display (SSD or 7SD) and then making a simple counter that will display the time after the board is turned on. Seven-segment displays are used in most digital displays to show numerical digits.

Before you begin, you should:
  • Understand how to setup and drive LEDs in a circuit.
After you're done, you should:
  • Be able to display information on a seven-segment display.

Inventory:

Qty Description Typical Image Schematic Symbol Breadboard Image
1 Four Digit seven-segment Display
4 220Ω Resistors

Basic Theory

Figure 1. Seven-segment LED display.

A seven-segment LED display is an array of seven (or sometimes eight) LEDs that has either a common anode or cathode (you can review previous LED projects if you need a refresher on terminology). Characters on the display are shown by illuminating particular LEDs in the array. Figure 2 shows how the digit “2” would be illuminated on a seven-segment display, and then shows the equivalent circuit.

Figure 2. seven-segment LED display with circuit.

The seven-segment display used for this project is a common anode type (meaning the anode of each LED is connected). For organization and for the rest of this project, the cathode pins of each LED segment will be referred to as pins A–G (as in Fig. 2), and the decimal point, DP.

This project will also use a four digit display. Figure 3 shows a circuit diagram of all four digits. You may have noticed that all four digits share the same cathode pin. This means with all four anode pins driven HIGH, and for instance the ”A“ cathode pin is driven LOW, that particular segment would illuminate for all four digits.

Figure 3. Four digit seven-segment display.

While this doesn't really seem useful at first, it is quite common to all seven segment displays. Even with shared pins we are still able to display separate digits, so sharing pins like this allows us to save on the overall pin count of the device (from 36 pins to only 12). The chipKIT board is used to create a precisely timed sequence, which will allow us to display information on each digit separately.

The chipKIT board will drive all cathodes and anodes in sequence. By only driving one anode HIGH at a time with the desired cathodes for the segments you want illuminated driven LOW, we can display a value on only one digit. Now if we cycle between digits slowly (i.e., turn the current anode off, and then turn on the next anode with all of the cathodes needed for the next digit driven LOW), you can see each digit display information separately in a kind of round robin fashion. The rate at which sequences cycle through each digit is the ”refresh rate“. The refresh rate can be increased until you can no longer see the switching and all digits ”appear“ on the display at the same time. This is the same concept behind driving an LED with PWM from previous projects, or television and video displays (i.e., images changing so fast that the brain observes them as a single image).

So for example, to display ”1234“, initially anode 1 is HIGH (while all others are LOW), and cathodes B and C are LOW (with all other cathodes HIGH). This correctly biases segment B and C of digit 1 only. After a short amount of time, anode 1 is set LOW, and anode 2 is set HIGH. All of the cathode pins to display a ”2“ are then set LOW (i.e., A,B,G,E,D), thus displaying a ”2“ in the digit 2 position. Continuing this sequence for digits 3 (driving anode 3 HIGH and cathodes A,B,C,D,G LOW) and then 4 (anode 4 HIGH, and cathodes F,G,B,C LOW). After going through all four digits, the sequence then starts over. Setting the refresh rate is only a matter of setting the delay time before switching to the next digit. For our project we will be using 200 Hz, which displays fine without any flicker.

Step 1: Setting up the circuit:

Figure 4. Four digit seven-segment display circuit.
  1. Place the seven-segment display so that it spans the valley in the breadboard.
  2. With a 220 Ω resistor, connect one end of the resistor to pin 12 of the seven-segment display. Connect the other end of the resistor to pin 9 of the chipKIT board.
  3. Connect a 220 Ω resistor to pin 9 of the seven-segment display, then connect the other end of the resistor to pin 11 of the chipKIT board.
  4. Connect a 220 Ω resistor to pin 8 of the seven-segment display, then connect the other end of the resistor to pin 12 of the chipKIT board.
  5. Connect a 220 Ω resistor to pin 6 of the seven-segment display, then connect the other end of the resistor to pin 13 of the chipKIT board.
  6. Connect seven-segment display pin 11 to chipKIT board pin 5.
  7. Connect seven-segment display pin 10 to chipKIT board pin 4.
  8. Connect seven-segment display pin 7 to chipKIT board pin 3.
  9. Connect seven-segment display pin 5 to chipKIT board pin 33.
  10. Connect seven-segment display pin 4 to chipKIT board pin 32.
  11. Connect seven-segment display pin 3 to chipKIT board pin 31.
  12. Connect seven-segment display pin 2 to chipKIT board pin 30.
  13. Connect seven-segment display pin 1 to chipKIT board pin 29.

You may notice that this circuit uses a lot of wires and pins on the chipKIT board to setup. To save on pin counts, I/O expanders or shift register ICs can be used to communicate with the seven-segment display serially (the chipKIT essentially communicates to the IC in serial, and then the IC communicates to the Segment display in parallel). While slightly out of the scope of this project, such components could be used in future projects.

Figure 5. Four digit seven-segment display schematic.

Seven-segment display schematic.

Step 2: Writing the Software

The following code will display a running count in seconds and minutes on the seven-segment display screen.


// seven-segment elements to chipKIT pins
const unsigned int A = 5; 
const unsigned int F = 4;
const unsigned int G = 33; 
const unsigned int B = 3; 
const unsigned int E = 29; 
const unsigned int D = 30; 
const unsigned int C = 32; 
const unsigned int DP = 31; 

const unsigned int Anode1 = 9;
const unsigned int Anode2 = 11;
const unsigned int Anode3 = 12;
const unsigned int Anode4 = 13;

// seven-segment digit
unsigned int digit = 1;

// Clock count
unsigned int SecondsD1 = 0;
unsigned int SecondsD2 = 0;
unsigned int MinutesD1 = 0;
unsigned int MinutesD2= 0;
unsigned int tick = 0;



void setup() {
 
// Pin Setup
  pinMode(Anode1, OUTPUT);
  pinMode(Anode2, OUTPUT);
  pinMode(Anode3, OUTPUT);
  pinMode(Anode4, OUTPUT);
 
 
  pinMode(A,OUTPUT);
  pinMode(B,OUTPUT);
  pinMode(C,OUTPUT);
  pinMode(D,OUTPUT);
  pinMode(E,OUTPUT);
  pinMode(F,OUTPUT);
  pinMode(G,OUTPUT);
  pinMode(DP,OUTPUT);
  

}

void decodeAndWrite(unsigned int value){
  /*   Initialize all values HIGH in order to not display information by default, and then depending 
  *    on the "value" parameter set the corresponding element
  *    LOW to display a number.
  */
  
  digitalWrite(A,HIGH);
  digitalWrite(B,HIGH);
  digitalWrite(C,HIGH);
  digitalWrite(D,HIGH);
  digitalWrite(E,HIGH);
  digitalWrite(F,HIGH);
  digitalWrite(G,HIGH);
  digitalWrite(DP,HIGH);
  
  // if digit being display is digit 2, add the decimal point
  if (digit == 2){
   digitalWrite(DP,LOW); 
  }
  
  
  switch(value){
    //  Each case corresponds to the digit that is being displayed 
    
    case 0:
    
    digitalWrite(A,LOW);
    digitalWrite(F,LOW);
    digitalWrite(E,LOW);
    digitalWrite(D,LOW);
    digitalWrite(C,LOW);
    digitalWrite(B,LOW);  
    break;
    
    case 1:
   
    digitalWrite(C,LOW);
    digitalWrite(B,LOW);
    break;
    
    case 2:
    
    digitalWrite(A,LOW);
    digitalWrite(G,LOW);
    digitalWrite(E,LOW);
    digitalWrite(D,LOW);
    digitalWrite(B,LOW);
    break;
    
    case 3:
    
    digitalWrite(C,LOW);
    digitalWrite(B,LOW);
    digitalWrite(A,LOW);
    digitalWrite(G,LOW);
    digitalWrite(D,LOW);
    break;
    
    case 4:
    
    digitalWrite(F,LOW);
    digitalWrite(B,LOW);
    digitalWrite(G,LOW);
    digitalWrite(C,LOW);
    break;
    
    case 5:
    
    digitalWrite(A,LOW);
    digitalWrite(F,LOW);
    digitalWrite(G,LOW);
    digitalWrite(C,LOW);
    digitalWrite(D,LOW);
    break;
    
    case 6:
    
    digitalWrite(C,LOW);
    digitalWrite(G,LOW);
    digitalWrite(E,LOW);
    digitalWrite(D,LOW);
    digitalWrite(F,LOW);  
    break;
    
    case 7:
    
    digitalWrite(A,LOW);
    digitalWrite(B,LOW);
    digitalWrite(C,LOW);
    break;
    
    case 8:
    
    digitalWrite(A,LOW);
    digitalWrite(F,LOW);
    digitalWrite(B,LOW);
    digitalWrite(G,LOW);
    digitalWrite(C,LOW);
    digitalWrite(D,LOW);
    digitalWrite(E,LOW);  
    break;
    
    case 9:
    
    digitalWrite(A,LOW);
    digitalWrite(F,LOW);
    digitalWrite(B,LOW);
    digitalWrite(G,LOW);
    digitalWrite(C,LOW);
    break;
    
    default:
    // do not display information for the default case
    break;
    
  }
 
  
}


void loop() {
  
  
 /*  Switch between which anode is driven HIGH in a 
  *  round robin fashion. Digit 1 is the furthest left of the seven-segment display.
  *
  *  This will drive each digit according to the clock counting variables.
  *  MinutesD2 will always display on digit 1
  *  MinutesD1 : digit 2
  *  SecondsD2 : digit 3
  *  SecondsD1 : digit 4
*/
  
  switch(digit){
  
  case 1:
  
  digitalWrite(Anode1,HIGH);
  digitalWrite(Anode2,LOW);
  digitalWrite(Anode3,LOW);
  digitalWrite(Anode4,LOW);
  decodeAndWrite(MinutesD2);
  break;
  
  case 2:
  
  digitalWrite(Anode1,LOW);
  digitalWrite(Anode2,HIGH);
  digitalWrite(Anode3,LOW);
  digitalWrite(Anode4,LOW);
  decodeAndWrite(MinutesD1);
  break;
  
  case 3:
  
  digitalWrite(Anode1,LOW);
  digitalWrite(Anode2,LOW);
  digitalWrite(Anode3,HIGH);
  digitalWrite(Anode4,LOW);
  decodeAndWrite(SecondsD2);
  break;
    
  case 4:
  
  digitalWrite(Anode1,LOW);
  digitalWrite(Anode2,LOW);
  digitalWrite(Anode3,LOW);
  digitalWrite(Anode4,HIGH);
  decodeAndWrite(SecondsD1);
  break;
  
  default:
  //default off
  digitalWrite(Anode1,LOW);
  digitalWrite(Anode2,LOW);
  digitalWrite(Anode3,LOW);
  digitalWrite(Anode4,LOW);
  break;
  
  
  }
  
  
  
  // Cycle through the digits, 
  digit++;
  if (digit == 5){
    digit = 1;
   
  }
  
  // Increment the clock tick count
  tick++;
  
  
  // main loop will run at 200 Hz
  // so SecondsD1 will increment every 200 ticks
  if (tick == 200){
    SecondsD1++;
    tick = 0;
  }
  // roll over to the second seconds digit
  if (SecondsD1 == 10){
    SecondsD1 = 0;
    SecondsD2++;
  }
  // roll over to the first minutes digit
    if (SecondsD2 == 6){
    SecondsD2 = 0;
    MinutesD1++;
  }
  // roll over to the second minutes digit
    if (MinutesD1 == 10){
    MinutesD1 = 0;
    MinutesD2++;
  }
    if (MinutesD2 == 6){
    MinutesD2 = 0;
    
  }
  
  
 
 delay(5); 
}

                

Once loaded, the count will begin right away.

Test Your Knowledge!

Now that you've completed this project, you should be able to:

  • Modify the circuit and code to create a stop watch. Add buttons to start the count, stop the count, and reset the value displayed on the seven-segment.
  • Display information other than a simple count (i.e., internal states of your chipKIT project, or sensor information).

You could also extend this project in various ways:

  • For this project you communicated with the seven-segment display by parallel (using 12 lines in general). You could reduce the overall wires needed for the seven-segment display by utilizing a shift register or I/O expander to convert the parallel signals into a serial communication.
  • Increase the brightness of the seven-segment display. With only one anode being driven at a time, it creates a 25% duty cycle for each digit (this is like using PWM signal to activate a LED, and only using 25% of the voltage you would normal use for an LED). Using parts from the chipKIT Starter Kit or the Analog Parts Kit (possibly the Schmitt trigger or NMOS transistors), create a level shifting circuit (i.e., a circuit that would convert the 3.3V signal being sent from the digital pin of the chipKIT board to the anode of the seven-segment display) to a 5V signal.

  • Other product and company names mentioned herein are trademarks or trade names of their respective companies. © 2014 Digilent Inc. All rights reserved.
  • Circuit and breadboard images were created using Fritzing.