I am having a hard time implementing what I would like the Arudino to do. I have a fairly elaborate code written and have included just a small portion of it, specifically where I am working.
I currently have the LCD buttons functioning like they should, but I would like it to "latch" or hold that input until I press the same button again.
For instance:
Press the left button
Perform left button task - looping
Press the right button
Press the left button again
Stop performing left button task and look for new button
Part of the problem I am having is due to how fast the loop is operating, I belive, so I cannot push and release the button fast enough. The following code is functional and is "dumb", it just holds as long as you press the button.
if (buttonState == LOW) { //if the log switch is off,
lcd_key = read_LCD_buttons();
switch (lcd_key){ // Then Look at the buttons,
case btnNONE:{ // If !no! buttons are pushed, follow this code,
// Turn all relays off
digitalWrite(relayPin[0], LOW);
digitalWrite(relayPin[1], LOW);
digitalWrite(relayPin[2], LOW);
digitalWrite(relayPin[3], LOW);
digitalWrite(relayPin[4], LOW);
digitalWrite(relayPin[5], LOW);
break;
Make sure you debounce the button (if it is an actual button) then save the button's last state.
If the current state is the same as its last state, then do nothing. If they are different and is the state you want (HIGH or LOW) then you do what you want.
Small example.
byte leftButtonState = digitalRead(leftBP);
static byte lastLeftState = 0; // make this either static [u]or[/u] global.
/* debounce here if needed */
if(leftButtonState != lastLeftState)
{
// do something
lastLeftState = leftButtonState; // update the last state.
}
else { /* do nothing */ }
HazardsMind:
Make sure you debounce the button (if it is an actual button) then save the button's last state.
If the current state is the same as its last state, then do nothing. If they are different and is the state you want (HIGH or LOW) then you do what you want.
Small example.
byte leftButtonState = digitalRead(leftBP);
static byte lastLeftState = 0; // make this either static or global.
/* debounce here if needed */
if(leftButtonState != lastLeftState)
{
// do something
lastLeftState = leftButtonState; // update the last state.
}
else { /* do nothing */ }
Thank you for the help. I should specify that the button state, shown as lcd_key is returned as an integer from the LCD board.
For example:
lcd_key = read_LCD_buttons();
//lcd_key = 5 when no button is pressed
//lcd_key = 3 when the left button is pressed
//lcd_key = 0 when the right button is pressed
Given, that I am having a hard time trying to juggle that input/variable, rather than just watching a button state high/low.
Thanks again-
It's the same thing. Whether it's HIGH or LOW, or a 1 or 0, you are comparing the current value to the last value.
Here is what I have tried, however I am still not able to get what I would like out of it. The LCD buttons are functioning as momentary switches.
The LCD board returns the following:
No Button = 5
Left = 3
Right = 0
//LCD Buttons
int keyState = 5;
int lastKeyState = 5;
long lastDebounceTime = 0;
long debounceDelay = 50;
int Reading;
Reading = read_LCD_buttons();
Serial.println(Reading);
if (Reading != lastKeyState){
lastDebounceTime = millis();
}
if(Reading == 5){
// Turn all relays off
digitalWrite(relayPin[0], LOW);
digitalWrite(relayPin[1], LOW);
digitalWrite(relayPin[2], LOW);
digitalWrite(relayPin[3], LOW);
digitalWrite(relayPin[4], LOW);
digitalWrite(relayPin[5], LOW);
//Print pressure and knob position
lcd.setCursor(0,0);
lcd.print("Log:Off ");
lcd.print(Lbag,0);
lcd.print(":");
lcd.print(Rbag,0);
lcd.print("psi ");
lcd.setCursor(0,1);
lcd.print("Ready ");
lcd.print(d_avg,2);
if (d_avg < 9.99){
lcd.print(" ");
}
lcd.print("L/R ");
}
if ((millis() - lastDebounceTime) > debounceDelay){
if(Reading != keyState){
keyState = Reading;
if(keyState == 3){
digitalWrite(relayPin[0], HIGH); //Relay1 - Off
digitalWrite(relayPin[1], HIGH); //Relay2 - Off
digitalWrite(relayPin[2], HIGH); //Relay3 - Off
digitalWrite(relayPin[3], LOW); //Relay4 - Off
digitalWrite(relayPin[4], LOW); //Relay5 - Off
digitalWrite(relayPin[5], LOW); //Relay6 - Off
lcd.setCursor(0,1);
lcd.print("<");
lcd.write(5);
lcd.write(5);
lcd.write(5);
lcd.print("[^] > ");
}
if (keyState == 0){
digitalWrite(relayPin[0], LOW); //Relay1 - Off
digitalWrite(relayPin[1], LOW); //Relay2 - Off
digitalWrite(relayPin[2], LOW); //Relay3 - Off
digitalWrite(relayPin[3], HIGH); //Relay4 - Off
digitalWrite(relayPin[4], HIGH); //Relay5 - Off
digitalWrite(relayPin[5], HIGH); //Relay6 - Off
lcd.setCursor(0,1);
lcd.print("< [^]");
lcd.write(5);
lcd.write(5);
lcd.write(5);
lcd.print("> ");
}
}
}
lastKeyState = Reading;
I have a feeling it's a simple mistake, I just can't quite get my head around how this is supposed to function. When there are no buttons pushed, I want it to follow what is in the "if(Reading == 5){" statement, otherwise latch on the left or right button code until it is pressed again
Thank you-
So much white space. Please clean your code. Press CTRL + T or Tools :: Auto Format.
If the buttons are builtin to the LCD shield, then they are probably already debounced with hardware or the software was already implemented into the library.
I can't test this. let me know what it does.
void setup() {
// put your setup code here, to run once:
}
void loop()
{
static byte lastReading = 5, Locked = false;
byte reading = valuefromLCD(); // fake function
if (reading != 5) // was a button pressed?
{
if ((reading != lastReading) && !Locked) // if this IF statement is unlocked then the previous button state was the same as the current button state.
{
lastReading = reading;
Locked = true;
}
else if (reading == lastReading)
Locked = false;
}
switch (lastReading)
{
case 1: /*something */
break;
case 2: /*something*/
break;
case 3: /*something*/
break;
case 4: /*something*/
break;
default: break;
}
}
byte valuefromLCD()
{
// dummy function
return 5;
}
Edit:
It actually worked the first time around.
http://cpp.sh/3m4i