Linking Four SHift Register

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: Linking Four SHift Register

Post by adafruit_support_mike »

bob500000 wrote:Still not too sure what you meant by checkbuttons.
That was just a name I made up while I was writing the example code. When I write snippets I tend to skip over details by calling a function with a name that describes what should happen at that point. Use your check_switches() function there.

Does the system do what you want with that code?

bob500000
 
Posts: 54
Joined: Tue Nov 20, 2012 11:16 am

Re: Linking Four SHift Register

Post by bob500000 »

Hi mike,

Thanks for that, was thinking that but, the second button doesn't work it is either live or not on the last shift registers in theory, by pressing the switch it should swap to shift registers 3 and 4, am I correct?

So I currently have to following edited of course, I need to the LED's to stop once a a cycle has finished, say lighting all 16 bits, which then calls the results function.

When the user presses the second button then the method test 2 executes and runs the exact same code as test 1 but on shift register 3 and 4.

Currently I can't get any LED's to light up, I can confirm that the wiring is correct.

Cheers.

Code: Select all

#include <Button.h>

int latchPin = 5;
int clockPin = 6;
int dataPin = 4;
int latchPin2 = 0;
int clockPin2 = 1;
int dataPin2 = 2;
int outputEnablePin = 3;
int outputEnablePin2 = 14;
int ledPin = 10;
//Button trigger = Button(2,LOW);
int sr1Colour = 0;  // Set for ShiftReg1 as 0 = off, 1 = green, 2 = red
int sr2Colour = 0;
int ledState = 0;
int ledState2 = 0;
const int ON = HIGH;
const int OFF = LOW;
int bright = 0;    // how bright the LED is
int fadeAmount = 5;    // how many points to fade the LED by

byte leds = 0;
byte button[] = {7, 8};
byte switch_value = 0;
boolean btnOn = false;
int count = 0;

#define NUMBUTTONS sizeof(button)
byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];

void setup() {
  
  
  //setBrightness(0);
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);
  pinMode(outputEnablePin, OUTPUT); 
  pinMode(outputEnablePin2, OUTPUT); 
 pinMode(latchPin2, OUTPUT);
  pinMode(dataPin2, OUTPUT);  
  pinMode(clockPin2, OUTPUT);
  //pinMode(2,INPUT); //Trigger switch sits on pin 2
  Serial.begin(9600);
  Serial.println("Welcome");
  byte i;
  
   for (i=0; i< NUMBUTTONS; i++) {
    pinMode(button[i], INPUT);
    digitalWrite(button[i], HIGH);
  }
    //Timer2 Overflow Interrupt Enable
  TIMSK2 |= 1<<TOIE2;
}
//byte pressCount1 = 0;
SIGNAL(TIMER2_OVF_vect) {
  check_switches();
}

void check_switches()
{
  static byte previousstate[NUMBUTTONS];
  static byte currentstate[NUMBUTTONS];
  byte index;

  for (index = 0; index < NUMBUTTONS; index++) {
    currentstate[index] = digitalRead(button[index]);   // read the button
    /*    
    Serial.print(index, DEC);
    Serial.print(": cstate=");
    Serial.print(currentstate[index], DEC);
    Serial.print(", pstate=");
    Serial.print(previousstate[index], DEC);
    Serial.print(", press=");
    */
    
    if (currentstate[index] == previousstate[index]) {
      if ((pressed[index] == LOW) && (currentstate[index] == LOW)) {
          // just pressed
          justpressed[index] = 1;
          count = count+1;
          //switch_value = switch_value + 1;

      }
      else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) {
          // just released
          justreleased[index] = 1;
      }
      pressed[index] = !currentstate[index];  // remember, digital HIGH means NOT pressed
    }
    //Serial.println(pressed[index], DEC);
    previousstate[index] = currentstate[index];   // keep a running tally of the buttons
  }
}


void loop() {
 /////////////////////////////////////////////////////
 //This is Button 1 Set Press
 /////////////////////////////////////////////////////
 updateLEDs(ledState == -5);
  idle();
  if(justpressed[0])
  {
    updateLEDs2(ledState == -5);
    Serial.print("Button 1 pressed");
    btnOn = true;
    idleoff();
  int delayTime = 2000; //the number of milliseconds to delay between LED updates
  for(int i = 0; i < 16; i++){
  updateLEDs(i);
  delay(delayTime);
  }
  }
//  /////////////////////////////////////////////////////
// //This is Button 2 Set Press
// /////////////////////////////////////////////////////
if(justpressed[1])
  {
    //updateLEDs2(ledState == -5);
    updateLEDs(ledState == -5);
    Serial.print("Button 2 pressed");
    btnOn = true;
    idleoff();
  int delayTime = 2000; //the number of milliseconds to delay between LED updates
  for(int i = 0; i < 16; i++){
    Serial.print("For");
  updateLEDs2(i);
  delay(delayTime);
  }
}
updateLEDs(ledState == -5);
   Result();
}
/////////////////////////////////////////////////////
//This the idle setup
////////////////////////////////////////////////////
void idle()
{
  // set the brightness of pin 9:
  analogWrite(10, bright);    

  // change the brightness for next time through the loop:
  bright = bright + fadeAmount;

  // reverse the direction of the fading at the ends of the fade: 
  if (bright == 0 || bright == 255) {
    fadeAmount = -fadeAmount ; 
  }     
  // wait for 30 milliseconds to see the dimming effect    
  delay(100);                            
}
/////////////////////////////////////////////////////
//This the idle off switch
////////////////////////////////////////////////////
void idleoff()
{
  // set the brightness of pin 9:
  analogWrite(10,0);                        
}
/////////////////////////////////////////////////////
//This the idle setup
////////////////////////////////////////////////////
void Result()
{
  // set the brightness of pin 9:
  analogWrite(11, bright);    

  // change the brightness for next time through the loop:
  bright = bright + fadeAmount;

  // reverse the direction of the fading at the ends of the fade: 
  if (bright == 0 || bright == 255) {
    fadeAmount = -fadeAmount ; 
  }     
  // wait for 30 milliseconds to see the dimming effect    
  delay(70);                            
}
////  /////////////////////////////////////////////////////
//// // Test1
//// /////////////////////////////////////////////////////

void updateLEDs(uint16_t value){
    digitalWrite(latchPin, LOW);                           //Pulls the chips latch low
    shiftOut(dataPin, clockPin, MSBFIRST, value >> 8);    //Shifts the upper 8 bits of 'value'
    shiftOut(dataPin, clockPin, MSBFIRST, value);         //Shifts the lower 8 bits of 'value'
    digitalWrite(latchPin, HIGH);                          //Pulls the latch high displaying the data
}

void updateLEDsLong(uint16_t value){
    digitalWrite(latchPin, LOW);

    for(int i = 16 ; i >= 0 ; i++) {        //  start at the high end and move to the low end
        if((value >> i) & 1) {              //  shift the i-th bit to the 1s position
            digitalWrite(dataPin, HIGH);
        } else { 
            digitalWrite(dataPin, LOW);
        }
        digitalWrite(clockPin, HIGH);
        delay(1);
        digitalWrite(clockPin, LOW);
    }
    
    digitalWrite(latchPin, HIGH);
}

void changeLED(int led, int state) {
    uint16_t bit = 1 << led;                //  all zeros except for a 1 at position 'led'
    ledState = ledState | bit;            //  set the bit high by default
    
    if(state == OFF) {
        ledState = ledState ^ bit;        //  set the bit low with an exclusive-OR
    }
    updateLEDs(ledState);
    setBrightness (255);
}

////  /////////////////////////////////////////////////////
//// // Test2
//// /////////////////////////////////////////////////////
void updateLEDs2(int value){
  digitalWrite(latchPin2, LOW);     //Pulls the chips latch low
  shiftOut(dataPin2, clockPin2, MSBFIRST, value); //Shifts out the 8 bits to the shift register
  digitalWrite(latchPin2, HIGH);   //Pulls the latch high displaying the data
}
/*
 * updateLEDsLong() - sends the LED states set in ledStates to the 74HC595
 * sequence. Same as updateLEDs except the shifting out is done in software
 * so you can see what is happening.
 */ 
void updateLEDs2(uint16_t value){
    digitalWrite(latchPin2, LOW);                           //Pulls the chips latch low
    shiftOut(dataPin2, clockPin2, MSBFIRST, value >> 8);    //Shifts the upper 8 bits of 'value'
    shiftOut(dataPin2, clockPin2, MSBFIRST, value);         //Shifts the lower 8 bits of 'value'
    digitalWrite(latchPin2, HIGH);                          //Pulls the latch high displaying the data
}

void updateLEDsLong2(uint16_t value){
    digitalWrite(latchPin2, LOW);

    for(int i = 16 ; i >= 0 ; i++) {        //  start at the high end and move to the low end
        if((value >> i) & 1) {              //  shift the i-th bit to the 1s position
            digitalWrite(dataPin2, HIGH);
        } else { 
            digitalWrite(dataPin2, LOW);
        }
        digitalWrite(clockPin2, HIGH);
        delay(1);
        digitalWrite(clockPin2, LOW);
    }
    
    digitalWrite(latchPin2, HIGH);
}

void changeLED2(int led, int state) {
    uint16_t bit = 1 << led;                //  all zeros except for a 1 at position 'led'
    ledState2 = ledState2 | bit;            //  set the bit high by default
    
    if(state == OFF) {
        ledState2 = ledState2 ^ bit;        //  set the bit low with an exclusive-OR
    }
    updateLEDs2(ledState2);
    setBrightness2 (255);
}

/////////////////////////////////////////////////////
 //This is setBrightness
 ////////////////////////////////////////////////////
void setBrightness(byte brightness) // 0 to 255
{
  analogWrite(outputEnablePin, 255-brightness);
}

void setBrightness2(byte brightness) // 0 to 255
{
  analogWrite(outputEnablePin2, 255-brightness);
}

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: Linking Four SHift Register

Post by adafruit_support_mike »

You have two versions of the updateLEDs2() function in the code:

Code: Select all

////  /////////////////////////////////////////////////////
//// // Test2
//// /////////////////////////////////////////////////////
void updateLEDs2(int value){
  digitalWrite(latchPin2, LOW);     //Pulls the chips latch low
  shiftOut(dataPin2, clockPin2, MSBFIRST, value); //Shifts out the 8 bits to the shift register
  digitalWrite(latchPin2, HIGH);   //Pulls the latch high displaying the data
}
/*
* updateLEDsLong() - sends the LED states set in ledStates to the 74HC595
* sequence. Same as updateLEDs except the shifting out is done in software
* so you can see what is happening.
*/ 
void updateLEDs2(uint16_t value){
    digitalWrite(latchPin2, LOW);                           //Pulls the chips latch low
    shiftOut(dataPin2, clockPin2, MSBFIRST, value >> 8);    //Shifts the upper 8 bits of 'value'
    shiftOut(dataPin2, clockPin2, MSBFIRST, value);         //Shifts the lower 8 bits of 'value'
    digitalWrite(latchPin2, HIGH);                          //Pulls the latch high displaying the data
}
That's probably causing some confusion about which one to execute. I'm surprised it compiles without a warning, but just confirmed that it does.

It doesn't look like you use any of the functions:

- UpdateLEDsLong()
- UpdateLEDsLong2()
- changeLED()
- changeLED2()

so you may as well remove those from the file too.

This loop:

Code: Select all

  for(int i = 0; i < 16; i++){
    Serial.print("For");
  updateLEDs2(i);
  delay(delayTime);
  }
will only light the last four LEDs, even when everything works as it should. The bit patterns for the integers 0-15 are [0000, 0001, 0010, 0011, 0100, 0101, 0110, 0111, 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111]

To light each of the 16 LEDs in turn, try this:

Code: Select all

  updateLEDs2( 0x8000 >> i );
I don't see any code that would swap the values that go to shift registers 3 and 4.

bob500000
 
Posts: 54
Joined: Tue Nov 20, 2012 11:16 am

Re: Linking Four SHift Register

Post by bob500000 »

Hi MIke,

Thanks for that, must have missed that part out of the trimming re: updateLEDs2 method.

Well the shift registers are independant of the first set so surely but duplicating the same structure will work, just amending if for example:

Code: Select all

int latchPin = 5;
int clockPin = 6;
int dataPin = 4;
int latchPin2 = 0;
int clockPin2 = 1;
int dataPin2 = 2;

  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);
  pinMode(latchPin2, OUTPUT);
  pinMode(dataPin2, OUTPUT);  
  pinMode(clockPin2, OUTPUT);

Cheers

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: Linking Four SHift Register

Post by adafruit_support_mike »

The code should work the same way for both pairs of shift registers, yes. Let's strip away some of the complexity and check that assumption though:

Code: Select all

int latchPin = 5;
int clockPin = 6;
int dataPin = 4;
int outputEnablePin = 3;

int latchPin2 = 0;
int clockPin2 = 1;
int dataPin2 = 2;
int outputEnablePin2 = 14;


void setup() {
    pinMode(latchPin, OUTPUT);
    pinMode(dataPin, OUTPUT);  
    pinMode(clockPin, OUTPUT);
    pinMode(outputEnablePin, OUTPUT); 

    pinMode(latchPin2, OUTPUT);
    pinMode(dataPin2, OUTPUT);  
    pinMode(clockPin2, OUTPUT);
    pinMode(outputEnablePin2, OUTPUT); 

    Serial.begin(9600);
    Serial.println("Welcome");
    
    byte i;
    int wait = 250;

    Serial.println("Testing the first pair of shift registers:");
    for (i=15 ; i >= 0 ; i--) {
        Serial.print("  LED #");
        Serial.println( i+1 );
        
        updateLEDs( 1 << i );
        delay( wait );
    }

    Serial.println("Testing the second pair of shift registers:");
    for (i=15 ; i >= 0 ; i--) {
        Serial.print("  LED #");
        Serial.println( i+1 );
        
        updateLEDs2( 1 << i );
        delay( wait );
    }
}

void updateLEDs(uint16_t value){
    digitalWrite(latchPin, LOW);                           //Pulls the chips latch low
    shiftOut(dataPin, clockPin, MSBFIRST, value >> 8);    //Shifts the upper 8 bits of 'value'
    shiftOut(dataPin, clockPin, MSBFIRST, value);         //Shifts the lower 8 bits of 'value'
    digitalWrite(latchPin, HIGH);                          //Pulls the latch high displaying the data
}

void updateLEDs2(uint16_t value){
    digitalWrite(latchPin2, LOW);                           //Pulls the chips latch low
    shiftOut(dataPin2, clockPin2, MSBFIRST, value >> 8);    //Shifts the upper 8 bits of 'value'
    shiftOut(dataPin2, clockPin2, MSBFIRST, value);         //Shifts the lower 8 bits of 'value'
    digitalWrite(latchPin2, HIGH);                          //Pulls the latch high displaying the data
}

bob500000
 
Posts: 54
Joined: Tue Nov 20, 2012 11:16 am

Re: Linking Four SHift Register

Post by bob500000 »

Hi mike,

So in terms of the buttons, how would you get them to give the desired results?

Would you call separate methods as I have or would you just put the conditions into the if statement?

Cheers

bob500000
 
Posts: 54
Joined: Tue Nov 20, 2012 11:16 am

Re: Linking Four SHift Register

Post by bob500000 »

Hi mike thanks for all your assistance,

It's been submitted now but a picture of it wil follow tomorrow, if you require anything else from me let me know.

Cheers bob.

bob500000
 
Posts: 54
Joined: Tue Nov 20, 2012 11:16 am

Re: Linking Four SHift Register

Post by bob500000 »

As requested here is a picture of the completed project.
Complete.jpg
Complete.jpg (658.25 KiB) Viewed 862 times

User avatar
adafruit_support_bill
 
Posts: 88089
Joined: Sat Feb 07, 2009 10:11 am

Re: Linking Four SHift Register

Post by adafruit_support_bill »

Thanks for the photo. :) Was this for a class project?

bob500000
 
Posts: 54
Joined: Tue Nov 20, 2012 11:16 am

Re: Linking Four SHift Register

Post by bob500000 »

Final year dissertation project bill

Lots of planning asking questions to get it right! In the end!

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”