Skip to content

Instantly share code, notes, and snippets.

@Robotto
Last active January 29, 2016 13:08
Show Gist options
  • Save Robotto/2d772ab6297a11b721d8 to your computer and use it in GitHub Desktop.
Save Robotto/2d772ab6297a11b721d8 to your computer and use it in GitHub Desktop.
/*
This code runs on an ESP8266 wifi module, compiled/programmed through the Arduino IDE.
The specific hardware in this case is a NodeMCU v0.9 module
The ESP hosts a webserver on port 80, with event listeners for access on / , /unlock, and /buzzToggle,
it also listens on UPD port 1337 for the (newline terminated) string "SESAME"
it broadcasts itself as "door" on Mdns, so that devices on LAN can access it via http://door.local (unless it's an android device, because fuck that.)
Hand coded http response and body are in the handleroot() function.
Door unlock and buzzer toggle is physically handled with solidstate relays, so all this code needs to do is toggle I/O pins
*/
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
//Function declarations:
void handleRoot();
void handleUnlock();
void handleBuzzerToggle();
void handleNotFound();
void errorLoop();
void UDPrx();
void unlock();
void wifiCheck();
//WIFI SETTINGS:
const char* ssid = "pretty13face37hacker";
const char* password = "ThisIsntTheRealCodeYouSexyHackerYou";
// Initialize the wifi Udp library
WiFiUDP Udp;
//init http server on port 80:
ESP8266WebServer server(80);
//hardware stuff:
const unsigned int buzzerPin = D1;
const unsigned int lockPin = D2;
const unsigned int unlockDuration=3000;
bool buzzerState=true;
//UDP stuff:
const unsigned int localPort = 1337; // local port to listen for UDP packets
const int NTP_PACKET_SIZE = 16; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE ]; //buffer to hold incoming and outgoing packets
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
pinMode(buzzerPin,OUTPUT);
pinMode(lockPin,OUTPUT);
digitalWrite(buzzerPin,buzzerState);
digitalWrite(lockPin,LOW);
delay(500);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
String ipString=String(WiFi.localIP()[0]) + "." + String(WiFi.localIP()[1]) + "." + String(WiFi.localIP()[2]) + "." + String(WiFi.localIP()[3]);
Serial.print("WiFi up!");
Serial.print(" IPv4: ");
Serial.println(ipString);
if (MDNS.begin("door")) {
Serial.println("MDNS responder started");
}
server.on("/", handleRoot);
server.on("/unlock", handleUnlock);
server.on("/buzzToggle", handleBuzzerToggle);
server.onNotFound(handleNotFound);
server.begin();
Serial.println("HTTP server started");
Udp.begin(localPort);
}
void loop() {
wifiCheck();
if (Udp.parsePacket()) UDPrx();
server.handleClient();
yield();
//delay(500);
}
//http stuff:
void handleRoot() {
Serial.println("client trying to access /");
//server.send(200, "text/plain", "hello from esp8266!");
//server.sendContent("\r\n");
server.sendContent("HTTP/1.1 200 OK\r\n"); //send new p\r\nage
server.sendContent("Content-Type: text/html\r\n");
server.sendContent("\r\n");
server.sendContent("<HTML>\r\n");
server.sendContent("<HEAD>\r\n");
server.sendContent("<meta name='apple-mobile-web-app-capable' content='yes' />\r\n");
server.sendContent("<meta name='apple-mobile-web-app-status-bar-style' content='black-translucent' />\r\n");
server.sendContent("<link rel='stylesheet' type='text/css' href='https://moore.dk/doorcss.css' />\r\n");
server.sendContent("<TITLE>Open Sesame.</TITLE>\r\n");
server.sendContent("</HEAD>\r\n");
server.sendContent("<BODY>\r\n");
server.sendContent("<H1>doorlock</H1>\r\n");
server.sendContent("<hr />\r\n");
server.sendContent("<br />\r\n");
if(buzzerState) server.sendContent("<H2>Buzzer is enabled</H2>\r\n");
else server.sendContent("<H2>Buzzer is disabled</H2>\r\n");
server.sendContent("<br />\r\n");
if(buzzerState) server.sendContent("<a class=\"red\" href=\"/buzzToggle\"\">Disable Buzzer</a>\r\n");
else server.sendContent("<a href=\"/buzzToggle\"\">Enable Buzzzer</a><br />\r\n");
server.sendContent("<br />\r\n");
server.sendContent("<br />\r\n");
server.sendContent("<br />\r\n");
server.sendContent("<a href=\"/unlock\"\">Unlock for 3 seconds...</a>\r\n");
server.sendContent("<br />\r\n");
server.sendContent("</BODY>\r\n");
server.sendContent("</HTML>\r\n");
}
void handleUnlock(){
Serial.println("unlocking..");
handleRoot();
unlock();
}
void handleBuzzerToggle(){
buzzerState=!buzzerState;
handleRoot();
if(buzzerState) Serial.println("buzzer on..");
else Serial.println("buzzer off..");
digitalWrite(buzzerPin,buzzerState);
}
void handleNotFound(){
Serial.println("client getting 404");
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);
}
void errorLoop()
{
unsigned long currentEpoch,epochAtError=millis();
unsigned long lastmillis=0;
while(1)
{
while(millis()<lastmillis+1000) yield(); //WAIT FOR ABOUT A SECOND
currentEpoch+=((millis()-lastmillis)/1000); //add a second or more to the current epoch
lastmillis=millis();
if (currentEpoch>epochAtError+300) ESP.reset(); //reset after 5 minutes
}
}
void UDPrx()
{
// We've received a packet, read the data from it
Serial.println("udpRX!");
memset(packetBuffer, 0, NTP_PACKET_SIZE); //reset packet buffer
int read_bytes=Udp.read(packetBuffer,NTP_PACKET_SIZE); // read the packet into the buffer
if (packetBuffer[0]=='S' &&
packetBuffer[1]=='E' &&
packetBuffer[2]=='S' &&
packetBuffer[3]=='A' &&
packetBuffer[4]=='M' &&
packetBuffer[5]=='E')
{
unlock();
}
else Serial.println("UDP Parsing failed.");
}
void unlock(){
Serial.println("open!");
digitalWrite(lockPin,HIGH);
delay(unlockDuration);
digitalWrite(lockPin,LOW);
Serial.println("close..");
Serial.println();
}
void wifiCheck()
{
if(WiFi.status() != WL_CONNECTED)
{
int tickCount=0;
Serial.println("Wifi dropped. Retry in 30 seconds.");
delay(30000);
Serial.println("Connecting");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println(".");
tickCount++;
if(tickCount>100)
{
Serial.println("ded...");
errorLoop();
}
}
Serial.println("Connected!");
//if connectivity has been restored, reset state?
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment