Different methods of driving 7 Segment LED displays with Arduino

8_LED_Array 001

LCDBitmap_via_SR

 I have since hosted an improved version of this, my first foray into some simple web ‘design’, into my own site and this tutorial is now located at http://www.pedrosdigitalsolutions.com/7SegLEDcircuits.php

 I would just like to show a few different methods of connecting 7 segment LED displays to an Arduino or Atmega 328 IC. They are only simple counter codes either automatically counting via the code or incremented / decremented via a pair of push button switches or a potentiometer . I have used 220 ohm resistors in all these circuits but you would be advised to calculate the correct ones required for the particular 7 segment displays that your 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

http://www.gammon.com.au/forum/?id=11473

are –

– The IO pins have an absolute maximum rating of 40 mA per pin.

– Also 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. The 7 segment displays are common cathode and the shift register is a 74HC595.

 

  1. Directly from Arduino / Atmega 328
  2. Via shift register from Arduino / Atmega 328
  3. Directly from Arduino / Atmega 328 with direct port manipulation
  4. Multiplexed via shift register from Arduino / Atmega 328 / Pushbutton counter
  5. Multiplexed via shift register from Arduino / Atmega 328 / Potentiometer counter

7 Segment LED Pin and Segment pin out common cathode

7seg_pinouts

1 – Directly from Arduino / Atmega 328

Counts automatically from zero to nine and then repeats

7 Seg Direct

Code

// Thanks to Grumpy Mike  http://www.thebox.myzen.co.uk/Tutorial/Arrays.html

// LED Segment allocation within byte = {DP ABCDEFG }

int 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 digit[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

int counter = 0;                              // initialise counter as zero

int timer = 1000;                             // delay timer interval

char tenCode[] = {B01111110, B00110000, B01101101, B01111001, B00110011, B01011011, B01011111, B01110000, B01111111, B01111011 };

void setup()

{

for(int i = 0; i < 8; i++)                  // set digital pins as OUTPUTS

pinMode(pins[i], OUTPUT);

}

void loop()

{

for(int j = 0; j < 10; j++)

{

displayEleven(digit[j]);

delay(timer);

}

}

void displayEleven(int num)

{

int mask = 1;

for(int i = 0; i < 8; i++)

{

if((mask & tenCode[num]) == 0)

digitalWrite(pins[i], LOW);

else digitalWrite(pins[i], HIGH);

mask = mask << 1;

}

}

2 – Via shift register from Arduino / Atmega 328

Counts automatically from zero to nine and then repeats

7 Seg SR

Code

// LED Segment allocation within byte = {ABCDEFG DP}

int latchPin = 8;    // connect to pin 12 on the shift register

int dataPin  = 11;   // connect to pin 14 on the shift register

int clockPin = 12;   // connect to pin 11 on the shift register

int i = 0;

byte digit[] = {B11111100,B01100000,B11011010,B11110010,B01100110,B10110110,B10111110,

B11100000,B11111110,B11110110};

void setup()

{

pinMode(dataPin, OUTPUT);       // Configure dataPin  as OUTPUT

pinMode(latchPin, OUTPUT);      // Configure latchPin as OUTPUT

pinMode(clockPin, OUTPUT);      // Configure clockPin as OUTPUT

}

void loop()

{

for (i = 0; i < 10; i++)

{

digitalWrite(latchPin, LOW);                                           // Pull latch LOW to start sending data

shiftOut(dataPin, clockPin, LSBFIRST,digit[i]);         // Send the data

digitalWrite(latchPin, HIGH);                                        // Pull latch HIGH to stop sending data

delay(1000);

}

}

3 – Directly from Arduino / Atmega 328 with direct port manipulation

Counts automatically from zero to nine and then repeats

7 Seg DPM

Code

// 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 }

byte i = 0;

byte digit[10] = {B01111110, B00110000, B01101101, B01111001, B00110011, B01011011, B01011111, B01110000, B01111111, B01111011 };

void setup()

{

DDRD = B11111111; // set PORTD (digital 7~0) to outputs

}

void count()

{

for(i = 0; i <10; i++)

{

PORTD = digit[i];

delay(1000);

PORTD = 0;

}

}

void loop()

{

count();

}

4 – Multiplexed Via shift register from Arduino / Atmega 328 / Pushbutton counter

Push buttons increment and decrement a counter between zero and eight

7 Seg SR Pushbutton

Code

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

//  http://www.sweeting.org/mark/blog/2011/11/27/arduino-74hc595-shift-register-and-a-7-segment-led-display

//  http://thecustomgeek.com/2011/06/29/multiplexing-for-a-7-year-old/

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 12

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

const byte 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

//delay(1);

}

if(counter > 8)

counter-=1;

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-=1;                              // decrement the counter by one

//delay(1);

}

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

for (int k=0; k <= 7; k++)

{

digitalWrite(clockPin, LOW); // clockPin LOW prior to sending a bit

if ( data & (1 << k) )

{

digitalWrite(dataPin, HIGH); // turn “On”

}

else

{

digitalWrite(dataPin, LOW); // turn “Off”

}

digitalWrite(clockPin, HIGH); // and clock the bit in

}

digitalWrite(clockPin, LOW);  //stop shifting out data

digitalWrite(latchPin, HIGH); //set latchPin to high to lock and send data

}

5 – Multiplexed via shift register from Arduino / Atmega 328 / Potentiometer counter

    Potentiometer used to increment and decrement a counter between zero and eight

7 Seg SR Potentiometewr

Code

//  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
//  http://www.sweeting.org/mark/blog/2011/11/27/arduino-74hc595-shift-register-and-a-7-segment-led-display
//  http://thecustomgeek.com/2011/06/29/multiplexing-for-a-7-year-old/

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;

const byte 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, 8);
{
if(potReading > 8)
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

for (int k=0; k <= 7; k++)
{
digitalWrite(clockPin, LOW); // clockPin LOW prior to sending a bit

// Note that in our case, we need to set pinState to 0 (LOW) for
// “On” as the 74HC595 is sinking current when using a common
// anode display. If you want to use a common cathode display then
// switch this around.
if ( data & (1 << k) )
{
digitalWrite(dataPin, HIGH); // turn “On”
}
else
{
digitalWrite(dataPin, LOW); // turn “Off”
}
digitalWrite(clockPin, HIGH); // and clock the bit in
}
digitalWrite(clockPin, LOW);  //stop shifting out data
digitalWrite(latchPin, HIGH); //set latchPin to high to lock and send data
}

3 Comments

  1. Nice tutorial. Thanks for sharing.

  2. There is a better version of this article available at http://www.pedrosdigitalsolutions.com/7SegLEDcircuits.php

Leave a reply to Allison Cancel reply