How do I implement two separate 7-segment displays with shift registers?

Hi All,

I've got a project where I have two separate pushbuttons, and a corresponding 7-segment display for each. When the user pushes the left button, a counter will cycle through 0, 1, and 2. Same for the right button. I've seen tutorials online on daisy chaining 74HC595 shift registers so that a person can make a double (or more) digit display, and save arduino pins in the process.

I'd also like to save pins, but I won't be outputting a double digit number. So i'm not sure how to implement the displays along with the 74HC595 shift registers. Any help would be much appreciated!

I'm thinking that I would not be able to do the daisy chaining, and just use 3 pins. I might have to wire each 7-segment display to its own shift register, then each shift register would connect to the arduino via 3 pins. So i'd use 6 pins in total. But i'm not sure if this is how its done.

exwhyzed: I'd also like to save pins, but I won't be outputting a double digit number.

You could decide that you always output a double digit number: 10 * v1 + v2. (Assuming that v1 and v2 are the counters for the 2 buttons.)

Hi Jobi-Wan,

That's a unique idea. But what i don't get is how do I say "stay the same" in Arduino-language? So if the user presses the left pushbutton, the left 7-segment counter will go up one, but the right counter and display will stay the same.

I think i will have to do some bitwise operations. I'm going to try this out and post what i've come up with, if (and when!) i run into a problem. Thanks!

exwhyzed: how do I say "stay the same" in Arduino-language? So if the user presses the left pushbutton, the left 7-segment counter will go up one, but the right counter and display will stay the same.

If you don't tell it to change, it stays the same.

But if one of the values change, you have to update the entire display (both digits). By chaining 2 74HC595's together, you now have a 16bit shift register, so you have to shift all 16 bits.

Something along these lines:

byte v1 = 0,v2 = 0;

void loop()
{
  if (button 1 went up)
    v1++; // and v2 stays the same
  if (button 2 went up)
    v2++; // and v1 stays the same

  digitalWrite(LATCH,LOW);
  shiftOut(DATA,CLOCK,digitToSegments(v1));
  shiftOut(DATA,CLOCK,digitToSegments(v2));
  digitalWrite(LATCH,HIGH);
}

I Assume you already have a way to encode a number into a segments-bitmap. (i.e. 0 = B0111111 1 = B0000110, 2 = B1011011, 3 = B1001111 etc...)

Hi Exwhyzed and Jobi-Wan (and anyone else out there),

Came across this old post while looking for a solution to my problem. I have a simple two-player scoreboard project that involves a mega, two Seg-o-matic 7 segment displays from Curious Electric Company.co.uk and two up/down buttons for the players to display their scores from 0-9. I want to adapt the following code to allow a second player.

The attached code worked well without any modifications for one player; the 7 segment led was nice and bright, no flickering and all segmentswere same brightness, also, no delays in increasing score etc.

I thought this would be straight forward since I just needed this code times two. I duplicated the code calling player one code latchPinA and player two code latchPinB for instance. Following this throughout the code, it did work but unfortunately, the segments on both were half as bright with exception of segments A and B who were bright. I have no idea why it doesn’t work.

Long story short, I have no idea how to adapt this code to allow two players without any loss in brightness etc. Since you guys seem to have experienced a similar issue, perhaps you could give me some advice?

Any help you can offer would be great.

JMB1971

//  7-Segment LED counter, multiplexing using 74HC595 8-bit shift register, increment counter zero to nine to zero via push button switch
  // 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/
  //  http://nootropicdesign.com/projectlab/2009/10/25/led-clock/
  
  const int latchPin = A10;  // Pin connected to Pin 12 of 74HC595 (Latch)
  const int dataPin  = A11;  // Pin connected to Pin 14 of 74HC595 (Data)
  const int clockPin = A12;  // Pin connected to Pin 11 of 74HC595 (Clock)
  
  int upPin = 14;      // pushbutton attached to pin 12
  int downPin = 15;      // 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
  
  {
    B00111111,
    B00000110,
    B01011011,
    B01001111,
    B01100110,
    B01101101,
    B01111100,
    B00000111,
    B01111111,
    B01100111,
  };
  
  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 > 9)
      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 & (~10000000 >> 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
  }