So I've spent the last few hours with a ridiculously simple problem, but my logic appears to have an issue somewhere.
I'm trying to make a simple software latch for another project:
push button, led stays on
push button again, led stays off
push button again, led stays on
etc
I have it working except for one last thing, here is the code
//simple program to test making a latch
//button held low by 10k pull down, button pressed should latch led on
//button pressed again, led should latch off
//variables
boolean ledpin = 13; //led on pin 13
boolean button = 12; //button on pin 12
boolean state = 0; //state of button pin
boolean newState = 0; //new button state variable
void setup(){
pinMode(ledpin, OUTPUT); //led output
pinMode(button, INPUT); //button input
}
void loop() {
state = (digitalRead(button)); //state is value of button
if(state == 0 && newState == 0){ //if state and lastState are both 0 (button unpressed)
digitalWrite(ledpin, LOW); // led is off
newState = 0; //lastState is still 0
}
if(state == 1 && newState == 0){ //if state is 1 (button press) and lastState is 0
digitalWrite(ledpin, HIGH); //led is on
newState = 1; // lastState is now 1
}
if(state == 0 && newState == 1){ //if state is 0(button unpressed) and lastState is 1
digitalWrite(ledpin, HIGH); //led is on
newState = 1; //lastState is still 1
}
if(state == 1 && newState == 1){ //if state is 1(button pressed) and lastState is 1
digitalWrite(ledpin, LOW); //turn led off
//newState = 0; //lastState should now be 0 again and loop repeats
}
}
//rinse and repeat
Now, that code will make the led latch on after pressing the button but when i push it again, the led blinks off but stays on when i release the button.
The commented out bit of the last If statement was my attempt to fix this but i'm having a logic issue somewhere. I'v also tried setting both 'state' and 'newState' to 0 when 'state' and 'newState' = 1 but to no avail.
I know this will have a simple answer, can someone please tell me what i'm missing?
As it is right now, multiple if tests may succeed, as you change states in previous blocks.
The value that you want for newState is the value that is in state, regarless of which action occurred. So, remove the code for setting newState, and add
newState = state; after all the if tests.
I saw that yes. I tried your way initially and have just redone it, but now nothing happens at all when I press the button.
//simple program to test making a latch
//button held low by 10k pull down, button pressed should latch led on
//button pressed again, led should latch off
//variables
boolean ledpin = 13; //led on pin 13
boolean button = 12; //button on pin 12
boolean state = 0; //state of button pin
boolean newState = 0; //new button state variable
void setup(){
pinMode(ledpin, OUTPUT); //led output
pinMode(button, INPUT); //button input
}
void loop() {
state = (digitalRead(button)); //state is value of button
if(state == 0 && newState == 0){ //if state and lastState are both 0 (button unpressed)
digitalWrite(ledpin, LOW); // led is off
newState = state; //lastState is still 0
}
else if(state == 1 && newState == 0){ //if state is 1 (button press) and lastState is 0
digitalWrite(ledpin, HIGH); //led is on
newState = state; // lastState is now 1
}
else if(state == 0 && newState == 1){ //if state is 0(button unpressed) and lastState is 1
digitalWrite(ledpin, HIGH); //led is on
newState = state; //lastState is still 1
}
else if(state == 1 && newState == 1){ //if state is 1(button pressed) and lastState is 1
digitalWrite(ledpin, LOW); //turn led off
newState = state; //lastState should now be 0 again and loop repeats
}
}
//rinse and repeat
if(state == 0 && newState == 0){ // switch is not and was not pressed
digitalWrite(ledpin, LOW);
}
else if(state == 1 && newState == 0){ // switch was just pressed
digitalWrite(ledpin, HIGH);
}
else if(state == 0 && newState == 1){ // switch was just released
digitalWrite(ledpin, HIGH); //led is on
}
else if(state == 1 && newState == 1){ // switch is pressed and was pressed last time we checked
digitalWrite(ledpin, LOW); //turn led off
}
newState = state; // newState is whatever the switch state was
Notice that I changed when the previous state is stored (newState is a lousy name for old state) and I changed the comments to reflect what test really means. You may need to change what happens in the block to agree with the comments.
I just got somewhere as I read your post. I tried your way but it didn't seem to work. I put a delay before the If statements in your code but when the button was pressed or depressed the led just flickers but no latching occurs.
I found this solution works, I was focusing on my 4th If statement but then I looked at my 3rd and made the following changes:
//simple program to test making a latch
//button held low by 10k pull down, button pressed should latch led on
//button pressed again, led should latch off
//variables
boolean ledpin = 13; //led on pin 13
boolean button = 12; //button on pin 12
boolean state = 0; //state of button pin
boolean newState = 0; //new button state variable
void setup(){
pinMode(ledpin, OUTPUT); //led output
pinMode(button, INPUT); //button input
}
void loop() {
state = (digitalRead(button)); //state is value of button
delay(70); //button debounce (not needed if debounce circuit exists)
if(state == 0 && newState == 0){ //if state and lastState are both 0 (button unpressed)
digitalWrite(ledpin, LOW); // led is off
newState = state; //lastState is still 0
}
else if(state == 1 && newState == 0){ //if state is 1 (button press) and lastState is 0
digitalWrite(ledpin, HIGH); //led is on
newState = state; // lastState is now 1
}
else if(state == 0 && newState == 1){ //if state is 0(button unpressed) and lastState is 1
digitalWrite(ledpin, HIGH); //led is on
//newState = 1; //lastState is still 1
}
else if(state == 1 && newState == 1){ //if state is 1(button pressed) and lastState is 1
digitalWrite(ledpin, LOW); //turn led off
newState = 0; //lastState should now be 0 again and loop repeats
}
}
//rinse and repeat
I basically just took out the 'newState' change in the 3rd If statement and now it works. It should work better on my actual hardware debounce circuit.