Button Function Fires repeatedly but no button was pushed

Hey All,
I’m working with a Huzzah Feather and as usual I can get the pieces to work but not the whole. My button function keeps firing despite no button pushes.

I’ve wired up a capacitive touch button and loaded up the Arduino Debounce example sketch and everything works as intended.

I’m using MQTT to send data to and from io.adafruit.com. I’ve set up a couple of feeds and I can toggle pins on the board from io.adafruit.com, super cool!

When I add the button function to the code it works but it keeps firing over and over. How can I write this so it only executes when the button is pressed?

#include "config.h"

#define LED_PIN 5

const int BUTTON_PIN = 16;    // the number of the pushbutton pin

int ledState = LOW;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers

AdafruitIO_Feed *digital = io.feed("digital");

void handleMessage(AdafruitIO_Data *data) {

  Serial.print("received Digital Feed <- ");

  if (data->toPinLevel() == HIGH)
    Serial.println("HIGH");
  else
    Serial.println("LOW");

  // write the current state to the led
  digitalWrite(LED_PIN, data->toPinLevel());

}

void button() {
  int reading = digitalRead(BUTTON_PIN);

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

  if ((millis() - lastDebounceTime) > debounceDelay) {

    if (reading != buttonState) {
      buttonState = reading;

      if (buttonState == HIGH) {
        ledState = !ledState;
      }
    }
  }
  lastButtonState = reading;

  Serial.print("Digital Pin Status"); Serial.println(ledState);

  digitalWrite(LED_PIN, ledState);

  digital->save(ledState);

}

void setup() {
  pinMode(BUTTON_PIN, INPUT);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, ledState);

  Serial.begin(115200);

  while (! Serial);

  Serial.print("Connecting to Adafruit IO");
  io.connect();

  digital->onMessage(handleMessage);

  while (io.status() < AIO_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  Serial.println(io.statusText());

}

void loop() {
  io.run();
 button();
}

Thanks!
Rich

How is the button wired ?

three wires

3.3V Ground Signal

p.s. the button wired up works perfectly with the example debounce sketch.

From the 'debounce' sketch:

  • 10K resistor attached from pin 2 to ground

Do you have this?

It's a little bit unclear what you mean by this:

My button function keeps firing despite no button pushes.

What it looks like from the code is that your button() function is supposed to run over and over again, and what the button() function does is check to see if a button is pressed. By "firing" do you mean that the button() function is run? Because that is what happens, and that is what is supposed to happen.

Or by "firing" do you mean it does the digital->save()? Because it does that every time the button() function is called, whether or not the button is pressed. If you want it to do THAT only when the button is pressed, you should put it inside the if conditional.

Thanks Jimmus!

Yes I only want to send data when the button is pressed. And yes, you were correct the way I had it was sending data on it’s own.

I did as you suggested and put the digital->save() in the if loop. That’s gotten me halfway there.

The code below allows me to toggle the pin through the feed at io.adafruit.com But when I touch the button it will turn the pin LOW and only LOW.

How can I write this button function so it also toggles the pin?

#include "config.h"

#define LED_PIN 5

const int BUTTON_PIN = 16;    // the number of the pushbutton pin

int ledState = LOW;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers

AdafruitIO_Feed *digital = io.feed("digital");

void handleMessage(AdafruitIO_Data *data) {

  Serial.print("received Digital Feed <- ");

  if (data->toPinLevel() == HIGH)
    Serial.println("HIGH");
  else
    Serial.println("LOW");

  // write the current state to the led
  digitalWrite(LED_PIN, data->toPinLevel());

}

void button() {
  int reading = digitalRead(BUTTON_PIN);

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

    if ((millis() - lastDebounceTime) > debounceDelay) {

      if (reading != buttonState) {
        buttonState = reading;

        if (buttonState == HIGH) {
          ledState = !ledState;
        }
      }
      lastButtonState = reading;
    }
    digital->save(ledState);
    Serial.print("Digital Pin Status"); Serial.println(ledState);
    digitalWrite(LED_PIN, ledState);
  }
}

void setup() {
  pinMode(BUTTON_PIN, INPUT);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, ledState);

  Serial.begin(115200);

  while (! Serial);

  Serial.print("Connecting to Adafruit IO");
  io.connect();

  digital->onMessage(handleMessage);

  while (io.status() < AIO_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  Serial.println(io.statusText());

}

void loop() {
  io.run();
}

Thanks!

To toggle the state of the LED you can do

    digitalWrite(LED_PIN, !digitalRead(LED_PIN));
  }

That will, of course, not change the value of the ledState variable, but does that matter ?

I still don't think you put it in the right place.

And now, button() NEVER gets called?