From 89afdd2b17097ddaaa1addc4f98cbd2f2d5b26ac Mon Sep 17 00:00:00 2001 From: cschwinne Date: Thu, 15 Mar 2018 12:04:14 +0100 Subject: [PATCH] Most 0.6.0 features working LEDs now turn on instantly after boot Support Hardware ESP32 RMT NeopixelBus library Added setting to force old LED boot behavior (init after WiFi) Fixed overlay switching bug Fixed ? characters in usused macros Added transitionDelay to notifier packet --- readme.md | 9 +++-- wled00/WS2812FX.cpp | 9 ++++- wled00/WS2812FX.h | 6 +++ wled00/data/settings_leds.htm | Bin 7984 -> 8110 bytes wled00/htmls01.h | 1 + wled00/wled00.ino | 33 ++++++++-------- wled00/wled01_eeprom.ino | 10 ++++- wled00/wled02_xml.ino | 1 + wled00/wled03_set.ino | 1 + wled00/wled05_init.ino | 69 ++++++++++++++++++++-------------- wled00/wled07_notify.ino | 4 +- wled00/wled10_ntp.ino | 3 +- wled00/wled11_ol.ino | 4 +- wled00/wled15_hue.ino | 2 +- 14 files changed, 96 insertions(+), 56 deletions(-) diff --git a/readme.md b/readme.md index 8225e21517..b6abc86f3b 100644 --- a/readme.md +++ b/readme.md @@ -3,22 +3,25 @@ WLED is a fast and (relatively) secure implementation of an ESP8266 webserver to control NeoPixel (WS2812B) LEDs! Now also with experimental ESP32 support. -### Features: (V0.5.0) +### Features: (V0.6.0) - RGB, HSB, and brightness sliders - Settings page - configuration over network - Access Point and station mode - automatic failsafe AP - WS2812FX library integrated for over 50 special effects! - Secondary color support lets you use even more effect combinations +- Alexa smart home device server (including dimming) +- Beta syncronization to Philips hue lights - Support for RGBW strips - 25 user presets! Save your favorite colors and effects and apply them easily! +- HTTP request API for simple integration +- Macro functions to automatically execute API calls - Nightlight function (gradually dims down) - Notifier function (multiple ESPs sync color via UDP broadcast) - Support for power pushbutton - Custom Theater Chase - Full OTA software update capability (HTTP and ArduinoOTA) - Password protected OTA page for added security (OTA lock) -- Alexa smart home device server (including dimming) -- NTP and experimental analog clock function +- NTP and configurable analog clock function - Support for the Cronixie Clock kit by Diamex - Realtime UDP Packet Control (WARLS) possible - Client HTML UI controlled, customizable themes diff --git a/wled00/WS2812FX.cpp b/wled00/WS2812FX.cpp index 7e60af38da..0d6958cee7 100644 --- a/wled00/WS2812FX.cpp +++ b/wled00/WS2812FX.cpp @@ -2040,12 +2040,17 @@ void WS2812FX::setBrightness(byte b) void WS2812FX::show() { #ifdef ARDUINO_ARCH_ESP32 + #ifdef WORKAROUND_ESP32_BITBANG delay(1); portDISABLE_INTERRUPTS(); //this is a workaround to prevent flickering (see https://github.com/adafruit/Adafruit_NeoPixel/issues/139) + #endif + #endif NeoPixelBrightnessBus::Show(); + + #ifdef ARDUINO_ARCH_ESP32 + #ifdef WORKAROUND_ESP32_BITBANG portENABLE_INTERRUPTS(); - #else - NeoPixelBrightnessBus::Show(); + #endif #endif } diff --git a/wled00/WS2812FX.h b/wled00/WS2812FX.h index 87755e46ef..047df7fd73 100644 --- a/wled00/WS2812FX.h +++ b/wled00/WS2812FX.h @@ -1,10 +1,16 @@ //#define RGBW #define PIN 2 //strip pin. Only change for ESP32 +#define WORKAROUND_ESP32_BITBANG +//see https://github.com/Aircoookie/WLED/issues/2 for flicker free ESP32 support //automatically uses the right driver method for each platform #ifdef ARDUINO_ARCH_ESP32 +#ifdef WORKAROUND_ESP32_BITBANG #define PIXELMETHOD NeoEsp32BitBangWs2813Method #else +#define PIXELMETHOD NeoEsp32RmtWS2813_V3Method +#endif +#else #define PIXELMETHOD NeoEsp8266Uart800KbpsMethod #endif diff --git a/wled00/data/settings_leds.htm b/wled00/data/settings_leds.htm index 44368c827a739db6ff1a6fb73bc0d60eebcffba1..324a226d22472d68ac457500e52477ea33e22a6a 100644 GIT binary patch delta 60 zcmdmBx6XdUGFf#`hCGH$h7tw^1|J4j1{a26AS;m}4JeYzPy}R$17+P9GA9d4*fYB_ Lcy693JD(8%xs(mS delta 12 TcmZ2yzrk+9GTF^4a$Sr7BrOEb diff --git a/wled00/htmls01.h b/wled00/htmls01.h index 2bd7b7bdf9..54e0600013 100644 --- a/wled00/htmls01.h +++ b/wled00/htmls01.h @@ -117,6 +117,7 @@ Default Target brightness:

Advanced

Reverse LED order (rotate 180):
+Init LEDs after WiFi:
WARLS offset:
diff --git a/wled00/wled00.ino b/wled00/wled00.ino index b1de3ff703..10ea871d2e 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -33,7 +33,7 @@ #include "WS2812FX.h" //version in format yymmddb (b = daily build) -#define VERSION 1803144 +#define VERSION 1803146 const String versionString = "0.6.0"; //AP and OTA default passwords (change them!) @@ -74,6 +74,7 @@ IPAddress staticSubnet(255, 255, 255, 0); IPAddress staticDNS(8, 8, 8, 8); //only for NTP bool useHSB = false, useHSBDefault = false; bool turnOnAtBoot = true; +bool initLedsLast = false; byte bootPreset = 0; byte colS[]{255, 159, 0}; byte colSecS[]{0, 0, 0}; @@ -99,8 +100,7 @@ byte effectSpeedDefault = 75; byte effectIntensityDefault = 128; //NTP stuff bool ntpEnabled = false; -IPAddress ntpServerIP; -const char* ntpServerName = "0.wled.pool.ntp.org"; +String ntpServerName = "0.wled.pool.ntp.org"; //custom chase byte ccNumPrimary = 2; byte ccNumSecondary = 4; @@ -123,20 +123,13 @@ unsigned long countdownTime = 1514764800L; double transitionResolution = 0.011; //hue -long hueLastRequestSent = 0; bool huePollingEnabled = false, hueAttempt = false; uint16_t huePollIntervalMs = 2500; -uint32_t huePollIntervalMsTemp = 2500; String hueApiKey = "api"; byte huePollLightId = 1; IPAddress hueIP = (0,0,0,0); bool notifyHue = true; bool hueApplyOnOff = true, hueApplyBri = true, hueApplyColor = true; -String hueError = "Inactive"; -uint16_t hueFailCount = 0; -float hueXLast=0, hueYLast=0; -uint16_t hueHueLast=0, hueCtLast=0; -byte hueSatLast=0, hueBriLast=0; //Internal vars byte col[]{0, 0, 0}; @@ -176,15 +169,19 @@ String cssFont="Verdana"; String cssColorString=""; //NTP stuff bool ntpConnected = false; -unsigned int ntpLocalPort = 2390; -const uint16_t NTP_PACKET_SIZE = 48; -byte ntpPacketBuffer[NTP_PACKET_SIZE]; -unsigned long ntpLastSyncTime = 999000000L; -unsigned long ntpPacketSentTime = 999000000L; byte currentTimezone = 0; time_t local; int utcOffsetSecs = 0; +//hue +String hueError = "Inactive"; +uint16_t hueFailCount = 0; +float hueXLast=0, hueYLast=0; +uint16_t hueHueLast=0, hueCtLast=0; +byte hueSatLast=0, hueBriLast=0; +long hueLastRequestSent = 0; +uint32_t huePollIntervalMsTemp = huePollIntervalMs; + //overlay stuff byte overlayDefault = 0; byte overlayCurrent = 0; @@ -242,6 +239,12 @@ HTTPClient hueClient; ESP8266HTTPUpdateServer httpUpdater; WiFiUDP notifierUdp; WiFiUDP ntpUdp; +IPAddress ntpServerIP; +unsigned int ntpLocalPort = 2390; +const uint16_t NTP_PACKET_SIZE = 48; +byte ntpPacketBuffer[NTP_PACKET_SIZE]; +unsigned long ntpLastSyncTime = 999000000L; +unsigned long ntpPacketSentTime = 999000000L; WS2812FX strip = WS2812FX(LEDCOUNT); diff --git a/wled00/wled01_eeprom.ino b/wled00/wled01_eeprom.ino index 78d1aafb58..c91af4be07 100644 --- a/wled00/wled01_eeprom.ino +++ b/wled00/wled01_eeprom.ino @@ -6,13 +6,14 @@ #define EEPSIZE 3072 //eeprom Version code, enables default settings instead of 0 init on update -#define EEPVER 5 +#define EEPVER 6 //0 -> old version, default //1 -> 0.4p 1711272 and up //2 -> 0.4p 1711302 and up //3 -> 0.4 1712121 and up //4 -> 0.5.0 and up -//5 -> 0.6.0 and up +//5 -> 0.5.1 and up +//6 -> 0.6.0 and up //todo add settings void clearEEPROM() @@ -145,6 +146,7 @@ void saveSettingsToEEPROM() EEPROM.write(394, (abs(utcOffsetSecs) >> 0) & 0xFF); EEPROM.write(395, (abs(utcOffsetSecs) >> 8) & 0xFF); EEPROM.write(396, (utcOffsetSecs<0)); //is negative + EEPROM.write(397, initLedsLast); for (int k=0;k<6;k++){ int in = 900+k*8; @@ -380,6 +382,8 @@ void loadSettingsFromEEPROM(bool first) hueApplyBri = EEPROM.read(2104); hueApplyColor = EEPROM.read(2105); huePollLightId = EEPROM.read(2106); + } + if (lastEEPROMversion > 5) { overlayMin = EEPROM.read(2150); overlayMax = EEPROM.read(2151); analogClock12pixel = EEPROM.read(2152); @@ -415,6 +419,7 @@ void loadSettingsFromEEPROM(bool first) wifiLock = EEPROM.read(393); utcOffsetSecs = ((EEPROM.read(394) << 0) & 0xFF) + ((EEPROM.read(395) << 8) & 0xFF00); if (EEPROM.read(396)) utcOffsetSecs = -utcOffsetSecs; //negative + initLedsLast = EEPROM.read(397); //favorite setting memory (25 slots/ each 20byte) //400 - 899 reserved @@ -519,6 +524,7 @@ String loadMacro(byte index) if (EEPROM.read(i) == 0) break; m += char(EEPROM.read(i)); } + if (m.charAt(0) < 65 || m.charAt(0) > 90) return ""; //do simple check if macro is valid (capital first letter) return m; } diff --git a/wled00/wled02_xml.ino b/wled00/wled02_xml.ino index ee7039e1d5..a6cc53c3c0 100644 --- a/wled00/wled02_xml.ino +++ b/wled00/wled02_xml.ino @@ -166,6 +166,7 @@ String getSettings(byte subPage) resp += ds + "TL" + v + nightlightDelayMins +";"; resp += ds + "TW" + c + nightlightFade +";"; resp += ds + "RV" + c + reverseMode +";"; + resp += ds + "EI" + c + initLedsLast +";"; resp += ds + "WO" + v + arlsOffset +";"; } diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino index 3800d6256c..5f84cebb74 100644 --- a/wled00/wled03_set.ino +++ b/wled00/wled03_set.ino @@ -231,6 +231,7 @@ void handleSettingsSet(byte subPage) } nightlightFade = server.hasArg("TW"); reverseMode = server.hasArg("RV"); + initLedsLast = server.hasArg("EI"); strip.setReverseMode(reverseMode); if (server.hasArg("WO")) { diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino index 2501762a6f..a0c66d8324 100644 --- a/wled00/wled05_init.ino +++ b/wled00/wled05_init.ino @@ -4,27 +4,19 @@ void wledInit() { + EEPROM.begin(EEPSIZE); + if (!EEPROM.read(397)) strip.init(); //quick init + Serial.begin(115200); - + #ifdef USEFS SPIFFS.begin(); - { - Dir dir = SPIFFS.openDir("/"); - 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 - } - DEBUG_PRINTF("\n"); - } #endif - DEBUG_PRINTLN("Init EEPROM"); - EEPROM.begin(EEPSIZE); + DEBUG_PRINTLN("Load EEPROM"); loadSettingsFromEEPROM(true); - DEBUG_PRINT("CC: SSID: "); + if (!initLedsLast) initStrip(); + DEBUG_PRINT("C-SSID: "); DEBUG_PRINT(clientSSID); buildCssColorString(); userBeginPreConnection(); @@ -140,7 +132,7 @@ void wledInit() }); server.on("/reset", HTTP_GET, [](){ - serveMessage(200,"Rebooting now...","(takes ~20 seconds, wait for auto-redirect)",139); + serveMessage(200,"Rebooting now...","(takes ~20 seconds, wait for auto-redirect)",79); reset(); }); @@ -301,10 +293,15 @@ void wledInit() ArduinoOTA.begin(); } + if (initLedsLast) initStrip(); userBegin(); + if (macroBoot>0) applyMacro(macroBoot); +} - // Initialize NeoPixel Strip - strip.init(); +void initStrip() +{ + // Initialize NeoPixel Strip and button + if (initLedsLast) strip.init(); strip.setLedCount(ledCount); strip.setReverseMode(reverseMode); strip.setColor(0); @@ -314,7 +311,6 @@ void wledInit() pinMode(buttonPin, INPUT_PULLUP); if (bootPreset>0) applyPreset(bootPreset, turnOnAtBoot, true, true); - if (macroBoot>0) applyMacro(macroBoot); colorUpdated(0); if(digitalRead(buttonPin) == LOW) buttonEnabled = false; //disable button if it is "pressed" unintentionally } @@ -331,17 +327,32 @@ void initCon() int fail_count = 0; if (clientSSID.length() <1 || clientSSID.equals("Your_Network")) fail_count = apWaitTimeSecs*2; WiFi.begin(clientSSID.c_str(), clientPass.c_str()); - while(WiFi.status() != WL_CONNECTED) { - delay(500); - DEBUG_PRINTLN("C_NC"); - fail_count++; - if (!recoveryAPDisabled && fail_count > apWaitTimeSecs*2) + unsigned long lastTry = 0; + bool con = false; + while(!con) + { + yield(); + if (!initLedsLast) { - WiFi.disconnect(); - DEBUG_PRINTLN("Can't connect. Opening AP..."); - onlyAP = true; - initAP(); - return; + handleTransitions(); + handleButton(); + handleOverlays(); + if (briT) strip.service(); + } + if (millis()-lastTry > 499) { + con = (WiFi.status() == WL_CONNECTED); + if (con) DEBUG_PRINTLN("rofl"); + lastTry = millis(); + DEBUG_PRINTLN("C_NC"); + if (!recoveryAPDisabled && fail_count > apWaitTimeSecs*2) + { + WiFi.disconnect(); + DEBUG_PRINTLN("Can't connect. Opening AP..."); + onlyAP = true; + initAP(); + return; + } + fail_count++; } } } diff --git a/wled00/wled07_notify.ino b/wled00/wled07_notify.ino index 3898e580a7..0a96ae220f 100644 --- a/wled00/wled07_notify.ino +++ b/wled00/wled07_notify.ino @@ -28,12 +28,14 @@ void notify(byte callMode, bool followUp=false) udpOut[8] = effectCurrent; udpOut[9] = effectSpeed; udpOut[10] = white; - udpOut[11] = 3; //compatibilityVersionByte: 0: old 1: supports white 2: supports secondary color 3: supports FX intensity, 24 byte packet + udpOut[11] = 4; //compatibilityVersionByte: 0: old 1: supports white 2: supports secondary color 3: supports FX intensity, 24 byte packet 4: supports transitionDelay udpOut[12] = colSec[0]; udpOut[13] = colSec[1]; udpOut[14] = colSec[2]; udpOut[15] = whiteSec; udpOut[16] = effectIntensity; + udpOut[17] = (transitionDelay >> 0) & 0xFF; + udpOut[18] = (transitionDelay >> 8) & 0xFF; IPAddress broadcastIp; broadcastIp = ~WiFi.subnetMask() | WiFi.gatewayIP(); diff --git a/wled00/wled10_ntp.ino b/wled00/wled10_ntp.ino index c9b5fd713b..c3224764f3 100644 --- a/wled00/wled10_ntp.ino +++ b/wled00/wled10_ntp.ino @@ -69,7 +69,8 @@ void handleNetworkTime() void sendNTPPacket() { - WiFi.hostByName(ntpServerName, ntpServerIP); + const char* ntpsrv = ntpServerName.c_str(); + WiFi.hostByName(ntpsrv, ntpServerIP); DEBUG_PRINTLN("send NTP packet"); memset(ntpPacketBuffer, 0, NTP_PACKET_SIZE); diff --git a/wled00/wled11_ol.ino b/wled00/wled11_ol.ino index a6a094fde8..1cdc9cddb6 100644 --- a/wled00/wled11_ol.ino +++ b/wled00/wled11_ol.ino @@ -118,19 +118,19 @@ void _nixieNumber(int number, int dur) void handleOverlays() { - if (overlayCurrent == 0) return; - if (millis() - overlayRefreshedTime > overlayRefreshMs) { initCronixie(); updateLocalTime(); switch (overlayCurrent) { + case 0: break;//no overlay case 1: _overlaySolid(); break;//solid secondary color case 2: _overlayAnalogClock(); break;//2 analog clock case 3: _overlayNixieClock(); break;//nixie 1-digit case 4: _overlayCronixie();//Diamex cronixie clock kit } + if (!countdownMode || overlayCurrent < 2) checkCountdown(); //countdown macro activation must work overlayRefreshedTime = millis(); } } diff --git a/wled00/wled15_hue.ino b/wled00/wled15_hue.ino index 6f3789b528..39ead60467 100644 --- a/wled00/wled15_hue.ino +++ b/wled00/wled15_hue.ino @@ -64,7 +64,7 @@ bool sendHuePoll(bool sAuth) st = false; } if (!st){ //error - if (hueFailCount<7) huePollIntervalMsTemp*=2; // only poll every 5min when unable to connect + if (huePollIntervalMsTemp<300000) huePollIntervalMsTemp*=2; // only poll every ~5min when unable to connect hueFailCount++; if (hueFailCount > 150) huePollingEnabled = false; //disable after many hours offline }