From 17b25789742a7ce6d6026eb7055684457ebd3899 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Tue, 19 Dec 2017 16:12:51 +0100 Subject: [PATCH] Added Cronixie backlight with current limiting (API NB) Added API functions ND, NT and NF Moved information from readme to wiki Removed todo.txt HTTP API is now available again while WARLS active --- TODO.txt | 53 -------------------------------------- readme.md | 33 +++--------------------- wled00/WS2812FX.cpp | 24 ++++++++++++++--- wled00/WS2812FX.h | 2 ++ wled00/wled00.ino | 10 +++---- wled00/wled03_set.ino | 37 ++++++++++++++++++++++++++ wled00/wled05_init.ino | 33 ++++++++++++++++-------- wled00/wled13_cronixie.ino | 25 +++++++++++++++--- 8 files changed, 111 insertions(+), 106 deletions(-) delete mode 100644 TODO.txt diff --git a/TODO.txt b/TODO.txt deleted file mode 100644 index 1d7d76981..000000000 --- a/TODO.txt +++ /dev/null @@ -1,53 +0,0 @@ -captive portal for ap -simple slide transition -additional color picker field -implement ranges -implement discrete range color setter -implement discrete single color setter -add preferred colors to settings -> quickly t. UI, button select, -/dumpeeprom and /pusheeprom (ota lock!) -(aux trigger pin) partially impl. -audioWLED - Broadcast - Less traffic (distr. and scroll proc. on module) - Make webserver accessible while receiving - More modes? - -randomizer -ir, touch, pin input -Automations - -clock functions: -analog clock on range (dots) -5 min lines -slider clock on range (track) -time zones + dst (other than CE) -adjustable chimes -timed light activation -alarm clock -countdown (= NL with seq. trans) - -more button functions (hold for bri select, double click, etc.): -hold -single click -double click -triple click -quad click -funcs: toggle on/off -toggle nightlight -toggle notifier -var. brightness - -auto update (get from server) - -ifLed feature -> set triggers for reqs.? - -BUGS -opening settings causes crash after long runtime -flashing random (fixed?) -general forced reset (usually around 48h) (fixed?) -NTP crash (1-48h) (fixed?) -losing connectivity -udp notifier doesn't work all the time -static ip disables mdns -? authentification for security relevant areas ([/settings, /reset]) diff --git a/readme.md b/readme.md index dd6c56efd..6321f7b76 100644 --- a/readme.md +++ b/readme.md @@ -19,7 +19,8 @@ Uses ESP Arduino core version 2.3.0 (latest as of December 2017). - Full OTA software update capability - Password protected OTA page for added security (OTA lock) - Alexa smart home device server -- (unstable) NTP and experimental analog clock function +- NTP and experimental analog clock function +- Realtime UDP Packet Control (WARLS) possible - client HTML controlled - Edit page. Change html and other files via OTA. (needs to be enabled in source) @@ -48,7 +49,7 @@ You will need to install the NeoPixelBus library by Makuna. All other dependenci 7. Have fun with the software! -### Advanced module control via HTTP requests API: +### Advanced module control via HTTP requests API or UDP: See the [wiki](https://github.com/Aircoookie/WLED/wiki/HTTP-request-API)! @@ -65,34 +66,6 @@ arduino-esp8266-alexa-multiple-wemo-switch by kakopappa Uses Linearicons by Perxis! (link in settings page) -#### This information will be moved to the wiki soon: - -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. -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". - - -The software now supports audio-reactive-led-strip! - -1. Download [audio-reactive-led-strip](https://github.com/scottlawsonbc/audio-reactive-led-strip) and follow its installation instruction. Use python 3! -2. Insert the following code in led.py after line 66: - m.append(1); - m.append(2); -3. In config.py set your led amount, ESP IP and WLED UDP notifier port. For FPS, a setting between 15-30 is recommended. -4. Run visualization.py! If you have a low amount of LEDS (e.g. 10) try lowering the sigma values in line 129-131. -5. If you have multiple WLED devices, you can sync them all with music. -Use the led count of your largest device and set the IP to X.X.X.255 (UDP broadcast). -You can adjust the position of the amplitude with the WARLS offset setting. -Note that there is currently an issue preventing you from accessing the control web page while the script is running. HTTP requests work. - diff --git a/wled00/WS2812FX.cpp b/wled00/WS2812FX.cpp index 6c2acca35..35ac7a544 100644 --- a/wled00/WS2812FX.cpp +++ b/wled00/WS2812FX.cpp @@ -127,7 +127,7 @@ void WS2812FX::setColor(uint32_t c) { void WS2812FX::setSecondaryColor(uint32_t c) { _color_sec = c; _mode_color_sec = _color; - if (_cronixieMode) _cronixieSecMultiplier = getSafePowerMultiplier(1000, 60, c, _brightness); + if (_cronixieMode) _cronixieSecMultiplier = getSafePowerMultiplier(900, 100, c, _brightness); setBrightness(_brightness); } @@ -1823,6 +1823,11 @@ void WS2812FX::driverModeCronixie(bool b) _cronixieMode = b; } +void WS2812FX::setCronixieBacklight(bool b) +{ + _cronixieBacklightEnabled = b; +} + void WS2812FX::setCronixieDigits(uint8_t d[]) { for (int i = 0; i<6; i++) @@ -1947,9 +1952,22 @@ void WS2812FX::setPixelColor(uint16_t i, uint8_t r, uint8_t g, uint8_t b, uint8_ } else { if(i>6)return; uint8_t o = 10*i; - for (int j=o; j< o+19; j++) + if (_cronixieBacklightEnabled && _cronixieDigits[i] <11) { - setPixelColorRaw(j,0,0,0,0); + uint8_t rCorr = (int)(((double)((_color_sec>>16) & 0xFF))*_cronixieSecMultiplier); + uint8_t gCorr = (int)(((double)((_color_sec>>8) & 0xFF))*_cronixieSecMultiplier); + uint8_t bCorr = (int)(((double)((_color_sec) & 0xFF))*_cronixieSecMultiplier); + uint8_t wCorr = (int)(((double)((_color_sec>>24) & 0xFF))*_cronixieSecMultiplier); + for (int j=o; j< o+19; j++) + { + setPixelColorRaw(j,rCorr,gCorr,bCorr,wCorr); + } + } else + { + for (int j=o; j< o+19; j++) + { + setPixelColorRaw(j,0,0,0,0); + } } switch(_cronixieDigits[i]) { diff --git a/wled00/WS2812FX.h b/wled00/WS2812FX.h index cffae9c8d..6dfaba98b 100644 --- a/wled00/WS2812FX.h +++ b/wled00/WS2812FX.h @@ -240,6 +240,7 @@ class WS2812FX : public NeoPixelBrightnessBus 0) { + nightlightDelayMins = req.substring(pos + 3).toInt(); + nightlightActive_old = false; //re-init + } + //set nightlight target brightness + pos = req.indexOf("NT="); + if (pos > 0) { + bri_nl = req.substring(pos + 3).toInt(); + nightlightActive_old = false; //re-init + } + //toggle nightlight fade + if (req.indexOf("NF=") > 0) + { + if (req.indexOf("NF=0") > 0) + { + nightlightFade = false; + } else { + nightlightFade = true; + } + nightlightActive_old = false; //re-init + } //toggle general purpose output pos = req.indexOf("AX="); if (pos > 0) { @@ -524,6 +547,20 @@ boolean handleSet(String req) if (pos > 0) { setCronixie(req.substring(pos + 3, pos + 9).c_str()); } + pos = req.indexOf("NM="); //mode, NI + if (pos > 0) { + + } + if (req.indexOf("NB=") > 0) //sets backlight + { + cronixieBacklight = true; + if (req.indexOf("NB=0") > 0) + { + cronixieBacklight = false; + } + strip.setCronixieBacklight(cronixieBacklight); + cronixieRefreshedTime = 0; + } #endif //internal call, does not send XML response pos = req.indexOf("IN"); diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino index 62eb95720..ac6b037c7 100644 --- a/wled00/wled05_init.ino +++ b/wled00/wled05_init.ino @@ -71,23 +71,33 @@ void wledInit() //SERVER INIT //settings page server.on("/settings", HTTP_GET, [](){ - String settingsBuffer = getSettings(); - server.setContentLength(strlen_P(PAGE_settings0) + strlen_P(PAGE_settings1) + settingsBuffer.length()); - server.send(200, "text/html", ""); - server.sendContent_P(PAGE_settings0); - server.sendContent(settingsBuffer); - server.sendContent_P(PAGE_settings1); + if (!arlsTimeout) //do not serve while receiving realtime + { + String settingsBuffer = getSettings(); + server.setContentLength(strlen_P(PAGE_settings0) + strlen_P(PAGE_settings1) + settingsBuffer.length()); + server.send(200, "text/html", ""); + server.sendContent_P(PAGE_settings0); + server.sendContent(settingsBuffer); + server.sendContent_P(PAGE_settings1); + } else { + server.send(200, "text/plain", "The settings are not available while receiving real-time data."); + } }); server.on("/favicon.ico", HTTP_GET, [](){ if(!handleFileRead("/favicon.ico")) server.send(200, "image/x-icon", favicon); }); server.on("/", HTTP_GET, [](){ if(!handleFileRead("/index.htm")) { - server.setContentLength(strlen_P(PAGE_index0) + strlen_P(PAGE_index1) + strlen_P(PAGE_index2)); - server.send(200, "text/html", ""); - server.sendContent_P(PAGE_index0); - server.sendContent_P(PAGE_index1); - server.sendContent_P(PAGE_index2); + if (!arlsTimeout) //do not serve while receiving realtime + { + server.setContentLength(strlen_P(PAGE_index0) + strlen_P(PAGE_index1) + strlen_P(PAGE_index2)); + server.send(200, "text/html", ""); + server.sendContent_P(PAGE_index0); + server.sendContent_P(PAGE_index1); + server.sendContent_P(PAGE_index2); + } else { + server.send(200, "text/plain", "The WLED UI is not available while receiving real-time data."); + } } }); server.on("/reset", HTTP_GET, [](){ @@ -168,6 +178,7 @@ void wledInit() strip.start(); #ifdef CRONIXIE strip.driverModeCronixie(true); + strip.setCronixieBacklight(cronixieBacklight); setCronixie(cronixieDefault); #endif if (bootPreset>0) applyPreset(bootPreset, turnOnAtBoot, true, true); diff --git a/wled00/wled13_cronixie.ino b/wled00/wled13_cronixie.ino index 9f671901d..1b659be90 100644 --- a/wled00/wled13_cronixie.ino +++ b/wled00/wled13_cronixie.ino @@ -82,26 +82,30 @@ void setCronixie(char const digits[]) DEBUG_PRINT("cset "); DEBUG_PRINTLN(digits); + + cronixieRefreshMs = 1997; //Only refresh every 2secs if no seconds are displayed for (int i = 0; i < 6; i++) { dP[i] = 10; switch (digits[i]) { + case '_': dP[i] = 10; + case '-': dP[i] = 11; case 'r': dP[i] = random(1,7); break; //random btw. 1-6 case 'R': dP[i] = random(0,10); break; //random btw. 0-9 case 't': break; //Test upw. case 'T': break; //Test dnw. - case 'b': break; - case 'B': break; + case 'b': dP[i] = 14 + getSameCodeLength('b',i,digits); i = i+dP[i]-14; break; + case 'B': dP[i] = 14 + getSameCodeLength('B',i,digits); i = i+dP[i]-14; break; case 'h': dP[i] = 70 + getSameCodeLength('h',i,digits); i = i+dP[i]-70; break; case 'H': dP[i] = 20 + getSameCodeLength('H',i,digits); i = i+dP[i]-20; break; case 'A': dP[i] = 108; i++; break; case 'a': dP[i] = 58; i++; break; case 'm': dP[i] = 74 + getSameCodeLength('m',i,digits); i = i+dP[i]-74; break; case 'M': dP[i] = 24 + getSameCodeLength('M',i,digits); i = i+dP[i]-24; break; - case 's': dP[i] = 80 + getSameCodeLength('s',i,digits); i = i+dP[i]-80; break;break; - case 'S': dP[i] = 30 + getSameCodeLength('S',i,digits); i = i+dP[i]-30; break; + case 's': dP[i] = 80 + getSameCodeLength('s',i,digits); i = i+dP[i]-80; cronixieRefreshMs = 497; break; //refresh more often bc. of secs + case 'S': dP[i] = 30 + getSameCodeLength('S',i,digits); i = i+dP[i]-30; cronixieRefreshMs = 497; break; case 'Y': break; case 'y': break; case 'I': break; //Month. Don't ask me why month and minute both start with M. @@ -131,6 +135,8 @@ void setCronixie(char const digits[]) DEBUG_PRINT(" "); } DEBUG_PRINTLN((int)dP[5]); + + cronixieRefreshedTime = 0; //refresh immediately } void handleCronixie() @@ -140,8 +146,12 @@ void handleCronixie() cronixieRefreshedTime = millis(); local = TZ.toLocal(now(), &tcr); uint8_t h = hour(local); + uint8_t h0 = h; uint8_t m = minute(local); uint8_t s = second(local); + uint8_t d = day(local); + uint8_t mi = month(local); + uint16_t y = year(local); if (cronixieUseAMPM) { if (h>12) h-=12; @@ -159,6 +169,13 @@ void handleCronixie() case 21: _digitOut[i] = h/10; _digitOut[i+1] = h- _digitOut[i]*10; i++; break; //HH case 25: _digitOut[i] = m/10; _digitOut[i+1] = m- _digitOut[i]*10; i++; break; //MM case 31: _digitOut[i] = s/10; _digitOut[i+1] = s- _digitOut[i]*10; i++; break; //SS + + case 20: _digitOut[i] = h- (h/10)*10; break; //H + case 24: _digitOut[i] = m/10; break; //M + case 30: _digitOut[i] = s/10; break; //S + case 16: _digitOut[i+2] = ((h0/3)&1)?1:0; i++; //BBB (BBBB NI) + case 15: _digitOut[i+1] = (h0>17 || (h0>5 && h0<12))?1:0; i++; //BB + case 14: _digitOut[i] = (h0>11)?1:0; break; //B } } else {