Last active
March 19, 2018 21:11
-
-
Save RyanParsley/9b7bcf68cc691d94cd7bce34766cc6f3 to your computer and use it in GitHub Desktop.
Code for a huzzah feather gather wifi information via an access point mode if not connected. Then, communicate state changes via MQTT.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <ESP8266WiFi.h> | |
| #include <WiFiClient.h> | |
| #include <ESP8266WebServer.h> | |
| #include <ESP8266mDNS.h> | |
| #include <DNSServer.h> | |
| #include <WiFiManager.h> | |
| #include "Adafruit_MQTT.h" | |
| #include "Adafruit_MQTT_Client.h" | |
| ESP8266WebServer server(80); | |
| //Status indicator | |
| const int statusLed = 13; | |
| //State indicator | |
| const int stateLed = 15; | |
| bool lightState = LOW; | |
| bool lastButtonState = LOW; | |
| bool lastLightState = LOW; | |
| /************************* Adafruit.io Setup *********************************/ | |
| #define AIO_SERVER "io.adafruit.com" | |
| #define AIO_SERVERPORT 1883 // use 8883 for SSL | |
| #define AIO_USERNAME "" | |
| #define AIO_KEY "" | |
| WiFiClient client; | |
| // Setup the MQTT client class by passing in the WiFi client and MQTT server and login details. | |
| Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY); | |
| /****************************** Feeds ***************************************/ | |
| // Setup a feed called 'photocell' for publishing. | |
| // Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname> | |
| char *prefix = "/feeds/dingus-"; | |
| String feed = String(AIO_USERNAME) + String("/feeds/dingus-") + String(ESP.getChipId()); | |
| Adafruit_MQTT_Publish light = Adafruit_MQTT_Publish(&mqtt, feed.c_str()); | |
| Adafruit_MQTT_Publish button = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/button"); | |
| // Setup a feed called 'onoff' for subscribing to changes. | |
| Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/onoff"); | |
| void MQTT_connect(); | |
| const char INDEX_HTML[] = | |
| "<!DOCTYPE HTML>" | |
| "<html>" | |
| "<head>" | |
| "<meta name = \"viewport\" content = \"width = device-width, initial-scale = 1.0, maximum-scale = 1.0, user-scalable=0\">" | |
| "<title>Dingus</title>" | |
| "<style>" | |
| "html { background-color: #fff;}" | |
| "body { background-color: #efefef; font-family: Arial, Helvetica, Sans-Serif; color: #000000; width: 80%; max-width: 900px; margin: 0 auto; padding: 2em; }" | |
| "h1 { text-align: center;}" | |
| "</style>" | |
| "</head>" | |
| "<body>" | |
| "<h1>Hello Dingus!</h1>" | |
| "<FORM action=\"/\" method=\"post\">" | |
| "<P>" | |
| "<h2>LED</h2>" | |
| "<INPUT type=\"radio\" name=\"LED\" value=\"1\">On<BR>" | |
| "<INPUT type=\"radio\" name=\"LED\" value=\"0\">Off<BR>" | |
| "<INPUT type=\"submit\" value=\"Send\"> <INPUT type=\"reset\">" | |
| "</P>" | |
| "</FORM>" | |
| "</body>" | |
| "</html>"; | |
| void handleRoot() { | |
| digitalWrite(statusLed, 1); | |
| if (server.hasArg("LED")) { | |
| handleSubmit(); | |
| } | |
| else { | |
| server.send(200, "text/html", INDEX_HTML); | |
| } | |
| digitalWrite(statusLed, 0); | |
| } | |
| void handleSubmit() { | |
| String LEDvalue; | |
| if (!server.hasArg("LED")) return returnFail("BAD ARGS"); | |
| LEDvalue = server.arg("LED"); | |
| if (LEDvalue != "1" && LEDvalue != "0") { | |
| returnFail("Bad LED value"); | |
| } | |
| if (LEDvalue == "1" && lastLightState != HIGH) { | |
| writeLED(true); | |
| server.send(200, "text/html", INDEX_HTML); | |
| } else if (LEDvalue == "0" && lastLightState != LOW) { | |
| writeLED(false); | |
| server.send(200, "text/html", INDEX_HTML); | |
| } | |
| // refresh the page, but don't change the light | |
| server.send(200, "text/html", INDEX_HTML); | |
| } | |
| void returnFail(String msg) { | |
| server.sendHeader("Connection", "close"); | |
| server.sendHeader("Access-Control-Allow-Origin", "*"); | |
| server.send(500, "text/plain", msg + "\r\n"); | |
| } | |
| void returnOK() { | |
| server.sendHeader("Connection", "close"); | |
| server.sendHeader("Access-Control-Allow-Origin", "*"); | |
| server.send(200, "text/plain", "OK\r\n"); | |
| } | |
| void writeLED(bool LEDon) { | |
| // Note inverted logic for Adafruit HUZZAH board | |
| if (LEDon) { | |
| lightState = HIGH; | |
| digitalWrite(stateLed, 0); | |
| } else { | |
| lightState = LOW; | |
| digitalWrite(stateLed, 1); | |
| } | |
| } | |
| void handleNotFound(){ | |
| digitalWrite(statusLed, 1); | |
| String message = "File Not Found\n\n"; | |
| message += "URI: "; | |
| message += server.uri(); | |
| message += "\nMethod: "; | |
| message += (server.method() == HTTP_GET)?"GET":"POST"; | |
| message += "\nArguments: "; | |
| message += server.args(); | |
| message += "\n"; | |
| for (uint8_t i=0; i<server.args(); i++){ | |
| message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; | |
| } | |
| server.send(404, "text/plain", message); | |
| digitalWrite(statusLed, 0); | |
| } | |
| void setup(void){ | |
| pinMode(statusLed, OUTPUT); | |
| Serial.begin(115200); | |
| WiFiManager wifiManager; | |
| Serial.println("chipID: " + String(ESP.getChipId())); | |
| wifiManager.autoConnect("AutoConnectAP"); | |
| Serial.println(""); | |
| pinMode(stateLed, OUTPUT); // Use Built-In LED for Indication | |
| /* INPUT_PULLUP enables the Arduino Internal Pull-Up Resistor */ | |
| pinMode(12, INPUT_PULLUP); | |
| // Wait for connection | |
| while (WiFi.status() != WL_CONNECTED) { | |
| delay(500); | |
| Serial.print("."); | |
| } | |
| Serial.println(""); | |
| Serial.print("IP address: "); | |
| Serial.println(WiFi.localIP()); | |
| if (MDNS.begin("esp8266")) { | |
| Serial.println("MDNS responder started"); | |
| } | |
| server.on("/", handleRoot); | |
| server.on("/inline", [](){ | |
| server.send(200, "text/plain", "this works as well"); | |
| }); | |
| server.onNotFound(handleNotFound); | |
| server.begin(); | |
| Serial.println("HTTP server started"); | |
| // Setup MQTT subscription for onoff feed. | |
| mqtt.subscribe(&onoffbutton); | |
| } | |
| void loop(void){ | |
| MQTT_connect(); | |
| // this is our 'wait for incoming subscription packets' busy subloop | |
| // try to spend your time here | |
| Adafruit_MQTT_Subscribe *subscription; | |
| while ((subscription = mqtt.readSubscription(5000))) { | |
| if (subscription == &onoffbutton) { | |
| Serial.print(F("Got: ")); | |
| Serial.println((char *)onoffbutton.lastread); | |
| } | |
| } | |
| bool buttonState = digitalRead(12); // store current state of pin 12 | |
| if (buttonState != lastButtonState) { | |
| Serial.print(F("\nBottonState has changed.")); | |
| if (buttonState == LOW) { | |
| Serial.print("Button was pressed, toggle light."); | |
| lightState = !lightState; | |
| } | |
| // Now we can publish stuff! | |
| Serial.print(F("\nSending button state val ")); | |
| Serial.print(buttonState); | |
| Serial.print("..."); | |
| Serial.print(F("\nSending light state val ")); | |
| Serial.print(lightState); | |
| if (! button.publish(buttonState)) { | |
| Serial.println(F("Failed")); | |
| } else { | |
| Serial.println(F("OK!")); | |
| } | |
| if (lightState != lastLightState){ | |
| if (! light.publish(lightState)) { | |
| Serial.println(F("Failed")); | |
| } else { | |
| Serial.println(F("OK!")); | |
| } | |
| } | |
| delay(50); | |
| } | |
| lastButtonState = buttonState; | |
| lastLightState = lightState; | |
| digitalWrite(15, lightState); | |
| server.handleClient(); | |
| } | |
| // 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!"); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment