Skip to content

Instantly share code, notes, and snippets.

@amd64bit
Forked from jpwsutton/MQTTWemosButton.ino
Created November 21, 2017 14:55
Show Gist options
  • Select an option

  • Save amd64bit/f6f8fc043ff942812c6b9a96b590f2c2 to your computer and use it in GitHub Desktop.

Select an option

Save amd64bit/f6f8fc043ff942812c6b9a96b590f2c2 to your computer and use it in GitHub Desktop.

Revisions

  1. @jpwsutton jpwsutton created this gist Jun 4, 2017.
    179 changes: 179 additions & 0 deletions MQTTWemosButton.ino
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,179 @@
    /***************************************************
    MQTT Button on Wemos
    James Sutton 2017 - jsutton.co.uk
    ****************************************************/
    #include <ESP8266WiFi.h>
    #include "Adafruit_MQTT.h"
    #include "Adafruit_MQTT_Client.h"

    /************************* WiFi Access Point *********************************/

    #define WLAN_SSID "WIFI SSID"
    #define WLAN_PASS "WIFI KEY"

    /************************* MQTT Setup *********************************/

    #define MQTT_SERVER "__SERVER__"
    #define MQTT_SERVERPORT 1883 // use 8883 for SSL
    #define MQTT_USERNAME "__USERNAME__"
    #define MQTT_PASSWORD "__PASSWORD__"

    /************************* Button Config *********************************/

    const int buttonPin = D5;

    /************ Global State (you don't need to change this!) ******************/

    // Create an ESP8266 WiFiClient class to connect to the MQTT server.
    WiFiClient client;
    // or... use WiFiFlientSecure for SSL
    //WiFiClientSecure client;

    // Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
    Adafruit_MQTT_Client mqtt(&client, MQTT_SERVER, MQTT_SERVERPORT, MQTT_USERNAME, MQTT_PASSWORD);

    int buttonState; // the current reading from the input pin
    int lastButtonState = LOW; // the previous reading from the input pin

    // the following variables are unsigned long's because the time, measured in miliseconds,
    // will quickly become a bigger number than can be stored in an int.
    unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
    unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers

    /****************************** Feeds ***************************************/

    // Setup a feed for publishing.
    Adafruit_MQTT_Publish buttonPub = Adafruit_MQTT_Publish(&mqtt, MQTT_USERNAME "/buttonPub");

    /*************************** Sketch Code ************************************/

    // Bug workaround for Arduino 1.6.6, it seems to need a function declaration
    // for some reason (only affects ESP8266, likely an arduino-builder bug).
    void MQTT_connect();

    void setup() {
    pinMode(buttonPin, INPUT);

    Serial.begin(115200);
    delay(10);

    Serial.println(F("MQTT Emergency Button"));

    // Connect to WiFi access point.
    Serial.println(); Serial.println();
    Serial.print("Connecting to ");
    Serial.println(WLAN_SSID);

    WiFi.begin(WLAN_SSID, WLAN_PASS);
    while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    }
    Serial.println();

    Serial.println("WiFi connected");
    Serial.println("IP address: "); Serial.println(WiFi.localIP());

    // Send Hello World Notification
    MQTT_connect();


    // Now we can publish stuff!
    Serial.print(F("\nSending Hello!"));
    Serial.print("...");
    if (! buttonPub.publish("Hello")) {
    Serial.println(F("Failed"));
    } else {
    Serial.println(F("OK!"));
    }


    }


    void loop() {
    // read the state of the switch into a local variable:
    int reading = digitalRead(buttonPin);

    // check to see if you just pressed the button
    // (i.e. the input went from LOW to HIGH), and you've waited
    // long enough since the last press to ignore any noise:

    // If the switch changed, due to noise or pressing:
    if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
    }

    if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
    buttonState = reading;

    // only toggle the LED if the new button state is HIGH
    if (buttonState == HIGH) {
    sendUpdate();
    }
    }
    }

    // save the reading. Next time through the loop,
    // it'll be the lastButtonState:
    lastButtonState = reading;
    }

    void sendUpdate() {
    // Ensure the connection to the MQTT server is alive (this will make the first
    // connection and automatically reconnect when disconnected). See the MQTT_connect
    // function definition further below.
    MQTT_connect();


    // Now we can publish stuff!
    Serial.print(F("\nSending button press!"));
    Serial.print("...");
    if (! buttonPub.publish(1)) {
    Serial.println(F("Failed"));
    } else {
    Serial.println(F("OK!"));
    }

    // ping the server to keep the mqtt connection alive
    // NOT required if you are publishing once every KEEPALIVE seconds
    /*
    if(! mqtt.ping()) {
    mqtt.disconnect();
    }
    */
    }

    // Function to connect and reconnect as necessary to the MQTT server.
    // Should be called in the loop function and it will take care if connecting.
    void MQTT_connect() {
    int8_t ret;

    // Stop if already connected.
    if (mqtt.connected()) {
    return;
    }

    Serial.print("Connecting to MQTT... ");

    uint8_t retries = 3;
    while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
    Serial.println(mqtt.connectErrorString(ret));
    Serial.println("Retrying MQTT connection in 5 seconds...");
    mqtt.disconnect();
    delay(5000); // wait 5 seconds
    retries--;
    if (retries == 0) {
    // basically die and wait for WDT to reset me
    while (1);
    }
    }
    Serial.println("MQTT Connected!");
    }