Sunday, 20 November 2011

Multiple Shift Registers and Lots of Seven Segment LEDS!!

So, after the success of the last part where We managed to get a shift register to control a seven segment LED display I decided to connect up four shift registers and four Seven Segment LED displays.  The jumble of wires is horrible but it does prove that all the displays and shift registers are working.  It is definitely time to consider designing a PCB or putting this design on strip board so that I can concentrate on something other than wiring issues!

The circuit I am using is exactly the same as in the previous post.  I have connected each shift register in turn and the data, latch and clock pins are connected together.  This makes all the displays count up in the same way at the same time!

If anyone else is doing this Kudos!!  Check out the video:


What we need to do now is get this circuit controlled in such a way so that we can use it as a clock or timer.  As I mentioned in the video we could turn this into an Alarm clock or a stopwatch.  The scope for timing in the real world is vast.  Everyone is concerned with time!

In order to do this we need to make some changes to the circuit.  I have connected the data, clock and latch inputs from the arduino to each shift register.  We need to disconnect the data lines from each shift register and then reconnected them as below:

pin 14 of  the 1st 74HC595 goes to pin 11 of the arduino

pin 9 of the 1st 74HC595 goes to pin 14 of the 2nd 74HC595

pin 9 of the 2nd 74HC595 goes to pin 14 of the 3rd 74HC595

pin 9 of the 3rd 74HC595 goes to pin 14 of the 4th 74HC595

Once we have made these connections we then need to update our sketch so that the unit counts up or down.  Lets do count up from zero first.  This sketch needs to control the shift registers and seven segment displays carefully.  We want to be able to distinguish between minutes and seconds and we want the clock to be able to count up to a some maximum value and then reset.  Lets set our clock to be a One hour timer.

Here is the Sketch:



/*
 Langster's Code for driving 4x seven segment displays via 4x Shift Registers
 This sketch will make a One Hour Counter!  After an hour has passed the count 
 will reset


 Repeat these steps four times for the different shift registers

 Connect Pin 3 and pin 10 on the seven segment display to 0V
 Connect all the other pins to the Shift Register digital ouputs 
 as listed below:

 pin 1 of 74HC595 to Seven Segment LED pin 6  
 pin 2 of 74HC595 to Seven Segment LED pin 4
 pin 3 of 74HC595 to Seven Segment LED pin 2
 pin 4 of 74HC595 to Seven Segment LED pin 1
 pin 5 of 74HC595 to Seven Segment LED pin 9
 pin 6 of 74HC595 to Seven Segment LED pin 8
 pin 7 of 74HC595 to Seven Segment LED pin 5
 pin 8 of 74HC595 to 0V

 pin 9 of 74HC595 is of shift register One is connected to pin 14 of 
 shift register Two...etc

 pin 10 of 74HC595 to +5V
 pin 11 of 74HC595 to Arduino pin 12  
 pin 12 of 74HC595 to Arduino pin 13
 pin 13 of 74HC595 is connected to 0V - 0V is better!
 pin 14 of 74HC595 to Arduino pin 11 for first shift register
 pin 15 of 74HC595 to Seven Segment LED pin 7
 pin 16 of 74HC595 to +5V


*/


int secondsUnits = 0; // count the seconds units


int secondsTens = 0; // count the seconds tens


int minutesUnits = 0; // count the minutes units 


int minutesTens = 0; // count the minutes tens
  
int unitCount=0; // count the units


// Pin connected to ST_CP (pin 12) of 74HC595
int latchPin = 13;


// Pin connected to SH_CP (pin 11 of 74HC595
int clockPin = 12;


// Pin connected to DS (pin 14) of 74HC595
int dataPin = 11;


// Initialise a two Dimensional integer array with 
// the values for 0 - 9 on the Seven Segment LED Display
// and 0-9 with the decimal point!


int seven_seg_digits[2][10]= {
                             { 189,132,47,143,150,155,187,140,191,158   },
                             { 253,196,111,207,214,219,251,204,255,222  }
                             };


/*
   
  without decimal point 
  { 1,0,1,1,1,1,0,1 },  // = 189 in decimal
  { 1,0,0,0,0,1,0,0 },  // = 132 in decimal
  { 0,0,1,0,1,1,1,1 },  // = 47 in decimal 
  { 1,0,0,0,1,1,1,1 },  // = 143 in decimal
  { 1,0,0,1,0,1,1,0 },  // = 150 in decimal
  { 1,0,0,1,1,0,1,1 },  // = 155 in decimal
  { 1,0,1,1,1,0,1,1 },  // = 187 in decimal
  { 1,0,0,0,1,1,0,0 },  // = 140 in decimal
  { 1,0,1,1,1,1,1,1 },  // = 191 in decimal
  { 1,0,0,1,1,1,1,0 },  // = 158 in decimal
  
  with decimal point
  { 1,1,1,1,1,1,0,1 },  // = 253 in decimal
  { 1,1,0,0,0,1,0,0 },  // = 196 in decimal
  { 0,1,1,0,1,1,1,1 },  // = 111 in decimal 
  { 1,1,0,0,1,1,1,1 },  // = 207 in decimal
  { 1,1,0,1,0,1,1,0 },  // = 214 in decimal
  { 1,1,0,1,1,0,1,1 },  // = 219 in decimal
  { 1,1,1,1,1,0,1,1 },  // = 251 in decimal
  { 1,1,0,0,1,1,0,0 },  // = 204 in decimal
  { 1,1,1,1,1,1,1,1 },  // = 255 in decimal
  { 1,1,0,1,1,1,1,0 },  // = 158 in decimal




//  Just for further reference here are the 
//  separate segment connections


  pin 2 = C
  pin 3 = DOT
  pin 4 = E
  pin 5 = F
  pin 6 = A
  pin 7 = B
  pin 8 = G
  pin 9 = D


*/


void setup() {
  // set the arduino pins to output so you 
  // can control the shift register(s)
  
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  
  
  //Turn on the serial Monitor - useful for debugging!
  Serial.begin(9600);
  
  //take the latch pin of the shift register(s) low
  digitalWrite(latchPin, LOW);
  
  shiftOut(dataPin, clockPin, LSBFIRST, 0); // clears the 4th or secondUnits display
  shiftOut(dataPin, clockPin, LSBFIRST, 0); // clears the 3rd or secondTens display
  shiftOut(dataPin, clockPin, LSBFIRST, 0); // clears the 2nd or minutesUnits display
  shiftOut(dataPin, clockPin, LSBFIRST, 0); // clears the 1st or minutesTens display
  
  //take the latch pin of the shift register(s) high
  digitalWrite(latchPin, HIGH);
}


void timerCountUp(){
  
        for (secondsUnits=0; secondsUnits <=9; secondsUnits++){
            
            // take the latch pin of the shift register low
            digitalWrite(latchPin, LOW);   
            
            // Update the displays with the respective values 
            shiftOut(dataPin, clockPin, LSBFIRST, seven_seg_digits[0][secondsUnits]);    
            shiftOut(dataPin, clockPin, LSBFIRST, seven_seg_digits[0][secondsTens]); 
            shiftOut(dataPin, clockPin, LSBFIRST, seven_seg_digits[1][minutesUnits]); 
            shiftOut(dataPin, clockPin, LSBFIRST, seven_seg_digits[0][minutesTens]); 
            
            // take the latch pin high so the LEDs will light up:      
            digitalWrite(latchPin, HIGH);
            
            // pause for a second before next value:
            delay(1000);
            
            // count the number of units that have paased
            unitCount++;
            
            // for debugging send the count to the serial monitor
            
            Serial.print("Timer Count = ");
            Serial.print(minutesTens);
            Serial.print(minutesUnits);
            Serial.print(":");
            Serial.print(secondsTens);
            Serial.println(secondsUnits);       
            
            // check if the Seconds count has reached ten
            // if it has increment the Seconds Tens count 
            // and reset the Minutes unit count to zero
            
              if (unitCount == 10){
                secondsTens++;
                unitCount = 0;
                }
                
            // check if the Second Tens count has reached six        
            // if it has reset it to zero
                   
              if (secondsTens > 5){
                minutesUnits++;
                secondsTens = 0;
                }
              
              // check if the Minutes unit count is ten
              // if it is increment the Minutes tens count
              // and reset the Minutes unit count to zero
              
              if (minutesUnits == 10){
                minutesTens++;
                minutesUnits = 0;
                }
                
            // check if the Minute Tens count has reached six        
            // if it has reset it to zero
                              
              if (minutesTens > 5){
                minutesTens = 0;  
                }
                 
       }
}
   


void loop() {   
  
  // call the function timerCountUp!
  timerCountUp();





This actually took me a while to work out how to do and there is more than one method of achieving the functionality that was required.  This is my implementation there may be other more efficient ways of getting the same result.  Have a play with the code and see if you can do any better!

Here is the video of the circuit working.  I have speeded up the timing delay because it was soooo boring to watch!!


For the next post we will modify the program to make the counter count down instead of up and then add some buttons so that the user can set the start time....For now happy circuit hacking and take care people!