homieiot / homie-esp8266

💡 ESP8266 framework for Homie, a lightweight MQTT convention for the IoT
http://homieiot.github.io/homie-esp8266
MIT License
1.36k stars 308 forks source link

Adding a user interrupt for a short press on GPIO0 ? #72

Closed SFarrell1 closed 8 years ago

SFarrell1 commented 8 years ago

Hi Marvin, First of all thank you for the impressive work on the Homie-ESP8266 framework - for a newcomer like me to programming it is a superb help to get Things up and running quickly.

I have a request - if I have understood correctly Homie uses a 5 second interrupt on GPIO0 to go into reset mode. For a simple smartplug I am looking to have just one physical button which could either toggle the relay (short press) or reset the unit as per currently (5 second press). I don't feel competent enough to mess with your source code ;-) is this something that could easily be implemented in a future version? Best, Sean

marvinroger commented 8 years ago

This is actually pretty simple: take the DoorSensor example

#include <Homie.h>

const int PIN_BUTTON = 16;

Bounce debouncer = Bounce(); // Bounce is built into Homie, so you can use it without including it first
int lastButtonValue = -1;

HomieNode buttonNode("button", "button");

void loopHandler() {
  int buttonValue = debouncer.read();

  if (buttonValue != lastButtonValue) {
     Serial.print("Button is now: ");
     Serial.println(buttonValue ? "closed" : "open");

     if (Homie.setNodeProperty(buttonNode, "pressed", buttonValue ? "false" : "true", true)) {
       lastButtonValue = buttonValue;
     } else {
       Serial.println("Sending failed");
     }
  }
}

void setup() {
  pinMode(PIN_BUTTON, INPUT);
  digitalWrite(PIN_BUTTON, HIGH);
  debouncer.attach(PIN_BUTTON);
  debouncer.interval(50);

  Homie.setFirmware("awesome-button", "1.0.0");
  Homie.setResetTrigger(PIN_BUTTON, LOW, 5000);
  Homie.registerNode(buttonNode);
  Homie.setLoopFunction(loopHandler);
  Homie.setup();
}

void loop() {
  Homie.loop();
  debouncer.update();
}

Let me know if it works for you.

SFarrell1 commented 8 years ago

Thanks Marvin. Yes - it works this way (before I was using an interrupt on GPIO 0), I see that there is no conflict between checking the state of PIN 0 and the reset function.

marvinroger commented 8 years ago

You're welcome! :smile:

peterhanzlik commented 8 years ago

Perhaps someone finds it useful. This code handles a button that is not a registered HomieNode (button itself does not subscribe/publish MQTT), but controls a registered HomieNode, e.g. a relay.

#include <Homie.h>

const int PIN_BUTTON = 2;

Bounce debouncer = Bounce();
boolean lastButtonValue = true;

void loopHandler() {
  boolean buttonValue = debouncer.read();

  if (buttonValue != lastButtonValue) {

     if (buttonValue == false) {
       Serial.print(millis());
       Serial.println(": button pressed");
     }

     lastButtonValue = buttonValue;
  }
}

void setup() {
  pinMode(PIN_BUTTON, INPUT);
  digitalWrite(PIN_BUTTON, HIGH);
  debouncer.attach(PIN_BUTTON);
  debouncer.interval(50);

  Homie.setFirmware("homie-button", "1.0.0");
  Homie.setLoopFunction(loopHandler);
  Homie.setup();
}

void loop() {
  Homie.loop();
  debouncer.update();
}