Last active
January 29, 2016 13:08
-
-
Save Robotto/2d772ab6297a11b721d8 to your computer and use it in GitHub Desktop.
This file contains 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
/* | |
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