hi i play with button and milis, i understand the way is working but something is not fit in my mind.
buttonCState[i] = digitalRead(BUTTON_ARDUINO_PIN);
if ((millis() - lastDebounceTime[i]) > debounceDelay) {
if (buttonPState[i] != buttonCState[i]) {
lastDebounceTime[i] = millis();
if (buttonCState[i] == LOW) {
how i understand it. buttoncstate is been read, lets say is high.
now millis it has start up since the arduino is power up. lets say millis is at 10000ms , last
debounce is 0
debounce delay is declared 100ms in the sketch. so 10000-0 is more that 100 so is true and go to next line
if (buttonPState[i] != buttonCState[i]) {
button is preset when mills was in 10000ms
because buttonpstate is not equal to buttoncstate then it move to the next parameter
lastDebounceTime[i] = millis();
in this faction millis will been write to lastdebounce, what time will be writen 10000ms?
if it wite 10000ms then 10000-1000=0 so is les than debouncedelay. so the program is stack
if the button is preset continiue then each time a new lastdebounce will be writen, so we are in endless loop.
this is in my mind.. i know is working but please explain the theory in simple words.
Hello
What do you want?
If you want to debounce the botton you have to reload the time when the debounce timer has triggert.
If you want a timer function you have to code this function separately from the debouncing.
Have a nice day and enjoy coding in C++.
p.s. You can use a struct for both timers.
buttonState = digitalRead(BUTTON_ARDUINO_PIN);
if (millis() - previousMillis > debounceDelay)
{
if (lastButtonState != buttonState)
{
previousMillis = millis();
if (buttonState == LOW)
{
The 'previousMillis' may not be larger than the millis(), and that does never happen.
To update the 'previousMillis', the new button state should be different than the old button state.
If the button is pressed for 50 days, then the code is not correct anymore.
There are many ways for debouncing. I don't know if I would do it this way.
debouncedelay is 150ms i know is to mutch. 50ms is the normal but i set it to 150 for expirament.
button is preset after arduino is power up. and it pass 10000ms or 10 sec time. so i assume millis count is 10000ms, at this moment i press the button.
here is my confusion, if millis and previousmillis are the same, how the debounce will come.
if button not been preset milis will count and previousmillis will be the old value.
so next time a button presset the faction is allready true. because millis is match bigger than previousmillis.
is crazy, how the debounce will accrued. if i press again the button at 13000 condition is true again.
if the switch is bouncing will be not deference.
what the meaning to compare it with debouncedelay
ohh i think i got it... if the switch is bouncing, on/off on/off lets say 5 times. then lastdebounce will be change 5 times, so the condition will be false.
You press button at 13000, so lastPressTime assume the same value 13000.
On the next loop millis() will be 13001 so the condition millis() - lastPressTime > 50 will not be true.
13001 - 13000 > 50
When millis() equals to 13051 the condition is true again, but in the meantime bounces stops (hopefully) so a new button press can be processed.
Edit:
Yes, now you got it!
You can save the amount of time to wait also in a variable if you prefer.
buttonCState[i] = digitalRead(BUTTON_ARDUINO_PIN);
if ((millis() - lastDebounceTime[i]) > debounceDelay) {
if (buttonPState[i] != buttonCState[i]) {
lastDebounceTime[i] = millis();
if (buttonCState[i] == LOW) {
first line in sketch is readding the button,
second line is doing the maths for the debouncing
third line is to tell if the button is preset
forth line is to update the lastdebounce parameter.
buttonCState[i] = digitalRead(BUTTON_ARDUINO_PIN);
if (buttonPState[i] != buttonCState[i]) {
lastDebounceTime[i] = millis();
if ((millis() - lastDebounceTime[i]) > debounceDelay) {
if (buttonCState[i] == LOW) {
in my mind will be more normal to
read button
check button
update lastdebounce
do the maths
and if is true to go on..
or the series docent matter? arduino is goin from line 1 to line 2 then 3 and so one.?
What is not clear to me is the reason you are putting the button reading and time into arrays.
Is the intention to use the same portion of code to read more buttons?
In this case, I think it would be much more efficient to use a small class made on purpose or use a function (there are also libraries, but DIY is cooler )
If you want, I can share the code of what I did for my purposes.
PushButton button1(5, INPUT_PULLUP); // Pin active state LOW (button close contact to GND)
PushButton button2(6, INPUT, 150); // Pin active state HIGH, debounce 150 ms
void setup() {
// pinMode() not needed, it's done inside class constructor
}
void loop() {
// Due to the bool operator overloading, this is the same as if(button1.pushed())
if(button1) {
Serial.println("Button 1 pushed and this is true while button remain pressed");
}
if(button2.falling()) {
// this will fire once
Serial.println("Button 2 has changed from HIGH to LOW");
}
if(button2.rising()) {
// this will fire once
Serial.println("Button 2 has changed from LOW to HIGH");
}
}
What you do is much too complicated and consuming unnecessary resources when reading/debounceing more than one button. To debounce a button, it is sufficent to read it not too often. You must not read it twice during the debounce time, that's all. So have one millis()-if for all buttons that gets true every ~20ms and read all buttons in there.
if ( millis() - lastReadTime > debounceTime ) {
lastReadTime = millis();
// read all buttons here e.g.
for( byte i=0; i<nbrOfButtons; i++ ) {
buttonState[i] = digitalRead(buttonPins[i]);
// you can do edge detection here if necessary
}
}