1

I'm running into issue properly reading a button connected to a digital I/O pin on my Adafruit Feather HUZZAH ESP8266 device.

I've implemented the debouncing script exactly as the Arduino provided example shows, but if I add a print statement to my setup loop:

void setup() {
  Serial.begin(230400);
  Serial.println("Starting");
  pinMode(buttonPin, INPUT_PULLUP);
}

I trigger a reading of the switch on every reset cycle. Commenting out the print statement will avoid the problem so it doesn't appear to be related to the debouncing script.

In addition, I can replicate the problem on any digital I/O pin even when there is no pin connected. Once I get past the setup function, everything works as intended. Here's my whole setup code (again, copied from the example):

const int buttonPin = 13;
int buttonState;             
int lastButtonState = LOW;   

unsigned long lastDebounceTime = 0;  
unsigned long debounceDelay = 50;    

void setup() {
  Serial.begin(230400);
  Serial.println("Starting");
  pinMode(buttonPin, INPUT_PULLUP);
  lastDebounceTime = millis(); 

}

void loop() {
  int reading = digitalRead(buttonPin);

  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;

      Serial.println("A");
    }
  }

  lastButtonState = reading;
}

And here's the output of my serial monitor (with no delays on reset):

Starting
A

I can avoid this by just ignoring the first button switch but it seems odd that this is happening and I can't find any explanations for what's going on.

7
  • 2
    Please not just include your setup code, but the whole code.
    – chrisl
    Jun 17, 2021 at 14:01
  • We can't either since we can't see your code ;) There's no particular reason writing to the serial port would "trigger a button read". However: serial writes are asynchronous, and adding a call to Serial.println adds to (a) time spent in setup, and (b) time spent doing "things" before the serial buffer is written out. It seems more likely there's a flaw in the debounce logic, particularly if lastDebounceTime is initialized to 0 (a Long Time Ago to the controller). Jun 17, 2021 at 14:17
  • Added my loop code. @DaveNewton - I changed my setup to reset my lastDebounceTime to my last operation before entering my loop but still I print "A" on every reset.
    – Marc
    Jun 17, 2021 at 14:33
  • Did you try moving the pinMode to avoid the period of floating? Jun 17, 2021 at 16:49
  • 1
    The issue ended up that buttonState was never initialized in the example scripts so it begins != to the reading thus triggering as soon as the timer exceeds the debounce delay. I was able to fix it simply by initializing the value to be the same as the value of lastButtonState.
    – Marc
    Jun 18, 2021 at 3:33

2 Answers 2

1

You need to initialise buttonState to the current signal state and initialise lastDebounceTime to the current time, something like this:

int buttonState = digitalRead(buttonPin);
unsigned long lastDebounceTime = millis();

Compare with this very simple debouncer I put on GitHub.

1
  • You're absolutely right! I'm not sure why I didn't catch that or why the Arduino provided sketch doesn't initialize the variables.
    – Marc
    Jun 18, 2021 at 21:04
1

Initializing my buttonState solved my problem:

int buttonState = LOW;    
3
  • 1
    In any case, be aware that writing in serial pauses the microcontroller for a few milliseconds! Jun 18, 2021 at 17:23
  • 1
    @alessandromrc: For a few microseconds. Unless the TX buffer is full, in which case it can indeed take milliseconds. Jun 18, 2021 at 17:57
  • @EdgarBonet You are right! Jun 18, 2021 at 18:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.