to detect a L->H on an input, then wait for a debounce time,
then verify if the pin is still H,
then wait for the pin to go back to L,
and only then to take action.
If however the pin was falsily detected H, then nothing should happen.
I have my doubts the following code will do what is required, but I can't "put my finger on it".
const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 12; // the number of the LED pin
int ledState = LOW; // the current state of the output pin
int buttonState = LOW; // the current reading from the input pin
int lastButtonState = LOW; // the previous reading from the input pin
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
int debounceDelay = 50; // the debounce time; increase if the output flickers
void setup() {
Serial.begin(115200);
pinMode(buttonPin, INPUT_PULLUP);
digitalWrite(buttonPin, HIGH);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW); // set initial LED state
}
void loop() {
// read the state of the switch into a local variable:
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH && lastButtonState == LOW) {
while (lastDebounceTime == 0) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) // uitvoeren na debounce
{
while (buttonState != lastButtonState)
{
buttonState = digitalRead (buttonPin);
}
lastButtonState = !buttonState;
}
}
if (buttonState == LOW && lastButtonState == HIGH)
{
digitalWrite (ledPin, HIGH);
delay (500);
digitalWrite (ledPin, LOW);
lastButtonState = buttonState;
lastDebounceTime = 0;
}
}
Hello
The combination of the functions delay() and millis() is not usefull.
Take a look into the IDE examples to find a proper soultion for your project.
Have a nice day and enjoy coding in C++.
The delay() in my sample is just for demo purposes. The issue at stake here is the nesting of a while in an if loop, and whether the preset conditions can be met by this program.
(Note! This is with INPUT_PULLUP) so it's an active LOW setup. Meaning you should connect your button to ground and a digital pin. No external resistors.)
#define arrSize(X) sizeof(X) / sizeof(X[0])
#define BTN0_PIN 10
#define BTN1_PIN 9
#define BTN2_PIN 8
#include "Button.h"
Button buttons[] = { BTN0_PIN, BTN1_PIN, BTN2_PIN };
void setup() {
Serial.begin(115200);
}
void loop() {
for (byte i = 0; i < arrSize(buttons); i++)
if (buttons[i].read())
Serial.println((String)"Button " + i + " Pressed"); // Debugging only. Don't cast to Strings!
}
Could be worth pulling the pinMode inside Button.h into its own 'begin' function, and then calling that on all buttons with a loop in setup. Personally, I've not had any issues with this approach, but others do advise that!
That's not expressed as a proper state machine. A state machine would be more like:
if (input reads HIGH) startTime=millis(); state = 2;
if (millis() - startTime >= debounceTime) state = 3; if (input reads LOW) state = 1;
if (input reads LOW) state = 4
take action. state = 1;
In code, that would be:
const byte ButtonPin = 4;
int State = 1;
unsigned long StartTime;
const unsigned long DebounceTime = 10;
void setup()
{
pinMode(ButtonPin, INPUT);
}
void loop()
{
switch (State)
{
case 1:
if (digitalRead(ButtonPin) == HIGH)
{
StartTime = millis();
State = 2;
}
break;
case 2:
if (millis() - StartTime >= DebounceTime)
State = 3; // Still HIGH at end of wait
if (digitalRead(ButtonPin) == LOW)
State = 1; // Went LOW before end of wait
break;
case 3:
if (digitalRead(ButtonPin) == LOW)
State = 4; // Button released
break;
case 4:
// take action
// Go back to waiting for a button press
State = 1;
break;
}
}
Top! Thank you johnwasser, use of case, and ditch my intial while.
Somewhere I found Robin2 stating that a while and for should not be used if condition fulfilment takes more than a few miliseconds.
But yet this on my initial code: a while resides inside an if loop where the while gets resolved after a short time but the if loop condition is not valid anymore... what happens then?