CIRCUIT NAV

7 Segment LED circuits

Here are five different methods of connecting 7 segment LED displays to an Arduino or Atmega 328 that I would like to show you. They are only simple counter codes that are incremented / decremented via a pair of push button switches or a potentiometer. I have used 220 ohm resistors in most of these circuits but you would be advised to calculate the correct ones required for the particular 7 segment displays that you are using. This will ensure that you do not damage the IO pins of the 328 IC.
The constraints to these maximum currents courtesy of Terry King & Crossroads of Arduino forum are

The IO pins have an absolute maximum rating of 40 mA per pin.The following groups of pins should not have more than 100 mA drawn from them
◀ Digital pins 0 to 4
◀ Digital pins 5 to 1
◀ Analog pins A0 to A5
In addition to that, the entire processor chip has a maximum rating of 200 mA current consumption In the following five methods explained, the
7 segment displays are common cathode and the shift registers used in circuits 3 and 4 are 74HC595's. Circuit 5 uses the MAX7219 constant current LED driver Arduino code formatting script, courtesy of Jason Knight / Deathshadow

7 Segment LED Pin and Segment pin out common cathode


7seg_pinouts1

1 - Directly from Arduino / Atmega 328 / Pushbutton counter

Push buttons increment and decrement a counter between zero and eight

7-seg-direct ◀click schematic to expand

 
  // Thanks to Grumpy Mike  [url]http://www.thebox.myzen.co.uk/Tutorial/Arrays.html[/url]
  // LED Segment allocation within byte = {DP ABCDEFG }
  
  byte upPin = 12;                              // pushbutton attached to pin 12
  byte downPin = 13;                            // pushbutton attached to pin 13
  byte currUpState = 1;                         // initialise currUpState as HIGH
  byte currDownState = 1;                       // initialise currDownState as HIGH
  byte prevUpState = 0;
  byte prevDownState = 0;
  byte pins [] = {2, 3, 4, 5, 6, 7, 8, 9 };     // pin 9 allocated to DP but not used (first element of binary array in char tenCode)
  int counter = 0;                             // initialise counter as zero
  byte timer = 1000;                            // delay timer interval
  int i[10] =  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
  char tenCode[] = {B01111110, B00110000, B01101101, B01111001, B00110011, B01011011, B01011111, B01110000, B01111111, B01111011 };
  void setup()
  {
    for(byte i = 0; i < 8; i++)                  // set digital pins as OUTPUTS
      pinMode(pins[i], OUTPUT);
  }

  void loop()
  {
      currUpState = digitalRead(upPin);
      if (prevUpState != currUpState)           // has the state changed from
      {                                         // HIGH to LOW or vice versa
        prevUpState = currUpState;
        if (currUpState == HIGH)                // If the button was pressed
          counter++;                            // increment the counter by one
    
      }
      if(counter > 8)
        counter--;
      displayEleven(i[counter]);
    
      currDownState = digitalRead(downPin);
      if (prevDownState != currDownState)       // has the state changed from
      {                                         // HIGH to LOW or vice versa
        prevDownState = currDownState;
        if (currDownState == HIGH)              // If the button was pressed
          counter--;                           // decrement the counter by one
      }
      if(counter < 0)
        counter++;
      displayEleven(i[counter]);
    }
    
  void displayEleven(byte num)
  {
    byte mask = 1;
    for(byte i = 0; i < 8; i++)
    {
      if((mask & tenCode[num]) == 0)
        digitalWrite(pins[i], LOW);
      else digitalWrite(pins[i], HIGH);
      mask = mask << 1;
    }
  }
  
  

2 - Directly from Arduino / Atmega 328 with direct port manipulation / Pushbutton counter

Push buttons increment and decrement a counter between zero and eight

7-seg-dpm ◀click schematic to expand

 

  // Because Direct Port Manipulation uses pins 0 and 1, which are the RX and TX
  // pins respectively, you have to disconnect these pins when uploading the code
  // LED Segment allocation within byte = {DP ABCDEFG }

  int upPin = 12;                                  // pushbutton attached to pin 12
  int downPin = 13;                                // pushbutton attached to pin 13
  int currUpState = 1;                             // initialise currUpState as HIGH
  int currDownState = 1;                           // initialise currDownState as HIGH
  int prevUpState = 0;
  int prevDownState = 0;
  int counter = 0;
  byte i = 0;
  byte J = 0;
  int digit[10] = {B01111110, B00110000, B01101101, B01111001, B00110011, B01011011, B01011111, B01110000, B01111111, B01111011 };
  int j[10] =  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

  void setup()
  {
    DDRD = B11111111;                              // set PORTD (digital 7~0) to outputs
  }
  void show(byte j)
  {
    for(i = 0; i < 10; i++)   
    {
      PORTD = digit[j];
     }
  }

  void loop()
  {
    {
      currUpState = digitalRead(upPin);
      if (prevUpState != currUpState)             // has the state changed from
      {                                           // HIGH to LOW or vice versa
        prevUpState = currUpState;
        if (currUpState == HIGH)                  // If the button was pressed
          counter++;                              // increment the counter by one
    
      }
      if(counter > 8)
        counter--;
      show(j[counter]);
    
      currDownState = digitalRead(downPin);
      if (prevDownState != currDownState)         // has the state changed from
      {                                           // HIGH to LOW or vice versa
        prevDownState = currDownState;
        if (currDownState == HIGH)                // If the button was pressed
          counter--;                             // decrement the counter by one
      }
      if(counter < 0)
        counter++;
      show(j[counter]);
    }
  }

3 - Multiplexed via shift register from Arduino / Atmega 328 / Pushbutton counter

Push buttons increment and decrement a counter between zero and eight. Uncomment delay on the last line to see multiplexing in action.

7-seg-pushbutton ◀click schematic to expand

 

//  7-Segment LED counter, multiplexing using 74HC595 8-bit shift register, increment counter zero to eight
//  to zero via push button switches
//  Code mangled together from these sources, thanks fellas
//  [url]http://thecustomgeek.com/2011/06/29/multiplexing-for-a-7-year-old/[/url]
//  [url]http://nootropicdesign.com/projectlab/2009/10/25/led-clock/[/url]
//  original tutorial link for 7Seg display functions at 
//  [url]http://www.sweeting.org/mark/blog/2011/11/27/arduino-74hc595-shift-register-and-a-7-segment-led-display[/url]

const int latchPin = 5;  // Pin connected to Pin 12 of 74HC595 (Latch)
const int dataPin  = 6;  // Pin connected to Pin 14 of 74HC595 (Data)
const int clockPin = 7;  // Pin connected to Pin 11 of 74HC595 (Clock)
int upPin = 12;      // pushbutton attached to pin 12
int downPin = 13;      // pushbutton attached to pin 13
int currUpState = 1;   // initialise currUpState as HIGH
int currDownState = 1;   // initialise currDownState as HIGH
int prevUpState = 0;
int prevDownState = 0;
int counter = 0;          // initialise counter as zero
int numbers[10] =  // Describe each digit in terms of display segments  0, 1, 2, 3, 4, 5, 6, 7, 8, 9
  {
    B11111100,
    B01100000,
    B11011010,
    B11110010,
    B01100110,
    B10110110,
    B10111110,
    B11100000,
    B11111110,
    B11100110,
  };
  
void setup()
  {
    pinMode(latchPin, OUTPUT);   // set SR pins to output
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, OUTPUT);
    pinMode(upPin, INPUT);   // sets pin 12 as pushbutton INPUT
    pinMode(downPin, INPUT);   // sets pin 13 as pushbutton INPUT
  }
  
 void loop()
  {
    currUpState = digitalRead(upPin);
    if (prevUpState != currUpState)             // has the state changed from
    {                                           // HIGH to LOW or vice versa
      prevUpState = currUpState;
      if (currUpState == HIGH)                  // If the button was pressed
        counter++;          // increment the counter by one
  
    }
    if(counter > 8)
      counter--;
    show(numbers[counter]); // display the current digit
    currDownState = digitalRead(downPin);
    if (prevDownState != currDownState)         // has the state changed from
    {                                           // HIGH to LOW or vice versa
      prevDownState = currDownState;
      if (currDownState == HIGH)                // If the button was pressed
        counter--;                             // decrement the counter by one
  
    }
    if(counter < 0)
      counter++;
    show(numbers[counter]); // display the current digit
  }
  
  void show( byte number)
   {
    // Use a loop and a bitwise AND to move over each bit that makes up
    // the seven segment display (from left to right, A => G), and check
    // to see if it should be on or not
    for(int j = 0; j <= 7; j++)
     {
      byte toWrite = number & (B10000000 >> j);
      if(!toWrite) {
        continue;
       }                 // If all bits are 0 then no point writing it to the shift register,so break out and
       //move on to next segment.
       shiftIt(toWrite); // Otherwise shift it into the register
     }
   }

 void shiftIt (byte data)
 {
   digitalWrite(latchPin, LOW);                  // Set latchPin LOW while clocking these 8 bits in to the register
   shiftOut(dataPin, clockPin, LSBFIRST, data);
   digitalWrite(latchPin, HIGH);                //set latchPin to high to lock and send data

  // put delay here if you want to see the multiplexing in action!
  //  delay(10);
 }




4 - Multiplexed via shift register from Arduino / Atmega 328 / Potentiometer counter

Potentiometer used to increment and decrement a counter between zero and eight. Uncomment delay on the last line to see multiplexing in
action.

7-seg-potentiometer ◀click schematic to expand

 

//  7-Segment LED counter, multiplexing using 74HC595 8-bit shift register, increment counter zero to eight 
//  to zero via potentiometer
//  Code mangled together from these sources - thanks fellas
//  [url]http://thecustomgeek.com/2011/06/29/multiplexing-for-a-7-year-old/[/url]
//  [url]http://nootropicdesign.com/projectlab/2009/10/25/led-clock/[/url]
//  original tutorial link for 7Seg display functions at 
//  [url]http://www.sweeting.org/mark/blog/2011/11/27/arduino-74hc595-shift-register-and-a-7-segment-led-display[/url]


const int latchPin = 5;  // Pin connected to Pin 12 of 74HC595 (Latch)
const int dataPin  = 6;  // Pin connected to Pin 14 of 74HC595 (Data)
const int clockPin = 7;  // Pin connected to Pin 11 of 74HC595 (Clock)
int counter = 0;          // initialise counter as zero
int potReading = 0;
int numbers[10] =  // Describe each digit in terms of display segments  0, 1, 2, 3, 4, 5, 6, 7, 8, 9
{
  B11111100,
  B01100000,
  B11011010,
  B11110010,
  B01100110,
  B10110110,
  B10111110,
  B11100000,
  B11111110,
  B11100110,
};

void setup()
{
  pinMode(latchPin, OUTPUT);   // set SR pins to output
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void loop()
{
  potReading = analogRead (A0);
  potReading = map(potReading, 0, 1023, 0, 9);
  {
    if(potReading > 9)
      potReading --;
    show(numbers[potReading]);
  }
  {
    if(potReading < 0)
      potReading ++;
    show(numbers[potReading]);
  }
}

void show( byte number)
{
  // Use a loop and a bitwise AND to move over each bit that makes up
  // the seven segment display (from left to right, A => G), and check
  // to see if it should be on or not
  for(int j = 0; j <= 7; j++)
  {
    byte toWrite = number & (B10000000 >> j);
    if(!toWrite) {
      continue;
    }  // If all bits are 0 then no point writing it to the shift register,so break out and move on to next segment.
    shiftIt(toWrite); // Otherwise shift it into the register
  }
}

void shiftIt (byte data)
    {
      digitalWrite(latchPin, LOW);                  // Set latchPin LOW while clocking these 8 bits in to the register
      shiftOut(dataPin, clockPin, LSBFIRST, data);
      digitalWrite(latchPin, HIGH);                 // set latchPin to high to lock and send data
    
      // put delay here if you want to see the multiplexing in action!
      //  delay(10);
    }

5 - Multiplexed via MAX7219 from Arduino / Atmega 328 / Pushbutton counter

Push buttons increment and decrement a counter between zero and eight

7-seg-max7219 ◀click schematic to expand

 

  // Code mangled together from these sources, thanks fellas
  // [url]http://playground.arduino.cc/Main/LedControlDemos#SevenSegmentDemo[/url]
  // [url]http://playground.arduino.cc/Main/MAX72XXHardware#Wiring7Segment[/url]
  // [url]http://tronixstuff.com/2013/10/11/tutorial-arduino-max7219-led-display-driver-ic/[/url]
  
  #include "LedControl.h"
  // pin 12 is connected to the DataIn 
  // pin 11 is connected to the CLK 
  // pin 10 is connected to LOAD 
  
  LedControl lc=LedControl(12,11,10,1);
  int timer = 1000;
  int upPin = 2;           // pushbutton attached to pin 2
  int downPin = 3;         // pushbutton attached to pin 3
  int currUpState = 1;     // initialise currUpState as HIGH
  int currDownState = 1;   // initialise currDownState as HIGH
  int prevUpState = 0;
  int prevDownState = 0;
  int counter = 0;
  int i[10] =  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
  
  void setup() 
  {
    lc.shutdown(0,false);
    lc.setIntensity(0,8);
    lc.clearDisplay(0);
  }
  
  /* true will turn on DP /  false will turn it off
   * lc.setDigit(A, B, C, D); WHERE
   A = 0 - 7: number of MAX7219's
   B = 0 - 7: number of 7Seg displays
   C = 0 - 9: digit to display on 7Seg
   D = true / false, DP on / DP off
   */
  
  void loop() 
  {
    currUpState = digitalRead(upPin);
    if (prevUpState != currUpState)             // has the state changed from
    {                                           // HIGH to LOW or vice versa
      prevUpState = currUpState;
      if (currUpState == HIGH)                  // If the button was pressed
        counter++;                              // increment the counter by one
  
    }
    if(counter > 8)
      counter--;
    lightSegments(i[counter]);
  
    currDownState = digitalRead(downPin);
    if (prevDownState != currDownState)         // has the state changed from
    {                                           // HIGH to LOW or vice versa
      prevDownState = currDownState;
      if (currDownState == HIGH)                // If the button was pressed
        counter--;                             // decrement the counter by one
    }
    if(counter < 0)
      counter++;
    lightSegments(i[counter]);
  }
  
   void lightSegments(byte i) 
  {
    lc.setDigit(0,0,i,false);
  }


6 - Multiplexed via shift register from Arduino / Pushbutton counter / Potentiometer delay

Push buttons increment and decrement a counter between zero and eight. A potentiomer is used to control a delay at the end of the
shiftIt function to allow the multiplexing that is displaying the selected digit to be seen
YouTube video

7-seg-potentiometer ◀click schematic to expand

 

  //  7-Segment LED counter, multiplexing using 74HC595 8-bit shift register, increment counter zero to eight
  //  to zero via push button switches. Potentiometer connected to A0 varies the  delay in function shiftIt   
  //  Code mangled together from these sources - thanks fellas
  //  [url]http://thecustomgeek.com/2011/06/29/multiplexing-for-a-7-year-old/[/url]
  //  [url]http://nootropicdesign.com/projectlab/2009/10/25/led-clock/[/url]
  //  original tutorial link for 7Seg display functions at 
  //  [url]http://www.sweeting.org/mark/blog/2011/11/27/arduino-74hc595-shift-register-and-a-7-segment-led-display[/url]


  
  byte latchPin = 5;                             // Pin connected to Pin 12 of 74HC595 (Latch)
  byte dataPin  = 6;                             // Pin connected to Pin 14 of 74HC595 (Data)
  byte clockPin = 7;                             // Pin connected to Pin 11 of 74HC595 (Clock)
  byte upPin = 12;                               // pushbutton attached to pin 12
  byte downPin = 13;                             // pushbutton attached to pin 13
  byte currUpState = 1;                          // initialise currUpState as HIGH
  byte currDownState = 1;                        // initialise currDownState as HIGH
  byte prevUpState = 0;
  byte prevDownState = 0;
  int counter = 0;                              // initialise counter as zero
  int potReading = 0;
  int numbers[10] =                              // Describe each digit in terms of display segments  0, 1, 2, 3, 4, 5, 6, 7, 8, 9
  {
    B11111100,  // Displays 0
    B01100000,  // Displays 1
    B11011010,  // Displays 2
    B11110010,  // Displays 3
    B01100110,  // Displays 4
    B10110110,  // Displays 5
    B10111110,  // Displays 6
    B11100000,  // Displays 7
    B11111110,  // Displays 8
    B11100110,  // Displays 9 (currently not used)
  };

  void setup()
  {
   //Serial.begin(9600);
    pinMode(latchPin, OUTPUT);                   // set SR pins to output
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, OUTPUT);
    pinMode(upPin, INPUT);                       // sets pin 12 as pushbutton INPUT
    pinMode(downPin, INPUT);                     // sets pin 13 as pushbutton INPUT
  }

  void loop()
  {
    currUpState = digitalRead(upPin);
    if (prevUpState != currUpState)             // has the state changed from
    {                                           // HIGH to LOW or vice versa
      prevUpState = currUpState;
      if (currUpState == HIGH)                  // If the button was pressed
        counter++;                              // increment the counter by one
  
    }
    if(counter > 8)
      counter--;
    show(numbers[counter]);                     // display the current digit
    currDownState = digitalRead(downPin);
    if (prevDownState != currDownState)         // has the state changed from
    {                                           // HIGH to LOW or vice versa
      prevDownState = currDownState;
      if (currDownState == HIGH)                // If the button was pressed
        counter--;                             // decrement the counter by one
  
    }
    if(counter < 0)
      counter++;
     
      
    show(numbers[counter]);                           // display the current digit
  }

  void show( byte number)
  {
    // Use a loop and a bitwise AND to move over each bit that makes up
    // the seven segment display (from left to right, A => G), and check
    // to see if it should be on or not
    for(byte j = 0; j <= 7; j++)
    {
      byte toWrite = number & (B10000000 >> j);
      if(!toWrite) {
        continue;
      }                                  // If all bits are 0 then no point writing it to the shift register,so break out and
                                         // move on to next segment.
      shiftIt(toWrite);                  // Otherwise shift it into the register
    }
  }

void shiftIt (byte data)
 {
    digitalWrite(latchPin, LOW);                 // Set latchPin LOW while clocking these 8 bits in to the register
    shiftOut(dataPin, clockPin, LSBFIRST, data);
    digitalWrite(latchPin, HIGH);                // set latchPin to high to lock and send data
    { 
      potReading = analogRead (A0);              // delay adjusted via potentiometer to allow multiplexing to be seen
      {
        potReading = map(potReading, 0, 1023, 1, 100);
        {
          if(potReading > 1)
          delay(potReading);
        }
        {
          if(potReading < 100)
          delay(potReading);
          //Serial.println(potReading);
        }
      }
    }
  }