From 31a6ddd0b3211ba5859dbf3269d6984b8c027743 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Tue, 7 Feb 2017 16:02:27 +0100 Subject: [PATCH] Attempted to fix NTP by reimplementing --- TODO.txt | 1 + readme.md | 5 ++-- wled00/data/settings.htm | 3 +- wled00/htmls01.h | 3 +- wled00/wled00.ino | 22 +++++++++++---- wled00/wled05_init.ino | 4 ++- wled00/wled10_ntp.ino | 59 +++++++++++++++++++++++++++++++++++++++- 7 files changed, 83 insertions(+), 14 deletions(-) diff --git a/TODO.txt b/TODO.txt index c2e46f01..8a33b88a 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,3 +1,4 @@ +captive portal for ap simple slide transition additional color picker field implement HSB slider option diff --git a/readme.md b/readme.md index 87d710f5..2eea6cba 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,7 @@ WLED is a basic, fast and (relatively) (ok, VERY relatively) secure implementation of a ESP8266 webserver to control Neopixel (WS2812B) leds Uses ESP8266 Arduino libraries from 15th August 2016! Untested with newer version! -Contents in the /data directory need to be uploaded to SPIFFS. +Contents in the /data directory may be uploaded to SPIFFS. Features: (V0.2) - RGB and brightness sliders @@ -16,11 +16,12 @@ Additions for V0.3 (nearly complete!) - Support for power pushbutton - Full OTA software update capability - Password protected OTA page for added security (OTA lock) +- NTP and experimental analog clock function Compile settings: Board: WeMos D1 mini CPU frequency: 80 MHz -Flash size : 4MB (1MB settings) +Flash size : 4MB (1MB SPIFFS) Upload speed: 115200 diff --git a/wled00/data/settings.htm b/wled00/data/settings.htm index 22efc6be..e1fc52af 100644 --- a/wled00/data/settings.htm +++ b/wled00/data/settings.htm @@ -143,8 +143,7 @@ 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.

+ Warning! NTP was updated but could still cause crashes. Requires reboot.
Get time from NTP server:
Current local time is unknown

Security

diff --git a/wled00/htmls01.h b/wled00/htmls01.h index 0fd54258..41954a56 100644 --- a/wled00/htmls01.h +++ b/wled00/htmls01.h @@ -147,8 +147,7 @@ const char PAGE_settings[] PROGMEM = R"=====( 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.

+ Warning! NTP was updated but could still cause crashes. Requires reboot.
Get time from NTP server:
Current local time is unknown

Security

diff --git a/wled00/wled00.ino b/wled00/wled00.ino index a16ce7c1..51994b91 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -84,6 +84,8 @@ uint8_t effectDefault = 0; uint8_t effectSpeedDefault = 75; //NTP stuff boolean ntpEnabled = false; +IPAddress ntpServerIP; +const char* ntpServerName = "time.nist.gov"; //overlay stuff int overlayMin = 0, overlayMax = 9; @@ -104,8 +106,8 @@ byte col[]{0, 0, 0}; byte col_old[]{0, 0, 0}; byte col_t[]{0, 0, 0}; byte col_it[]{0, 0, 0}; -long transitionStartTime; -long nightlightStartTime; +unsigned long transitionStartTime; +unsigned long nightlightStartTime; float tper_last = 0; byte bri = 0; byte bri_old = 0; @@ -123,27 +125,35 @@ uint8_t effectSpeed = 75; boolean udpConnected = false; byte udpIn[LEDCOUNT*4+2]; //NTP stuff +boolean ntpConnected = false; +unsigned int ntpLocalPort = 2390; +const int NTP_PACKET_SIZE = 48; +byte ntpPacketBuffer[NTP_PACKET_SIZE]; +unsigned long ntpLastSyncTime = 999000000L; +unsigned long ntpPacketSentTime = 999000000L; +const unsigned long seventyYears = 2208988800UL; //overlay stuff uint8_t overlayCurrent = 0; long overlayRefreshMs = 200; -long overlayRefreshedTime; +unsigned long overlayRefreshedTime; int overlayArr[6]; int overlayDur[6]; int overlayPauseDur[6]; int nixieClockI = -1; boolean nixiePause; -long countdownTime = 1483225200L; +unsigned long countdownTime = 1483225200L; int arlsTimeoutMillis = 2500; boolean arlsTimeout = false; long arlsTimeoutTime; uint8_t auxTime = 0; -long auxStartTime; +unsigned long auxStartTime; boolean auxActive, auxActiveBefore; ESP8266WebServer server(80); ESP8266HTTPUpdateServer httpUpdater; WiFiUDP notifierUdp; +WiFiUDP ntpUdp; WS2812FX strip = WS2812FX(LEDCOUNT, 2, NEO_GRB + NEO_KHZ800); @@ -226,7 +236,7 @@ void loop() { } lastWifiState = WiFi.status(); DEBUG_PRINT("Wifi state: "); DEBUG_PRINTLN(wifiStateChangedTime); - //DEBUG_PRINT("NTP sync needed: "); DEBUG_PRINTLN(ntpSyncNeeded); + DEBUG_PRINT("NTP last sync: "); DEBUG_PRINTLN(ntpLastSyncTime); DEBUG_PRINT("Client IP: "); DEBUG_PRINTLN(WiFi.localIP()); } #endif diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino index 7729e5d3..b13d52fb 100644 --- a/wled00/wled05_init.ino +++ b/wled00/wled05_init.ino @@ -58,10 +58,12 @@ void wledInit() } DEBUG_PRINTLN("mDNS responder started"); - if (udpPort > 0) + if (udpPort > 0 && udpPort != ntpLocalPort) { udpConnected = notifierUdp.begin(udpPort); } + if (ntpEnabled) + ntpConnected = ntpUdp.begin(ntpLocalPort); //SERVER INIT //settings page diff --git a/wled00/wled10_ntp.ino b/wled00/wled10_ntp.ino index 57b0756c..5c3cda94 100644 --- a/wled00/wled10_ntp.ino +++ b/wled00/wled10_ntp.ino @@ -4,7 +4,64 @@ void handleNetworkTime() { - + if (ntpEnabled && ntpConnected && millis() - ntpLastSyncTime > 50000000L) + { + if (millis() - ntpPacketSentTime > 10000) + { + sendNTPPacket(); + ntpPacketSentTime = millis(); + } + if (checkNTPResponse()) + { + ntpLastSyncTime = millis(); + } + } +} + +void sendNTPPacket() +{ + WiFi.hostByName(ntpServerName, ntpServerIP); + Serial.println("sending NTP packet..."); + + memset(ntpPacketBuffer, 0, NTP_PACKET_SIZE); + + ntpPacketBuffer[0] = 0b11100011; // LI, Version, Mode + ntpPacketBuffer[1] = 0; // Stratum, or type of clock + ntpPacketBuffer[2] = 6; // Polling Interval + ntpPacketBuffer[3] = 0xEC; // Peer Clock Precision + // 8 bytes of zero for Root Delay & Root Dispersion + ntpPacketBuffer[12] = 49; + ntpPacketBuffer[13] = 0x4E; + ntpPacketBuffer[14] = 49; + ntpPacketBuffer[15] = 52; + + ntpUdp.beginPacket(ntpServerIP, 123); //NTP requests are to port 123 + ntpUdp.write(ntpPacketBuffer, NTP_PACKET_SIZE); + ntpUdp.endPacket(); +} + +boolean checkNTPResponse() +{ + int cb = ntpUdp.parsePacket(); + if (cb) { + DEBUG_PRINT("packet received, length="); + DEBUG_PRINTLN(cb); + + ntpUdp.read(ntpPacketBuffer, NTP_PACKET_SIZE); // read the packet into the buffer + + unsigned long highWord = word(ntpPacketBuffer[40], ntpPacketBuffer[41]); + unsigned long lowWord = word(ntpPacketBuffer[42], ntpPacketBuffer[43]); + if (highWord == 0 && lowWord == 0) return false; + + unsigned long secsSince1900 = highWord << 16 | lowWord; + + DEBUG_PRINT("Unix time = "); + unsigned long epoch = secsSince1900 - seventyYears; + setTime(epoch); + DEBUG_PRINTLN(epoch); + return true; + } + return false; } String getTimeString()