Skip to content

Instantly share code, notes, and snippets.

@RyanParsley
Last active March 19, 2018 21:11
Show Gist options
  • Select an option

  • Save RyanParsley/9b7bcf68cc691d94cd7bce34766cc6f3 to your computer and use it in GitHub Desktop.

Select an option

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.
#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