Shift register - 8 led + 8 buttons

The setup:

8 buttons connected to my Arduino.
8 Leds connected to shift register (74HC595)

I want to connect button 1 to led 1, button 2 to led 2, .........

So if button 1 is pressed the led 1 should light up. But if I press button 2 when led 1 is still high, then it should only put led 2 to high.

Every example, guide or tutorial that I could find only puts 1 out of 8 leds high. I've spent hours trying to bind a button to a led, but without succes.

I have no idea how to do the following in my code:

If I press button 1:

B00000001

If I press button 2:

B00000011

If I press button 1 again:

B00000010

I hope I explained enough what my intentions are.

NOTE: I can get it to work WITHOUT a shift register. But I would like it to work using a Shift register.
NOTE2: I am not the best programmer yet :wink:

You can use bitwise XOR to toggle individual bits.

Say you've got a byte variable called LEDstate that's keeping track of the 8 LED states.

When button 1 is pressed, toggle bit 1 like this:

LEDstate ^= B00000001;

When button 2 is pressed, toggle bit 2:

LEDstate ^= B00000010;

same for button 3:

LEDstate ^= B00000100;

...

all the way up to button 8:

LEDstate ^= B10000000;

At suitable intervals, send the whole LEDstate byte out to the shift register. Sounds like you can do that already.

Good luck!

GypsumFantastic:
You can use bitwise XOR to toggle individual bits.

Say you've got a byte variable called LEDstate that's keeping track of the 8 LED states.

When button 1 is pressed, toggle bit 1 like this:

LEDstate ^= B00000001;

When button 2 is pressed, toggle bit 2:

LEDstate ^= B00000010;

same for button 3:

LEDstate ^= B00000100;

...

all the way up to button 8:

LEDstate ^= B10000000;

At suitable intervals, send the whole LEDstate byte out to the shift register. Sounds like you can do that already.

Good luck!

Thanks you for your explanation. I am trying to implement bitwise XOR into my code. I picked a standard Adafruit code for the shift register, added my buttons and added the XOR. However both buttons still interact with each other. I can sometimes control Led 1 and Led 2 with Button 1. But not all the time. What am I doing wrong or forgetting here?

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

int knop1 = 1;  //button 1 connected to pin 1
int knop2 = 2;  //button 2 connected to pin 2

int buttonstate1 = 0;    //state button 1
int buttonstate2 = 0;    //state button 2

int ledaan1 = 0;  //Light1 on/off
int ledaan2 = 0;  //Light2 on/off
 
byte leds = 0;
 
void setup() 
{
  pinMode(knop1, INPUT_PULLUP);
  pinMode(knop2, INPUT_PULLUP);
 
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);
  

}
 
void loop() 
{

    buttonstate1 = digitalRead(knop1);
    buttonstate2 = digitalRead(knop2);
    
    if (buttonstate1 == LOW && ledaan1 == 0)
    {
    leds ^= B00000001;
    bitSet(leds, 1);
    updateShiftRegister();
    delay(1000);
    //ledaan1 = !ledaan1;
    }
 
    if (buttonstate2 == LOW && ledaan2 == 0)
    {
    leds ^= B00000010;
    bitSet(leds, 2);
    updateShiftRegister();
    delay(1000);
  
  }

}
 
void updateShiftRegister()
{
   digitalWrite(latchPin, LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, leds);
   digitalWrite(latchPin, HIGH);
}

I reconnected everything on my breadboard because I wanted to make sure everything was connected properly. I noticed some pins on the shift register were bent so maybe that was the reason I got those strange results.

I also modified some code and now everything is working properly. The code is originally from here:

http://bildr.org/2011/02/74hc595/#

int SER_Pin = 4;   //pin 14 on the 75HC595
int RCLK_Pin = 5;  //pin 12 on the 75HC595
int SRCLK_Pin = 6; //pin 11 on the 75HC595

byte buttonState[8]; 
byte KnopPin[] = { 1, 3 ,2 ,7, 8, 9, 10, 11 };

//How many of the shift registers - change this
#define number_of_74hc595s 1 

//do not touch
#define numOfRegisterPins number_of_74hc595s * 8

boolean registers[numOfRegisterPins];

void setup(){
  pinMode(SER_Pin, OUTPUT);
  pinMode(RCLK_Pin, OUTPUT);
  pinMode(SRCLK_Pin, OUTPUT);

   for (int x = 0; x < 2; x++){
pinMode(KnopPin[x], INPUT_PULLUP);
   }
  //reset all register pins
  clearRegisters();
  writeRegisters();
}               


//set all register pins to LOW
void clearRegisters(){
  for(int i = numOfRegisterPins - 1; i >=  0; i--){
     registers[i] = LOW;
  }
} 


//Set and display registers
//Only call AFTER all values are set how you would like (slow otherwise)
void writeRegisters(){

  digitalWrite(RCLK_Pin, LOW);

  for(int i = numOfRegisterPins - 1; i >=  0; i--){
    digitalWrite(SRCLK_Pin, LOW);

    int val = registers[i];

    digitalWrite(SER_Pin, val);
    digitalWrite(SRCLK_Pin, HIGH);

  }
  digitalWrite(RCLK_Pin, HIGH);

}

//set an individual pin HIGH or LOW
void setRegisterPin(int index, int value){
  registers[index] = value;
}


void loop(){

for (int x = 0; x < 8; x++) {
  
  buttonState[x] = digitalRead(KnopPin[x]);
  
  if (buttonState[x] == LOW) 
  {
  setRegisterPin(x, HIGH);
  writeRegisters();  //MUST BE CALLED TO DISPLAY CHANGES
  }
  
  else if (buttonState[x] == HIGH)
   {
  setRegisterPin(x, LOW);
  writeRegisters();
   }
   }
}
  //Only call once after the values are set how you need.

Excellent. Working fine how can I toggle the led with serial read.I want to use it with serial communication from another arduino like received 'A' led1 ON and received 'B' led OFF.