问题
How to stop contiguous state change upon button hold?
const int btn = 5;
const int ledPin = 3;
int ledValue = LOW;
void setup(){
Serial.begin(9600);
pinMode(btn, INPUT_PULLUP);
pinMode(ledPin, OUTPUT);
}
void loop ()
{
if (digitalRead(btn) == LOW)
delay(100);
{
ledValue = !ledValue;
delay(100);
digitalWrite(ledPin, ledValue);
delay(100);
Serial.println(digitalRead(ledPin));
}
}
When I hold the button I receive contiguous state change. I want to press button and receive single state change, upon hold -- or accidental hold -- I would not like to change state.
More looking for effect of edge detection with the result of flip flop.
There is more development to be done on this code but this is the first stage. Eventually I will integrate a FOR statement into the loop and perhaps a SWITCH(case) statement.
Basically I need to be able to toggle output pins with a single momentary push, I also would like -- in the FUTURE -- to be able to cycle through possible output states based on specific input conditions, by way of using FOR and SWITCH(case) together. That is a different post. Unless you can surmise a solution for that problem as well.
回答1:
The easiest way is to add a variable that holds the state of the button.
When you press the button, that variable is set to true and the code you want runs. While that variable is true, the code you wrote will not be executed a second time. When you release the button, the variable gets set to false, so a next button press will have your code executed again.
Code:
bool isPressed = false; // the button is currently not pressed
void loop ()
{
if (digitalRead(btn) == LOW) //button is pressed
{
if (!isPressed) //the button was not pressed on the previous loop (!isPressed means isPressed == FALSE)
{
isPressed = true; //set to true, so this code will not run while button remains pressed
ledValue = !ledValue;
digitalWrite(ledPin, ledValue);
Serial.println(digitalRead(ledPin));
}
}
else
{
isPressed = false;
// the button is not pressed right now,
// so set isPressed to false, so next button press will be handled correctly
}
}
Edit: added a second example
const int btn = 5;
const int ledPin = 3;
int ledValue = LOW;
boolean isPressed = false;
void setup(){
Serial.begin(9600);
pinMode(btn, INPUT_PULLUP);
pinMode(ledPin, OUTPUT);
}
void loop ()
{
if (digitalRead(btn) == LOW && isPressed == false ) //button is pressed AND this is the first digitalRead() that the button is pressed
{
isPressed = true; //set to true, so this code will not run again until button released
doMyCode(); // a call to a separate function that holds your code
} else if (digitalRead(btn) == HIGH)
{
isPressed = false; //button is released, variable reset
}
}
void doMyCode() {
ledValue = !ledValue;
digitalWrite(ledPin, ledValue);
Serial.println(digitalRead(ledPin));
}
来源:https://stackoverflow.com/questions/53980861/bistable-single-push-toggle-using-momentary-pushbutton-no-contiguous-toggle-upo