diff --git a/README.md b/README.md index befbb2e..98bceaa 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,26 @@ # Esp8266-Laser Wifi Host for the Arduino-Laser-Spirograph -HTTP GET endpoints: - /motor/{motorNr}/{value} - /laser/{value} - /saveconf -> write wificonfig to file - /resetwifi -> reconnect wifi with the new settings - /wificonfig -> GET returns wifi settings - POST sets new wifi settings - apMode=0: will try to connect to SSID first, 1: will directly start the AP - SSID=ssid - password=password - save=true will save config to spiffs - apply=true will reset wifi and try to connect with new param (buggy atm) - /readvalues -> return laser and motor values (all 0 at startup, ram only) +HTTP endpoints: + /spirograph GET returns laser and motor values (0 at startup) + POST sets new value(s) + laser=1-128 (1:permanent, 2-127 pulse, 128 off) + motor1=1-128 + motor2=1-128 + motor3=1-128 + + + /wificonfig -> GET returns wifi settings + POST sets new wifi setting{s} + apMode=0: will try to connect to SSID first, 1: will directly start the AP + SSID=ssid + password=password + save=true will save config to spiffs, false will only change RAM variable (useful for onetime ap joins) + apply=true will reset wifi and try to connect with new param (buggy atm) + /saveconf -> POST write wificonfig to file (similar to wificonfig->save=true) + /resetwifi -> POST reconnect wifi (similar to wificonfig->apply=true) + /heap -> GET returns free heap of the ESP8266 + /files -> GET returns list of files # Install - install arduino ide (1.8.5) diff --git a/esp8266-laser.ino b/esp8266-laser.ino index 93b2771..04cd5eb 100644 --- a/esp8266-laser.ino +++ b/esp8266-laser.ino @@ -1,5 +1,6 @@ /* https://github.com/0x1d/esp8266-laser + 0x1d, FrYakaTKoP */ @@ -16,7 +17,7 @@ */ // Set how long the esp should try to connect to a network before starting it's own AP -int wifiTimeout = 15000; //ms +unsigned int wifiTimeout = 15000; //ms // Hardcoded Soft AP network parameters char *ssidAP = "laserAp"; @@ -24,9 +25,9 @@ IPAddress apIP(192, 168, 4, 1); IPAddress netMsk(255, 255, 255, 0); // this is sent to server if invalid request -const char *metaRefreshStr = "
redirecting...
"; +const char *metaRefreshStr = "redirecting...
"; -/* hostname for mDNS. Should work at least on windows. Try http://esp8266.local */ +/* hostname for mDNS. Should work at least on windows. Try http://esplaser.local */ const char *myHostname = "esplaser"; // espsoftwareserial @@ -43,7 +44,7 @@ String password = ""; int apMode = 1; // default value, will be overwriten with config from file int _apMode = 0; // runtime apMode -// [0] laser[1] m1 [2] m2 [3] m3 +// [0] laser, [1] m1, [2] m2, [3] m3 byte lmValues[4] = {0, 0, 0, 0}; unsigned long previousMillis = 0; @@ -51,18 +52,20 @@ unsigned long previousMillis = 0; // Web server ESP8266WebServer server(80); - -//format bytes -String formatBytes(size_t bytes) { - if (bytes < 1024) { - return String(bytes) + "B"; - } else if (bytes < (1024 * 1024)) { - return String(bytes / 1024.0) + "KB"; - } else if (bytes < (1024 * 1024 * 1024)) { - return String(bytes / 1024.0 / 1024.0) + "MB"; - } else { - return String(bytes / 1024.0 / 1024.0 / 1024.0) + "GB"; +bool hFileRead(String path) { + //Serial.println("handleFileRead: " + path); + if (path.endsWith("/")) path += "index.html"; + String contentType = getContentType(path); + String pathWithGz = path + ".gz"; + if (SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)) { + if (SPIFFS.exists(pathWithGz)) + path += ".gz"; + File file = SPIFFS.open(path, "r"); + size_t sent = server.streamFile(file, contentType); + file.close(); + return true; } + return false; } String getContentType(String filename) { @@ -83,114 +86,83 @@ String getContentType(String filename) { return "text/plain"; } -bool handleFileRead(String path) { - Serial.println("handleFileRead: " + path); - if (path.endsWith("/")) path += "index.html"; - String contentType = getContentType(path); - String pathWithGz = path + ".gz"; - if (SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)) { - if (SPIFFS.exists(pathWithGz)) - path += ".gz"; - File file = SPIFFS.open(path, "r"); - size_t sent = server.streamFile(file, contentType); - file.close(); - return true; - } - return false; -} +void hFileList() { + String responseBuffer = String(); + StaticJsonBuffer<500> jsonBuffer; + JsonObject& root = jsonBuffer.createObject(); + JsonArray& files = root.createNestedArray("files"); -void handleFileList() { - if (!server.hasArg("dir")) { - server.send(500, "text/plain", "BAD ARGS"); - return; - } + Dir dir = SPIFFS.openDir("/"); - String path = server.arg("dir"); - Serial.println("handleFileList: " + path); - Dir dir = SPIFFS.openDir(path); - path = String(); - - String output = "["; while (dir.next()) { File entry = dir.openFile("r"); - if (output != "[") output += ','; - bool isDir = false; - output += "{\"type\":\""; - output += (isDir) ? "dir" : "file"; - output += "\",\"name\":\""; - output += String(entry.name()).substring(1); - output += "\"}"; + files.add(String(entry.name())); entry.close(); } - - output += "]"; - server.send(200, "text/json", output); + root.prettyPrintTo(responseBuffer); + server.send(200, "text/json", responseBuffer); + jsonBuffer.clear(); + responseBuffer = String(); } -void handleLaser(String uri) +void hReadSpiro() { - String laserValue = uri.substring(7); - if (laserValue.toInt() > 128) { - lmValues[0] = 128; - laserValue = "128"; - } - else - { - lmValues[0] = laserValue.toInt(); - } - - String msg = "AT SLV "; - msg += laserValue; - - Serial.println("Sent to Laser: " + msg); - laserSerial.println(msg); - - String json = "{ \"handledLaser\":"; - json += "{\"value\":\"" + laserValue + "\"}}"; - - //server.send(200, "text/plain", "blub"); - server.send(200, "text/json", json); - json = String(); + String responseBuffer = String(); + StaticJsonBuffer<200> jsonBuffer; + JsonObject& root = jsonBuffer.createObject(); + JsonObject& data = root.createNestedObject("spirograph"); + data["laser"] = (String)lmValues[0]; + data["motor1"] = (String)lmValues[1]; + data["motor2"] = (String)lmValues[2]; + data["motor3"] = (String)lmValues[3]; + root.prettyPrintTo(responseBuffer); + server.send(200, "text/json", responseBuffer); + jsonBuffer.clear(); + responseBuffer = String(); } -void handleMotor(String uri) +void hWriteSpiro() { - String motorNr = uri.substring(7, 8); - String motorValue = uri.substring(9); - if (motorValue.toInt() > 128) { - lmValues[motorNr.toInt()] = 128; - motorValue = "128"; + String responseBuffer = String(); + StaticJsonBuffer<200> jsonBuffer; + JsonObject& root = jsonBuffer.createObject(); + JsonObject& data = root.createNestedObject("wificonfig"); + if (server.hasArg("laser") ) { + lmValues[0] = server.arg("laser").toInt(); + data["laser"] = (String)lmValues[0]; + String msg = "AT SLV "; + msg += (String)lmValues[0]; + laserSerial.println(msg); + delay(20); } - else - { - lmValues[motorNr.toInt()] = motorValue.toInt(); + if (server.hasArg("motor1") ) { + lmValues[1] = server.arg("motor1").toInt(); + data["motor1"] = (String)lmValues[1]; + String msg = "AT SMS 1 "; + msg += (String)lmValues[1]; + laserSerial.println(msg); + delay(20); } - String msg = "AT SMS "; - msg += motorNr; - msg += " "; - msg += motorValue; - - Serial.println("Sent to Laser: " + msg); - laserSerial.println(msg); - - String json = "{ \"handledMotor\": "; - json += "{ \"motor\":\"" + motorNr + "\", "; - json += "\"value\":\"" + motorValue + "\" }}"; - - //server.send(200, "text/plain", "blub"); - server.send(200, "text/json", json); - json = String(); -} - -void handleReadValues() -{ - String json = "{ \"handledReadValues\":"; - json += "{\"laser\":\"" + (String)lmValues[0] + "\","; - json += "\"motors\": {\"1\":\"" + (String)lmValues[1] + "\","; - json += "\"2\":\"" + (String)lmValues[2] + "\","; - json += "\"3\":\"" + (String)lmValues[3] + "\"}}}"; - server.send(200, "text/json", json); - json = String(); + if (server.hasArg("motor2") ) { + lmValues[2] = server.arg("motor2").toInt(); + data["motor2"] = (String)lmValues[2]; + String msg = "AT SMS 2 "; + msg += (String)lmValues[2]; + laserSerial.println(msg); + delay(20); + } + if (server.hasArg("motor3") ) { + lmValues[3] = server.arg("motor3").toInt(); + data["motor3"] = (String)lmValues[3]; + String msg = "AT SMS 3 "; + msg += (String)lmValues[3]; + laserSerial.println(msg); + delay(20); + } + root.prettyPrintTo(responseBuffer); + server.send(200, "text/json", responseBuffer); + jsonBuffer.clear(); + responseBuffer = String(); } void hReadWifi() @@ -256,8 +228,6 @@ void hWriteWifi() responseBuffer = String(); } - - bool saveConfigFile() { StaticJsonBuffer<200> jsonBuffer; JsonObject& json = jsonBuffer.createObject(); @@ -267,14 +237,14 @@ bool saveConfigFile() { File configFile = SPIFFS.open("/wifi.json", "w"); if (!configFile) { - Serial.println("Failed to open config file for writing"); + //Serial.println("Failed to open config file for writing"); return false; } json.printTo(configFile); return true; } -void handleSaveConf() { +void hSaveConf() { bool success = saveConfigFile(); if (success) { @@ -319,12 +289,25 @@ boolean readConfigFile() { Serial.print("SSID: "); Serial.println(ssid); Serial.print("PW: "); - Serial.println(password); + Serial.println("***"); + //Serial.println(password); return true; } -boolean setupWifi() { - Serial.print("setupWifi apMode="); +void setupWifi() +{ + WiFi.disconnect(); + delay(100); + if (!connectWifi()) + { + Serial.println("connect failed, start SoftAP"); + _apMode = 1; // fallback to AP mode + connectWifi(); + } +} + +boolean connectWifi() { + Serial.print("connectWifi apMode="); Serial.println(apMode); if (_apMode == 0) { @@ -372,28 +355,22 @@ void setup(void) { // while (dir.next()) { // String fileName = dir.fileName(); // size_t fileSize = dir.fileSize(); - // Serial.printf("FS File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str()); + // Serial.printf("FS File: %s\n", fileName.c_str()); // } // Serial.printf("\n"); // } - //WIFI INIT - WiFi.disconnect(); - delay(100); + + if (!readConfigFile()) { Serial.println("reading wifi config failed, start SoftAP"); _apMode = 1; } delay(100); - - if (!setupWifi()) - { - Serial.println("connect failed, start SoftAP"); - _apMode = 1; // fallback to AP mode - setupWifi(); - } - + + setupWifi(); + // Setup MDNS responder if (!MDNS.begin(myHostname)) { Serial.println("Error setting up MDNS responder!"); @@ -406,23 +383,36 @@ void setup(void) { //SERVER INIT //list directory - server.on("/listFiles", HTTP_GET, handleFileList); - server.on("/saveconf", HTTP_GET, handleSaveConf); - server.on("/resetwifi", HTTP_GET, setupWifi); + server.on("/files", HTTP_GET, hFileList); + server.on("/files", HTTP_POST, []() { + server.send(400, "text/plain", "400 Bad Request"); + }); + server.on("/saveconf", HTTP_GET, []() { + server.send(400, "text/plain", "400 Bad Request"); + }); + server.on("/saveconf", HTTP_POST, hSaveConf); + + server.on("/resetwifi", HTTP_GET, []() { + server.send(400, "text/plain", "400 Bad Request"); + }); + server.on("/resetwifi", HTTP_POST, setupWifi); server.on("/wificonfig", HTTP_GET, hReadWifi); server.on("/wificonfig", HTTP_POST, hWriteWifi); - // server.on("/wificonfig", HTTP_POST, []() { - // hWriteWifi(); - // }); - server.on("/readvalues", HTTP_GET, handleReadValues); + + server.on("/spirograph", HTTP_GET, hReadSpiro); + server.on("/spirograph", HTTP_POST, hWriteSpiro); + server.on("/heap", HTTP_GET, []() { String json = "{"; json += "\"heap\":" + String(ESP.getFreeHeap()); json += "}"; server.send(200, "text/json", json); json = String(); + }); + server.on("/heap", HTTP_POST, []() { + server.send(400, "text/plain", "400 Bad Request"); }); server.onNotFound(handleNotFound); server.begin(); @@ -431,24 +421,14 @@ void setup(void) { void handleNotFound() { String uri = server.uri(); - Serial.print("unhandled uri:"); - Serial.println(uri); - if (uri.substring(0, 7) == "/motor/") - { - handleMotor(uri); - return; - } - if (uri.substring(0, 7) == "/laser/") - { - handleLaser(uri); - return; - } + //Serial.print("unhandled uri:"); + //Serial.println(uri); if (uri.substring(0, 12) == "/wifi.json") { server.send(403, "text/plain", "Forbidden"); return; } - if (!handleFileRead(server.uri())) + if (!hFileRead(server.uri())) { server.send(404, "text/html", metaRefreshStr); // server.send(302, "text/plain", "blub");