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
This commit is contained in:
cschwinne 2017-12-19 16:12:51 +01:00
parent cc9046be52
commit 17b2578974
8 changed files with 111 additions and 106 deletions

View File

@ -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])

View File

@ -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 "<moduleip>/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.

View File

@ -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])
{

View File

@ -240,6 +240,7 @@ class WS2812FX : public NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp8266Uart800Kb
decreaseBrightness(uint8_t s),
driverModeCronixie(bool b),
setCronixieDigits(uint8_t* d),
setCronixieBacklight(bool b),
setIndividual(int i),
setIndividual(int i, uint32_t col),
setRange(int i, int i2),
@ -350,6 +351,7 @@ class WS2812FX : public NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp8266Uart800Kb
_triggered,
_fastStandard,
_cronixieMode,
_cronixieBacklightEnabled,
_cc_fs,
_cc_fe,
_running;

View File

@ -25,7 +25,7 @@
#include "WS2812FX.h"
//version in format yymmddb (b = daily build)
#define VERSION 1712152
#define VERSION 1712192
//AP and OTA default passwords (change them!)
String appass = "wled1234";
@ -73,6 +73,7 @@ long cronixieRefreshMs = 497;
unsigned long cronixieRefreshedTime;
byte dP[]{0,0,0,0,0,0};
bool cronixieUseAMPM = false;
bool cronixieBacklight = true;
boolean ntpEnabled = true;
#endif
@ -288,9 +289,9 @@ void setup() {
}
void loop() {
server.handleClient();
handleNotifications();
handleTransitions();
handleNightlight();
yield();
handleButton();
handleNetworkTime();
@ -298,14 +299,13 @@ void loop() {
handleCronixie();
#endif
handleAlexa();
if (!arlsTimeout)
if (!arlsTimeout) //block stuff if WARLS is enabled
{
handleNetworkTime();
handleNightlight();
#ifdef USEOVERLAYS
handleOverlays();
#endif
strip.service();
server.handleClient();
}
//DEBUG

View File

@ -455,6 +455,29 @@ boolean handleSet(String req)
nightlightStartTime = millis();
}
}
//set nightlight delay
pos = req.indexOf("ND=");
if (pos > 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");

View File

@ -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);

View File

@ -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
{