From 849eefd64cb7f569e9966dadd4a8f9efd3dec291 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Thu, 14 Dec 2017 00:12:02 +0100 Subject: [PATCH] Version 0.5dev Started Cronixie development Added /power page to get current draw estimate Replaced a redundant effect (35) with a new traffic light effect Started adding ICU effect (34), currently broken Limited FX and apChannel fields in settings to their bounds --- wled00/WS2812FX.cpp | 160 ++++++++++++++++++++++++++++++++----- wled00/WS2812FX.h | 27 +++++-- wled00/data/index-min.htm | 2 +- wled00/data/index.htm | 2 +- wled00/data/settings.htm | 4 +- wled00/htmls00.h | 2 +- wled00/wled00.ino | 41 +++++++--- wled00/wled02_xml.ino | 2 +- wled00/wled05_init.ino | 14 +++- wled00/wled07_notify.ino | 1 - wled00/wled13_cronixie.ino | 124 ++++++++++++++++++++++++++++ 11 files changed, 334 insertions(+), 45 deletions(-) create mode 100644 wled00/wled13_cronixie.ino diff --git a/wled00/WS2812FX.cpp b/wled00/WS2812FX.cpp index 02bdd79fb..464353890 100644 --- a/wled00/WS2812FX.cpp +++ b/wled00/WS2812FX.cpp @@ -127,6 +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); setBrightness(_brightness); } @@ -989,18 +990,67 @@ void WS2812FX::mode_chase_rainbow_white(void) { /* - * _color_sec running on _color. REDUNDANT!!! + * Eye (broken) */ -void WS2812FX::mode_chase_blackout(void) { - mode_chase_color(); +void WS2812FX::mode_icu(void) { + uint16_t dest = _counter_mode_step & 0xFFFF; + + setPixelColor(dest, _color); + setPixelColor(dest + _led_count/2, _color); + + if(_mode_color == dest) { // pause between eye movements + if(random(6) == 0) { // blink once in a while + setPixelColor(dest, _color_sec); + setPixelColor(dest + _led_count/2, _color_sec); + show(); + _mode_delay = 200; + return; + } + _mode_color = random(_led_count/2); + _mode_delay = 1000 + random(2000); + return; + } + + setPixelColor(dest, _color_sec); + setPixelColor(dest + _led_count/2, _color_sec); + + if(_mode_color > _counter_mode_step) { + _counter_mode_step++; + dest++; + } else if (_mode_color < _counter_mode_step) { + _counter_mode_step--; + dest--; + } + + setPixelColor(dest, _color); + setPixelColor(dest + _led_count/2, _color); + show(); + + _mode_delay = 100 + ((100 * (uint32_t)(SPEED_MAX - _speed)) / _led_count); } /* - * _color_sec running on rainbow. REDUNDANT!!! + * Emulates a traffic light. */ -void WS2812FX::mode_chase_blackout_rainbow(void) { - mode_chase_rainbow(); +void WS2812FX::mode_traffic_light(void) { + for(uint16_t i=0; i < _led_count; i++) { + if (!_locked[i]) + setPixelColor(i, _color_sec); + } + for (int i = 0; i < _led_count-2 ; i+=3) + { + switch (_counter_mode_step) + { + case 0: if(!_locked[i])setPixelColor(i, 0x00FF0000); _mode_delay = 150 + (100 * (uint32_t)(SPEED_MAX - _speed));break; + case 1: if(!_locked[i])setPixelColor(i, 0x00FF0000); _mode_delay = 150 + (20 * (uint32_t)(SPEED_MAX - _speed)); if(!_locked[i+1])setPixelColor(i+1, 0x00EECC00); break; + case 2: if(!_locked[i+2])setPixelColor(i+2, 0x0000FF00); _mode_delay = 150 + (100 * (uint32_t)(SPEED_MAX - _speed));break; + case 3: if(!_locked[i+1])setPixelColor(i+1, 0x00EECC00); _mode_delay = 150 + (20 * (uint32_t)(SPEED_MAX - _speed));break; + } + } + show(); + _counter_mode_step++; + if (_counter_mode_step >3) _counter_mode_step = 0; } @@ -1768,6 +1818,49 @@ void WS2812FX::setFastUpdateMode(bool y) if (_mode_index == 0) _mode_delay = 20; } +void WS2812FX::driverModeCronixie(bool b) +{ + _cronixieMode = b; +} + +void WS2812FX::setCronixieDigits(uint8_t d[]) +{ + for (int i = 0; i<6; i++) + { + _cronixieDigits[i] = d[i]; + } +} + +double WS2812FX::getPowerEstimate(uint8_t leds, uint32_t c, uint8_t b) +{ + double _mARequired = 100; //ESP power + double _mul = (double)b/255; + double _sum = ((c & 0xFF000000) >> 24) + ((c & 0x00FF0000) >> 16) + ((c & 0x0000FF00) >> 8) + ((c & 0x000000FF) >> 0); + #ifdef RGBW + _sum /= 1024; + #else + _sum /= 768; + #endif + double _mAPerLed = 50*(_mul*_sum); + _mARequired += leds*_mAPerLed; + return _mARequired; +} + +//DISCLAIMER +//This is just a helper function for huge amounts of LEDs. +//It is NOT guaranteed to stay within the safeAmps margin. +//Stay safe with high amperage and have a reasonable safety margin! +//I am NOT to be held liable for burned down garages! +double WS2812FX::getSafePowerMultiplier(double safeMilliAmps, uint8_t leds, uint32_t c, uint8_t b) +{ + double _mARequired = getPowerEstimate(leds,c,b); + if (_mARequired > safeMilliAmps) + { + return safeMilliAmps/_mARequired; + } + return 1.0; +} + void WS2812FX::setCCIndex1(uint8_t i1) { if (i1 < _led_count-1) _cc_i1 = i1; @@ -1833,32 +1926,55 @@ void WS2812FX::setCustomChase(uint8_t i1, uint8_t i2, uint8_t is, uint8_t np, ui } //Added for quick NeoPixelBus compatibility with Adafruit syntax - -void WS2812FX::setPixelColor(uint16_t i, uint32_t c) +void WS2812FX::setPixelColorRaw(uint16_t i, uint8_t r, uint8_t g, uint8_t b, uint8_t w) { #ifdef RGBW - NeoPixelBrightnessBus::SetPixelColor(i, RgbwColor((c>>16) & 0xFF, (c>>8) & 0xFF, (c) & 0xFF, (c>>24) & 0xFF)); - #else - NeoPixelBrightnessBus::SetPixelColor(i, RgbColor((c>>16) & 0xFF, (c>>8) & 0xFF, (c) & 0xFF)); - #endif + NeoPixelBrightnessBus::SetPixelColor(i, RgbwColor(r,g,b,w)); + #else + NeoPixelBrightnessBus::SetPixelColor(i, RgbColor(r,g,b)); + #endif } void WS2812FX::setPixelColor(uint16_t i, uint8_t r, uint8_t g, uint8_t b, uint8_t w) { - #ifdef RGBW - NeoPixelBrightnessBus::SetPixelColor(i, RgbwColor(r,g,b,w)); - #else - NeoPixelBrightnessBus::SetPixelColor(i, RgbColor(r,g,b)); - #endif + if (!_cronixieMode) + { + #ifdef RGBW + NeoPixelBrightnessBus::SetPixelColor(i, RgbwColor(r,g,b,w)); + #else + NeoPixelBrightnessBus::SetPixelColor(i, RgbColor(r,g,b)); + #endif + } else { + if(i>6)return; + uint8_t o = 20*i; + for (int j=o; j< o+19; j++) + { + setPixelColorRaw(j,0,0,0,0); + } + switch(_cronixieDigits[i]) + { + case 0: setPixelColorRaw(o+5,r,g,b,w); setPixelColorRaw(o+15,r,g,b,w); break; + case 1: setPixelColorRaw(o+0,r,g,b,w); setPixelColorRaw(o+10,r,g,b,w); break; + case 2: setPixelColorRaw(o+6,r,g,b,w); setPixelColorRaw(o+16,r,g,b,w); break; + case 3: setPixelColorRaw(o+1,r,g,b,w); setPixelColorRaw(o+11,r,g,b,w); break; + case 4: setPixelColorRaw(o+7,r,g,b,w); setPixelColorRaw(o+17,r,g,b,w); break; + case 5: setPixelColorRaw(o+2,r,g,b,w); setPixelColorRaw(o+12,r,g,b,w); break; + case 6: setPixelColorRaw(o+8,r,g,b,w); setPixelColorRaw(o+18,r,g,b,w); break; + case 7: setPixelColorRaw(o+3,r,g,b,w); setPixelColorRaw(o+13,r,g,b,w); break; + case 8: setPixelColorRaw(o+9,r,g,b,w); setPixelColorRaw(o+19,r,g,b,w); break; + case 9: setPixelColorRaw(o+4,r,g,b,w); setPixelColorRaw(o+14,r,g,b,w); break; + } + } } void WS2812FX::setPixelColor(uint16_t i, uint8_t r, uint8_t g, uint8_t b) { - #ifdef RGBW - NeoPixelBrightnessBus::SetPixelColor(i, RgbwColor(r,g,b,0)); - #else - NeoPixelBrightnessBus::SetPixelColor(i, RgbColor(r,g,b)); - #endif + setPixelColor(i,r,g,b,0); +} + +void WS2812FX::setPixelColor(uint16_t i, uint32_t c) +{ + setPixelColor(i,(c>>16) & 0xFF,(c>>8) & 0xFF,(c) & 0xFF,(c>>24) & 0xFF); } uint32_t WS2812FX::getPixelColor(uint16_t i) diff --git a/wled00/WS2812FX.h b/wled00/WS2812FX.h index e315e6c21..19c6a7f95 100644 --- a/wled00/WS2812FX.h +++ b/wled00/WS2812FX.h @@ -85,8 +85,8 @@ #define FX_MODE_CHASE_FLASH 31 #define FX_MODE_CHASE_FLASH_RANDOM 32 #define FX_MODE_CHASE_RAINBOW_WHITE 33 -#define FX_MODE_CHASE_BLACKOUT 34 -#define FX_MODE_CHASE_BLACKOUT_RAINBOW 35 +#define FX_MODE_ICU 34 +#define FX_MODE_TRAFFIC_LIGHT 35 #define FX_MODE_COLOR_SWEEP_RANDOM 36 #define FX_MODE_RUNNING_COLOR 37 #define FX_MODE_RUNNING_RED_BLUE 38 @@ -157,8 +157,8 @@ class WS2812FX : public NeoPixelBrightnessBus -WLED 0.4 +WLED 0.5dev diff --git a/wled00/data/index.htm b/wled00/data/index.htm index 1d4b8c0f5..a2340a973 100644 --- a/wled00/data/index.htm +++ b/wled00/data/index.htm @@ -1,7 +1,7 @@ - WLED 0.4p + WLED 0.5dev diff --git a/wled00/wled00.ino b/wled00/wled00.ino index e2445301a..ffe4c31a1 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -1,6 +1,11 @@ /* * Main sketch */ +/* + * @title WLED project sketch + * @version 0.5dev + * @author Christian Schwinne + */ #include #include @@ -20,7 +25,7 @@ #include "WS2812FX.h" //version in format yymmddb (b = daily build) -#define VERSION 1712122 +#define VERSION 1712132 //If you have an RGBW strip, uncomment first line in WS2812FX.h! @@ -31,7 +36,10 @@ //#define USEFS //overlays, needed for clocks etc. -//#define USEOVERLAYS +#define USEOVERLAYS + +//support for the CRONIXIE clock by Diamex +//#define CRONIXIE #ifdef USEFS #include @@ -54,11 +62,6 @@ //2 -> 0.4p 1711302 and up //3 -> 0.4 1712121 and up -/* - * @title WLED project sketch - * @version 0.4 - * @author Christian Schwinne - */ //Hardware-settings (only changeble via code) #define LEDCOUNT 255 //maximum, exact count set-able via settings #define MAXDIRECT 255 //for direct access like arls, should be >= LEDCOUNT @@ -77,13 +80,28 @@ Timezone TZ(CEST, CET); TimeChangeRule *tcr; //pointer to the time change rule, use to get the TZ abbrev time_t local; +//cronixie defaults +#ifdef CRONIXIE +#undef LEDCOUNT +#define LEDCOUNT 120 +#undef MAXDIRECT +#define MAXDIRECT 48 +uint8_t ledcount = 6; +String apssid = "CRONIXIE-AP"; +String alexaInvocationName = "Clock"; +long cronixieRefreshMs = 99; +unsigned long cronixieRefreshedTime; +#endif + //Default CONFIG -uint8_t ledcount = 93; -String serverDescription = "WLED 0.4"; +String serverDescription = "WLED 0.5dev"; String clientssid = "Your_Network_Here"; String clientpass = "Dummy_Pass"; String cmdns = "led"; +#ifndef CRONIXIE +uint8_t ledcount = 100; String apssid = "WLED-AP"; +#endif uint8_t apchannel = 1; uint8_t aphide = 0; uint8_t apWaitTimeSecs = 32; @@ -130,7 +148,9 @@ uint8_t cc_start = 0; //alexa boolean alexaEnabled = true; +#ifndef CRONIXIE String alexaInvocationName = "Light"; +#endif boolean alexaNotify = false; double transitionResolution = 0.011; @@ -276,6 +296,9 @@ void loop() { #ifdef USEOVERLAYS handleOverlays(); #endif + #ifdef CRONIXIE + handleCronixie(); + #endif handleAlexa(); strip.service(); diff --git a/wled00/wled02_xml.ino b/wled00/wled02_xml.ino index 291608c8a..1a82066ed 100644 --- a/wled00/wled02_xml.ino +++ b/wled00/wled02_xml.ino @@ -162,7 +162,7 @@ String getSettings() resp += "Not active"; } resp += "\";"; - resp += dg + "(\"msg\")[0]" + ih + "\"WLED 0.4 (build " + VERSION + ") OK\";"; + resp += dg + "(\"msg\")[0]" + ih + "\"WLED 0.5dev (build " + VERSION + ") OK\";"; return resp; } diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino index 2923d9b46..2857ab524 100644 --- a/wled00/wled05_init.ino +++ b/wled00/wled05_init.ino @@ -107,6 +107,11 @@ void wledInit() server.on("/freeheap", HTTP_GET, [](){ server.send(200, "text/plain", (String)ESP.getFreeHeap()); }); + server.on("/power", HTTP_GET, [](){ + String val = (String)(int)strip.getPowerEstimate(ledcount,strip.getColor(),strip.getBrightness()); + val += "mA currently\nNotice: This is just an estimate which does not take into account several factors (like effects and wire resistance). It is NOT an accurate measurement!"; + server.send(200, "text/plain", val); + }); if (!otaLock){ server.on("/edit", HTTP_GET, [](){ if(!handleFileRead("/edit.htm")) server.send(200, "text/html", PAGE_edit); @@ -161,6 +166,9 @@ void wledInit() strip.setSpeed(effectSpeed); strip.setBrightness(255); strip.start(); + #ifdef CRONIXIE + strip.driverModeCronixie(true); + #endif if (bootPreset>0) applyPreset(bootPreset, turnOnAtBoot, true, true); colorUpdated(0); pinMode(buttonPin, INPUT_PULLUP); @@ -185,7 +193,11 @@ void initCon() DEBUG_PRINTLN("Can't connect. Opening AP..."); String save = apssid; onlyAP = true; - if (apssid.length() <1) apssid = "WLED-AP"; + #ifdef CRONIXIE + if (apssid.length() <1) apssid = "CRONIXIE-AP"; + #else + if (apssid.length() <1) apssid = "WLED-AP"; + #endif initAP(); apssid = save; return; diff --git a/wled00/wled07_notify.ino b/wled00/wled07_notify.ino index 8246aab85..c57a67a74 100644 --- a/wled00/wled07_notify.ino +++ b/wled00/wled07_notify.ino @@ -9,7 +9,6 @@ void notify(uint8_t callMode) { case 1: if (!notifyDirect) return; break; case 2: if (!notifyButton) return; break; - case 3: return; case 4: if (!notifyDirect) return; break; case 6: if (!notifyDirect) return; break; //fx change default: return; diff --git a/wled00/wled13_cronixie.ino b/wled00/wled13_cronixie.ino new file mode 100644 index 000000000..6b323214c --- /dev/null +++ b/wled00/wled13_cronixie.ino @@ -0,0 +1,124 @@ +#ifdef CRONIXIE +void setCronixieMode(char digits[], uint8_t l) +{ + hourDigitCount = 0; + + /* + * bool trailingzero[] + * + * digit purpose index + * 0-9 | 0-9 (incl. random) + * 10 | blank + * 11 | blank, bg off + * 12 | test upw. + * 13 | test dnw. + * 14 | binary AM/PM + * 15 | BB upper + * 16 | BBB + * 17 | BBBB + * 18 | BBBBB + * 19 | BBBBBB + * 20 | H + * 21 | HH + * 22 | HHH + * 23 | HHHH + * 24 | M + * 25 | MM + * 26 | MMM + * 27 | MMMM + * 28 | MMMMM + * 29 | MMMMMM + * 30 | S + * 31 | SS + * 32 | SSS + * 33 | SSSS + * 34 | SSSSS + * 35 | SSSSSS + * 36 | Y + * 37 | YY + * 38 | YYYY + * 39 | I + * 40 | II + * 41 | W + * 42 | WW + * 43 | D + * 44 | DD + * 45 | DDD + * 46 | V + * 47 | VV + * 48 | VVV + * 49 | VVVV + * 50 | VVVVV + * 51 | VVVVVV + * 52 | v + * 53 | vv + * 54 | vvv + * 55 | vvvv + * 56 | vvvvv + * 57 | vvvvvv + * 255 | set by previous + */ + + //H HourLower | HH - Hour 24. | AH - Hour 12. | HHH Hour of Month | HHHH Hour of Year + //M MinuteUpper | MM Minute of Hour | MMM Minute of 12h | MMMM Minute of Day | MMMMM Minute of Month | MMMMMM Minute of Year + //S SecondUpper | SS Second of Minute | SSS Second of 10 Minute | SSSS Second of Hour | SSSSS Second of Day | SSSSSS Second of Week + //B AM/PM | BB 0-6/6-12/12-18/18-24 | BBB 0-3... | BBBB 0-1.5... | BBBBB 0-1 | BBBBBB 0-0.5 + + //Y YearLower | YY - Year LU | YYYY - Std. + //I MonthLower | II - Month of Year + //W Week of Month | WW Week of Year + //D Day of Week | DD Day Of Month | DDD Day Of Year + + for (int i = min(5,l); i >= 0; i--) + { + switch (digits[i]) + { + case '-': break; //blank + case '_': break; //blank, bg off + case 'r': break; //random btw. 1-6 + case 'R': break; //random btw. 0-9 + case 't': break; //Test upw. + case 'T': break; //Test dnw. + case 'b': break; + case 'B': break; + case 'h': break; + case 'H': break; + case 'm': break; + case 'M': break; + case 's': break; + case 'S': break; + case 'Y': break; + case 'y': break; + case 'I': break; //Month. Don't ask me why month and minute both start with M. + case 'i': break; + case 'W': break; + case 'w': break; + case 'D': break; + case 'd': break; + case '0': break; + case '1': break; + case '2': break; + case '3': break; + case '4': break; + case '5': break; + case '6': break; + case '7': break; + case '8': break; + case '9': break; + case 'V': break; //user var0 + case 'v': break; //user var1 + } + } +} + +void handleCronixie() +{ + if (millis() - cronixieRefreshedTime > cronixieRefreshMs) + { + cronixieRefreshedTime = millis(); + local = TZ.toLocal(now(), &tcr); + + strip.setCronixieDigits(); + //cronixieRefreshMs = 99; +} +#endif