diff --git a/readme.md b/readme.md index 2186d953..93666cde 100644 --- a/readme.md +++ b/readme.md @@ -16,3 +16,67 @@ Additions for V0.3 (nearly complete!) - Support for power pushbutton - Full OTA software update capability - Password protected OTA page for added security (OTA lock) + +Compile settings: +Board: WeMos D1 mini +CPU frequency: 80 MHz +Flash size : 4MB (1MB settings) +Upload speed: 115200 + + +Quick start guide: + +1. Make sure your ESP module has a min. 4MB SPI flash module. (currently working on supporting 1MB modules) +Connect a WS2812B RGB led strip to GPIO2. Optionally connect a NO-pushbutton to GPIO0 (internal pull-up) and ground. + +2. Follow a guide to setup your Arduino client (I am using version 1.6.9) with the ESP8266 libraries. +For current compiles I use an old version from 15th August 2016. + +3. You will also need the ESP8266 SPIFFS sketch data uploader. (currently working on making this step unnecessary) + +4. In file "wled00.ino", change the LED count to the amount you connected. Proceed to flash the sketch and the SPIFFS data. +You should also change the access point and OTA update passphrases for added security (you can change them later, this is just the "factory default"). + +5. Connect to automatically started WiFi access point "WLED-AP" using default passwort "wled1234". Go to the IP "192.168.4.1". + +6. Click on the wrench icon to edit settings like connecting the module to your home WiFi. + +7. Have fun with the software! + + +Advanced module control via HTTP requests: + +Base URL scheme: "/ajax_in". This will return a XML file with some current values. +Add one or multiple of the following parameters after the base url to change values: +"&A=<0-255>" set LED brightness (yellow slider) +"&R=<0-255>" set LED red value (red slider) +"&G=<0-255>" set LED green value (green slider) +"&B=<0-255>" set LED blue value (blue slider) +"&FX=<0-47>" set LED effect (refer to WS2812FX library) +"&SX=<0-255>" set LED effect speed (refer to WS2812FX library) +"&NR=<0 or 1>" receive notifications on or off +"&NS=<0 or 1>" send (direct) notifications on or off +"&NL=<0 or 1>" turns nightlight function on or off +("&OL=<0, 1, 3 or 5>" experimental clock overlays) +("&I=<0-255>" experimental individual LED control) +("&I=<0-255>&I2=<0-255>" experimental individual LED range control) + + +Software update procedure: + +Method 1: Reflash the new update source via USB. + +Method 2: The software has an integrated OTA software update capability. +First you have to enable it by typing in the correct OTA passphrase (default: "wledota") in the settings menu. +Remove the tick in the checkbox "OTA locked". Then save settings and reboot the ESP. +Now you can go to "/update" to update binary firmware. +To edit flash content (images and HTML), go to "/edit". +After you are done, it is recommended to lock the OTA function again. +To do so, tick the checkbox again (you can change the passphrase by typing in a new one now). Reboot. +If you try to access the update page now, you should see the message "OTA lock active". + + + + + + diff --git a/wled00/data/settings.htm b/wled00/data/settings.htm index 6e120863..2961b750 100644 --- a/wled00/data/settings.htm +++ b/wled00/data/settings.htm @@ -139,6 +139,8 @@ Send notifications on button press:
Send nightlight notifications:

Time

+ Warning! Using NTP usually results in a complete system crash after 1-48 hours.
+ Please only enable it if you are willing to experiment with it.

Get time from NTP server:
Current local time is unknown

Security

@@ -156,7 +158,12 @@ HTTP traffic is not encrypted. An attacker in the same network could intercept form data!

About

WLED version 0.3pd
- (c) 2016 Christian Schwinne
+ (c) 2016-2017 Christian Schwinne
+ Licensed under the MIT license
+ Uses libraries:
+ ESP8266 Arduino Core
+ WS2812FX by kitesurfer1404 (Aircoookie fork)
+ Timezone library by JChristensen
Server message: XML response error!

diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 6472a3bc..79c44fb6 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -16,15 +16,32 @@ #include #include +//to toggle usb serial debug (un)comment following line +#define DEBUG + +#ifdef DEBUG + #define DEBUG_PRINT(x) Serial.print (x) + #define DEBUG_PRINTLN(x) Serial.println (x) + #define DEBUG_PRINTF(x) Serial.printf (x) +#else + #define DEBUG_PRINT(x) + #define DEBUG_PRINTLN(x) + #define DEBUG_PRINTF(x) +#endif + /* * @title WLED project sketch * @version 0.3pd * @author Christian Schwinne */ //Hardware-settings (only changeble via code) -uint8_t led_amount = 10; +uint8_t led_amount = 84; uint8_t buttonPin = 0; //needs pull-up +//AP and OTA default passwords (change them!) +String appass = "wled1234"; +String otapass = "wledota"; + TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120}; //Central European Summer Time TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60}; //Central European Standard Time Timezone TZ(CEST, CET); @@ -37,7 +54,6 @@ String clientssid = "Your_Network_Here"; String clientpass = "Dummy_Pass"; String cmdns = "led"; String apssid = "WLED-AP"; -String appass = "wled1234"; uint8_t apchannel = 1; uint8_t aphide = 0; boolean useap = true; @@ -51,7 +67,6 @@ boolean fadeTransition = true; boolean seqTransition = false; uint16_t transitionDelay = 1500; boolean ota_lock = true; -String otapass = "wledota"; boolean only_ap = false; boolean buttonEnabled = true; boolean notifyDirect = true, notifyButton = true, notifyNightlight = false, notifyMaster = true; @@ -62,15 +77,15 @@ boolean nightlightFade = true; uint16_t udpPort = 21324; uint8_t effectDefault = 0; uint8_t effectSpeedDefault = 75; -boolean ntpEnabled = true; +boolean ntpEnabled = false; const char* ntpServerName = "time.nist.gov"; -long ntpRetryMs = 12000; -long ntpResyncMs = 72000000; +long ntpRetryMs = 9600; +long ntpResyncMs = 72000000L; int overlayMin = 0, overlayMax = 9; int analogClock12pixel = 25; boolean analogClockSecondsTrail = false; boolean analogClock5MinuteMarks = true; -boolean nixieClockDisplaySeconds = true; +boolean nixieClockDisplaySeconds = false; boolean nixieClock12HourFormat = false; boolean overlayReverse = true; uint8_t overlaySpeed = 200; @@ -107,7 +122,7 @@ boolean ntpConnected = false; boolean ntpSyncNeeded = true; boolean ntpPacketSent = false; long ntpPacketSentTime, ntpSyncTime; -uint8_t overlayCurrent = 5; +uint8_t overlayCurrent = 0; long overlayRefreshMs = 200; long overlayRefreshedTime; int overlayArr[6]; @@ -126,11 +141,17 @@ WS2812FX strip = WS2812FX(led_amount, 2, NEO_GRB + NEO_KHZ800); File fsUploadFile; +#ifdef DEBUG +int debugIndex = 0; +int lastWifiState = 3; +long wifiStateChangedTime = 0; +#endif + void down() { bri_t = 0; setAllLeds(); - Serial.println("MODULE TERMINATED"); + DEBUG_PRINTLN("MODULE TERMINATED"); while (1) {delay(1000);} } @@ -138,7 +159,7 @@ void reset() { bri_t = 0; setAllLeds(); - Serial.println("MODULE RESET"); + DEBUG_PRINTLN("MODULE RESET"); ESP.reset(); } @@ -161,6 +182,27 @@ void loop() { handleNetworkTime(); handleOverlays(); strip.service(); + + //DEBUG + #ifdef DEBUG + debugIndex ++; + if (debugIndex > 99999) + { + debugIndex = 0; + DEBUG_PRINTLN("---MODULE DEBUG INFO---"); + DEBUG_PRINT("Runtime: "); DEBUG_PRINTLN(millis()); + DEBUG_PRINT("Unix time: "); DEBUG_PRINTLN(now()); + DEBUG_PRINT("Wifi state: "); DEBUG_PRINTLN(WiFi.status()); + if (WiFi.status() != lastWifiState) + { + wifiStateChangedTime = millis(); + } + lastWifiState = WiFi.status(); + DEBUG_PRINT("Wifi state: "); DEBUG_PRINTLN(wifiStateChangedTime); + DEBUG_PRINT("NTP sync needed: "); DEBUG_PRINTLN(ntpSyncNeeded); + DEBUG_PRINT("Client IP: "); DEBUG_PRINTLN(WiFi.localIP()); + } + #endif } diff --git a/wled00/wled02_xml.ino b/wled00/wled02_xml.ino index 12ce0436..c7af90c1 100644 --- a/wled00/wled02_xml.ino +++ b/wled00/wled02_xml.ino @@ -48,7 +48,7 @@ void XML_response() void XML_response_settings() { - Serial.println("XML settings response"); + DEBUG_PRINTLN("XML settings response"); String resp; resp = resp + ""; resp = resp + ""; @@ -148,11 +148,11 @@ void XML_response_settings() resp = resp + ""; resp = resp + bool2int(ntpEnabled); resp = resp + ""; - Serial.println("pretime"); + DEBUG_PRINTLN("pretime"); resp = resp + ""; resp = resp + getTimeString(); resp = resp + ""; - Serial.println("posttime"); + DEBUG_PRINTLN("posttime"); resp = resp + ""; resp = resp + bool2int(ota_lock); resp = resp +""; @@ -188,6 +188,6 @@ void XML_response_settings() resp = resp + ""; resp = resp + "WLED 0.3pd OK"; resp = resp + ""; - Serial.println(resp); + DEBUG_PRINTLN(resp); server.send(200, "text/xml", resp); } diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino index 4ba134be..8d99086e 100644 --- a/wled00/wled03_set.ino +++ b/wled00/wled03_set.ino @@ -9,7 +9,7 @@ void handleSettingsSet() { if (!server.arg("CPASS").indexOf('*') == 0) { - Serial.println("Setting pass"); + DEBUG_PRINTLN("Setting pass"); clientpass = server.arg("CPASS"); } } diff --git a/wled00/wled04_file.ino b/wled00/wled04_file.ino index 9dee4f7c..2b4b704c 100644 --- a/wled00/wled04_file.ino +++ b/wled00/wled04_file.ino @@ -32,7 +32,7 @@ String getContentType(String filename){ } bool handleFileRead(String path){ - Serial.println("handleFileRead: " + path); + DEBUG_PRINTLN("handleFileRead: " + path); if(path.endsWith("/")) path += "index.htm"; String contentType = getContentType(path); String pathWithGz = path + ".gz"; @@ -53,24 +53,24 @@ void handleFileUpload(){ if(upload.status == UPLOAD_FILE_START){ String filename = upload.filename; if(!filename.startsWith("/")) filename = "/"+filename; - Serial.print("handleFileUpload Name: "); Serial.println(filename); + DEBUG_PRINT("handleFileUpload Name: "); DEBUG_PRINTLN(filename); fsUploadFile = SPIFFS.open(filename, "w"); filename = String(); } else if(upload.status == UPLOAD_FILE_WRITE){ - //Serial.print("handleFileUpload Data: "); Serial.println(upload.currentSize); + //DEBUG_PRINT("handleFileUpload Data: "); DEBUG_PRINTLN(upload.currentSize); if(fsUploadFile) fsUploadFile.write(upload.buf, upload.currentSize); } else if(upload.status == UPLOAD_FILE_END){ if(fsUploadFile) fsUploadFile.close(); - Serial.print("handleFileUpload Size: "); Serial.println(upload.totalSize); + DEBUG_PRINT("handleFileUpload Size: "); DEBUG_PRINTLN(upload.totalSize); } } void handleFileDelete(){ if(server.args() == 0) return server.send(500, "text/plain", "BAD ARGS"); String path = server.arg(0); - Serial.println("handleFileDelete: " + path); + DEBUG_PRINTLN("handleFileDelete: " + path); if(path == "/") return server.send(500, "text/plain", "BAD PATH"); if(!SPIFFS.exists(path)) @@ -84,7 +84,7 @@ void handleFileList() { if(!server.hasArg("dir")) {server.send(500, "text/plain", "BAD ARGS"); return;} String path = server.arg("dir"); - Serial.println("handleFileList: " + path); + DEBUG_PRINTLN("handleFileList: " + path); Dir dir = SPIFFS.openDir(path); path = String(); @@ -109,7 +109,7 @@ void handleFileCreate(){ if(server.args() == 0) return server.send(500, "text/plain", "BAD ARGS"); String path = server.arg(0); - Serial.println("handleFileCreate: " + path); + DEBUG_PRINTLN("handleFileCreate: " + path); if(path == "/") return server.send(500, "text/plain", "BAD PATH"); if(SPIFFS.exists(path)) diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino index ef79516c..313eb6cb 100644 --- a/wled00/wled05_init.ino +++ b/wled00/wled05_init.ino @@ -12,15 +12,17 @@ void wledInit() while (dir.next()) { String fileName = dir.fileName(); size_t fileSize = dir.fileSize(); + #ifdef DEBUG Serial.printf("FS File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str()); + #endif } - Serial.printf("\n"); + DEBUG_PRINTF("\n"); } - Serial.println("Init EEPROM"); + DEBUG_PRINTLN("Init EEPROM"); EEPROM.begin(1024); loadSettingsFromEEPROM(); - Serial.print("CC: SSID: "); - Serial.print(clientssid); + DEBUG_PRINT("CC: SSID: "); + DEBUG_PRINT(clientssid); WiFi.disconnect(); //close old connections @@ -34,27 +36,27 @@ void wledInit() if (apssid.length()>0) { - Serial.print("USING AP"); - Serial.println(apssid.length()); + DEBUG_PRINT("USING AP"); + DEBUG_PRINTLN(apssid.length()); initAP(); } else { - Serial.println("NO AP"); + DEBUG_PRINTLN("NO AP"); WiFi.softAPdisconnect(true); } initCon(); - Serial.println(""); - Serial.print("Connected! IP address: "); - Serial.println(WiFi.localIP()); + DEBUG_PRINTLN(""); + DEBUG_PRINT("Connected! IP address: "); + DEBUG_PRINTLN(WiFi.localIP()); // Set up mDNS responder: if (cmdns != NULL && !only_ap && !MDNS.begin(cmdns.c_str())) { - Serial.println("Error setting up MDNS responder!"); + DEBUG_PRINTLN("Error setting up MDNS responder!"); down(); } - Serial.println("mDNS responder started"); + DEBUG_PRINTLN("mDNS responder started"); if (udpPort > 0 && udpPort != 123) { @@ -128,7 +130,7 @@ void wledInit() }); server.begin(); - Serial.println("HTTP server started"); + DEBUG_PRINTLN("HTTP server started"); // Add service to MDNS MDNS.addService("http", "tcp", 80); // Initialize NeoPixel Strip @@ -153,12 +155,12 @@ void initCon() WiFi.begin(clientssid.c_str(), clientpass.c_str()); while(WiFi.status() != WL_CONNECTED) { delay(500); - Serial.println("C_NC"); + DEBUG_PRINTLN("C_NC"); fail_count++; if (fail_count > 32) { WiFi.disconnect(); - Serial.println("Can't connect to network. Opening AP..."); + DEBUG_PRINTLN("Can't connect to network. Opening AP..."); String save = apssid; only_ap = true; if (apssid.length() <1) apssid = "WLED-AP"; diff --git a/wled00/wled10_ntp.ino b/wled00/wled10_ntp.ino index a78ef5d4..4c70f563 100644 --- a/wled00/wled10_ntp.ino +++ b/wled00/wled10_ntp.ino @@ -15,8 +15,8 @@ void handleNetworkTime() ntpSyncNeeded = false; ntpPacketSent = false; ntpSyncTime = millis(); - Serial.print("Time: "); - Serial.println(now()); + DEBUG_PRINT("Time: "); + DEBUG_PRINTLN(now()); } else { if (millis() - ntpPacketSentTime > ntpRetryMs) @@ -29,7 +29,7 @@ void handleNetworkTime() WiFi.hostByName(ntpServerName, ntpIp); if (ntpIp[0] == 0) { - Serial.println("DNS f!"); + DEBUG_PRINTLN("DNS f!"); ntpIp = ntpBackupIp; } sendNTPpacket(); @@ -45,9 +45,25 @@ void handleNetworkTime() bool getNtpTime() { - int size = ntpUdp.parsePacket(); - if (size >= 48) { + if (ntpUdp.parsePacket()) { ntpUdp.read(ntpBuffer, 48); // read packet into the buffer + + #ifdef DEBUG + int i= 0; + while (i < 48) + { + Serial.print(ntpBuffer[i], HEX); + Serial.print("."); + i++; + if ((i % 4) ==0) Serial.println(); + } + #endif + if (ntpBuffer[40] == 0 && ntpBuffer[41] == 0 && ntpBuffer[42] == 0 && ntpBuffer[43] == 0) + { + DEBUG_PRINTLN("Bad NTP response!"); + return false; + } + unsigned long secsSince1900; // convert four bytes starting at location 40 to a long integer secsSince1900 = (unsigned long)ntpBuffer[40] << 24; @@ -63,7 +79,8 @@ bool getNtpTime() void sendNTPpacket() { while (ntpUdp.parsePacket()>0); - Serial.println("Sending NTP packet"); + ntpUdp.flush(); //discard old packets + DEBUG_PRINTLN("Sending NTP packet"); memset(ntpBuffer, 0, 48); ntpBuffer[0] = 0b11100011; // LI, Version, Mode ntpBuffer[1] = 0; // Stratum, or type of clock diff --git a/wled00/wled11_ol.ino b/wled00/wled11_ol.ino index 0a4973ff..c6350157 100644 --- a/wled00/wled11_ol.ino +++ b/wled00/wled11_ol.ino @@ -32,7 +32,7 @@ void nixieNumber(int number, int dur) { if (nixieClockI < 0) { - Serial.print(number); + DEBUG_PRINT(number); int digitCnt = -1; int digits[4]; digits[3] = number/1000; @@ -51,15 +51,15 @@ void nixieNumber(int number, int dur) } else { //single digit digitCnt = 1; } - Serial.print(" "); + DEBUG_PRINT(" "); for (int i = 0; i < digitCnt; i++) { - Serial.print(digits[i]); + DEBUG_PRINT(digits[i]); overlayArr[digitCnt-1-i] = digits[i]; overlayDur[digitCnt-1-i] = ((dur/4)*3)/digitCnt; overlayPauseDur[digitCnt-1-i] = 0; } - Serial.println(" "); + DEBUG_PRINTLN(" "); for (int i = 1; i < digitCnt; i++) { if (overlayArr[i] == overlayArr[i-1]) @@ -86,14 +86,14 @@ void nixieNumber(int number, int dur) } for (int i = 0; i <6; i++) { - Serial.print(overlayArr[i]); - Serial.print(" "); - Serial.print(overlayDur[i]); - Serial.print(" "); - Serial.print(overlayPauseDur[i]); - Serial.print(" "); + DEBUG_PRINT(overlayArr[i]); + DEBUG_PRINT(" "); + DEBUG_PRINT(overlayDur[i]); + DEBUG_PRINT(" "); + DEBUG_PRINT(overlayPauseDur[i]); + DEBUG_PRINT(" "); } - Serial.println(" "); + DEBUG_PRINTLN(" "); nixieClockI = 0; } else { nixieDisplay(overlayArr, overlayDur, overlayPauseDur, 6); @@ -237,7 +237,7 @@ void handleOverlays() { nixieDisplay(overlayArr, overlayDur, overlayPauseDur, 6); } - } + } break; case 5: {//countdown if (now() >= countdownTime) {