# Seven-Segment Displays

## 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

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.

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.

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:

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.

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.