diff --git a/readme.md b/readme.md
index ea7a0266..51a14402 100644
--- a/readme.md
+++ b/readme.md
@@ -2,29 +2,28 @@
WLED is a fast and (relatively) secure implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B) LEDs!
-### Features: (V0.6.4)
+### Features: (V0.7.0)
- RGB, HSB, and brightness sliders
+- All new, mobile-friendly web UI!
- Settings page - configuration over network
- Access Point and station mode - automatic failsafe AP
-- WS2812FX library integrated for over 50 special effects!
+- WS2812FX library integrated for over 50 special effects (+Custom Theater Chase)!
- 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! Now supports cycling through them.
+- 25 user presets! Save colors and effects and apply them easily! Supports cycling through them.
- 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
- Support for the Adalight serial ambilight protocol!
- Full OTA software update capability (HTTP and ArduinoOTA)
- Password protected OTA page for added security (OTA lock)
- NTP and configurable analog clock function
- Support for the Cronixie Clock kit by Diamex
-- Realtime UDP Packet Control (WARLS, DRGB, DRGBW) possible
-- Client HTML UI controlled, customizable themes
+- Realtime UDP Packet Control (Hyperion, WARLS, DRGB, DRGBW)
### Quick start guide and documentation:
diff --git a/wled00/WS2812FX.cpp b/wled00/WS2812FX.cpp
index 60e1d548..9b2e0e74 100644
--- a/wled00/WS2812FX.cpp
+++ b/wled00/WS2812FX.cpp
@@ -37,8 +37,8 @@
#define CALL_MODE(n) (this->*_mode[n])();
-void WS2812FX::init(bool supportWhite, uint16_t countPixels, uint8_t pin) {
- begin(supportWhite,countPixels,pin);
+void WS2812FX::init(bool supportWhite, uint16_t countPixels, uint8_t pin,bool skipFirst) {
+ begin(supportWhite,countPixels,pin,skipFirst);
for (int i=0; i < _led_count; i++) _locked[i] = false;
WS2812FX::setBrightness(_brightness);
show();
@@ -2032,6 +2032,7 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
if (_reverseMode) i = _led_count - 1 -i;
if (!_cronixieMode)
{
+ if (_skipFirstMode) {i++;if(i==1)setPixelColorRaw(0,0,0,0,0);}
if (_rgbwMode)
{
bus->SetPixelColor(i, RgbwColor(r,g,b,w));
@@ -2050,27 +2051,27 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
byte wCorr = (int)(((double)((_color_sec>>24) & 0xFF))*_cronixieSecMultiplier);
for (int j=o; j< o+19; j++)
{
- setPixelColorRaw(j,rCorr,gCorr,bCorr,wCorr);
+ setPixelColorRaw((_skipFirstMode)?j+1:j,rCorr,gCorr,bCorr,wCorr);
}
} else
{
for (int j=o; j< o+19; j++)
{
- setPixelColorRaw(j,0,0,0,0);
+ setPixelColorRaw((_skipFirstMode)?j+1:j,0,0,0,0);
}
}
switch(_cronixieDigits[i])
{
- case 0: setPixelColorRaw(o+5,r,g,b,w); break;
- case 1: setPixelColorRaw(o+0,r,g,b,w); break;
- case 2: setPixelColorRaw(o+6,r,g,b,w); break;
- case 3: setPixelColorRaw(o+1,r,g,b,w); break;
- case 4: setPixelColorRaw(o+7,r,g,b,w); break;
- case 5: setPixelColorRaw(o+2,r,g,b,w); break;
- case 6: setPixelColorRaw(o+8,r,g,b,w); break;
- case 7: setPixelColorRaw(o+3,r,g,b,w); break;
- case 8: setPixelColorRaw(o+9,r,g,b,w); break;
- case 9: setPixelColorRaw(o+4,r,g,b,w); break;
+ case 0: setPixelColorRaw((_skipFirstMode)?o+6:o+5,r,g,b,w); break;
+ case 1: setPixelColorRaw((_skipFirstMode)?o+1:o+0,r,g,b,w); break;
+ case 2: setPixelColorRaw((_skipFirstMode)?o+7:o+6,r,g,b,w); break;
+ case 3: setPixelColorRaw((_skipFirstMode)?o+2:o+1,r,g,b,w); break;
+ case 4: setPixelColorRaw((_skipFirstMode)?o+8:o+7,r,g,b,w); break;
+ case 5: setPixelColorRaw((_skipFirstMode)?o+3:o+2,r,g,b,w); break;
+ case 6: setPixelColorRaw((_skipFirstMode)?o+9:o+8,r,g,b,w); break;
+ case 7: setPixelColorRaw((_skipFirstMode)?o+4:o+3,r,g,b,w); break;
+ case 8: setPixelColorRaw((_skipFirstMode)?o+10:o+9,r,g,b,w); break;
+ case 9: setPixelColorRaw((_skipFirstMode)?o+5:o+4,r,g,b,w); break;
default: break;
}
}
@@ -2134,17 +2135,19 @@ void WS2812FX::clear()
bus->ClearTo(RgbColor(0));
}
-void WS2812FX::begin(bool supportWhite, uint16_t countPixels, uint8_t pin)
+void WS2812FX::begin(bool supportWhite, uint16_t countPixels, uint8_t pin, bool skipFirst)
{
if (supportWhite == _rgbwMode && countPixels == _led_count && _locked != NULL) return;
_rgbwMode = supportWhite;
+ _skipFirstMode = skipFirst;
_led_count = countPixels;
_cc_i2 = _led_count -1;
+ if (_skipFirstMode) _led_count++;
uint8_t ty = 1;
if (supportWhite) ty =2;
- bus->Begin((NeoPixelType)ty, countPixels, pin);
+ bus->Begin((NeoPixelType)ty, _led_count, pin);
if (_locked != NULL) delete _locked;
- _locked = new bool[countPixels];
+ _locked = new bool[_led_count];
}
//For some reason min and max are not declared here
diff --git a/wled00/WS2812FX.h b/wled00/WS2812FX.h
index 7a9ae891..2ea09e4f 100644
--- a/wled00/WS2812FX.h
+++ b/wled00/WS2812FX.h
@@ -199,6 +199,7 @@ class WS2812FX {
_counter_ccStep = 0;
_fastStandard = false;
_reverseMode = false;
+ _skipFirstMode = false;
_locked = NULL;
_cronixieDigits = new byte[6];
bus = new NeoPixelWrapper();
@@ -208,7 +209,7 @@ class WS2812FX {
show(void),
setPixelColor(uint16_t i, byte r, byte g, byte b),
setPixelColor(uint16_t i, byte r, byte g, byte b, byte w),
- init(bool supportWhite, uint16_t countPixels, uint8_t pin),
+ init(bool supportWhite, uint16_t countPixels, uint8_t pin, bool skipFirst),
service(void),
start(void),
stop(void),
@@ -277,7 +278,7 @@ class WS2812FX {
NeoPixelWrapper *bus;
void
- begin(bool supportWhite, uint16_t countPixels, uint8_t pin),
+ begin(bool supportWhite, uint16_t countPixels, uint8_t pin, bool skipFirst),
clear(void),
setPixelColor(uint16_t i, uint32_t c),
setPixelColorRaw(uint16_t i, byte r, byte g, byte b, byte w),
@@ -348,6 +349,7 @@ class WS2812FX {
bool
_triggered,
_rgbwMode,
+ _skipFirstMode,
_fastStandard,
_reverseMode,
_cronixieMode,
diff --git a/wled00/data/index.htm b/wled00/data/index.htm
index c79496a8..e395b3ad 100644
--- a/wled00/data/index.htm
+++ b/wled00/data/index.htm
@@ -1,8 +1,8 @@
-
+
- WLED 0.6.4
+ WLED 0.7.0
+
+
+
+Loading WLED UI...
+
+
+
+
FX 2nd Color
+
+
+
+
Sync Lights
+
+
+
+
+
+
+
+
+
+
+
+
Presets
+
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
+
+Cycle Range
+
+
+
+
+
+- Solid
+- Blink
+- Breathe
+- Wipe
+- Wipe Random
+- Random Colors
+- Easter
+- Multi Colors
+- Rainbow Full
+- Rainbow Cycle
+- Scan
+- Double Scan
+- Fade
+- Chase
+- Chase Rainbow
+- Running
+- Twinkle
+- Twinkle Random
+- Twinkle Fade
+- Twinkle Random Fade
+- Sparkle
+- Dark Sparkle
+- Dark Sparkle+
+- Strobe
+- Strobe Rainbow
+- Double Strobe
+- Blink Rainbow
+- Android
+- Dark Chase
+- Dark Chase Random
+- Dark Chase Rainbow
+- Chase Flash
+- Dark Chase Random
+- Rainbow Runner
+- Colorful
+- Traffic Light
+- Sweep Random
+- Running 2
+- Red & Blue
+- Running 2 Random
+- Scanner
+- Lighthouse
+- Fireworks
+- Fireworks Random
+- Merry Christmas
+- Fire Flicker
+- Gradient
+- Gradient Loading
+- In Out
+- In In
+- Out Out
+- Out In
+- Circus
+- Go to top
+
+
+
+
+
+
\ No newline at end of file
diff --git a/wled00/data/msg.htm b/wled00/data/msg.htm
index 5475635f..2b5bf7c3 100644
--- a/wled00/data/msg.htm
+++ b/wled00/data/msg.htm
@@ -9,7 +9,7 @@
window.location = "/settings";
}
function RP() {
- top.location.href=top.location.href;
+ top.location.href="/";
}
+
-
+
+
diff --git a/wled00/data/settings_leds.htm b/wled00/data/settings_leds.htm
index a8931e63..83a84271 100644
Binary files a/wled00/data/settings_leds.htm and b/wled00/data/settings_leds.htm differ
diff --git a/wled00/data/settings_sec.htm b/wled00/data/settings_sec.htm
index 482e2d95..c02bcd39 100644
Binary files a/wled00/data/settings_sec.htm and b/wled00/data/settings_sec.htm differ
diff --git a/wled00/data/settings_sync.htm b/wled00/data/settings_sync.htm
index 5be3944e..54a1db9b 100644
Binary files a/wled00/data/settings_sync.htm and b/wled00/data/settings_sync.htm differ
diff --git a/wled00/data/settings_ui.htm b/wled00/data/settings_ui.htm
index 24649e4c..172b01aa 100644
Binary files a/wled00/data/settings_ui.htm and b/wled00/data/settings_ui.htm differ
diff --git a/wled00/htmls00.h b/wled00/htmls00.h
index ac7efc71..b3de4829 100644
--- a/wled00/htmls00.h
+++ b/wled00/htmls00.h
@@ -1,14 +1,65 @@
/*
- * Index html
+ * Mobile UI by StormPie html
+*/
+#ifndef WLED_FLASH_512K_MODE
+const char PAGE_indexM[] PROGMEM = R"=====(
+WLED 0.7.0 Loading WLED UI...
Presets
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Cycle Range
- Solid
- Blink
- Breathe
- Wipe
- Wipe Random
- Random Colors
- Easter
- Multi Colors
- Rainbow Full
- Rainbow Cycle
- Scan
- Double Scan
- Fade
- Chase
- Chase Rainbow
- Running
- Twinkle
- Twinkle Random
- Twinkle Fade
- Twinkle Random Fade
- Sparkle
- Dark Sparkle
- Dark Sparkle+
- Strobe
- Strobe Rainbow
- Double Strobe
- Blink Rainbow
- Android
- Dark Chase
- Dark Chase Random
- Dark Chase Rainbow
- Chase Flash
- Dark Chase Random
- Rainbow Runner
- Colorful
- Traffic Light
- Sweep Random
- Running 2
- Red & Blue
- Running 2 Random
- Scanner
- Lighthouse
- Fireworks
- Fireworks Random
- Merry Christmas
- Fire Flicker
- Gradient
- Gradient Loading
- In Out
- In In
- Out Out
- Out In
- Circus
- Go to top
+)=====";
+#else
+const char PAGE_indexM[] PROGMEM = R"=====(
+The Mobile UI is not supported due to limited flash storage. Please go to IP/settings/ui and change the UI mode to "Classic".
+)=====";
+#endif
+
+/*
+ * Classic UI Index html
*/
//head0 (js)
const char PAGE_index0[] PROGMEM = R"=====(
-
+
-WLED 0.6.4
-
+WLED 0.7.0
+
)=====";
//head1 (css)
diff --git a/wled00/htmls01.h b/wled00/htmls01.h
index 0f542507..aea78045 100644
--- a/wled00/htmls01.h
+++ b/wled00/htmls01.h
@@ -7,15 +7,15 @@ body{font-family:var(--cFn),sans-serif;text-align:center;background:var(--cCol);
const char PAGE_settings0[] PROGMEM = R"=====(
-
-
-WLED Settings
+WLED Settings
)=====";
const char PAGE_settings1[] PROGMEM = R"=====(
-body{text-align:center;background:var(--cCol);height:100%;margin:0;background-attachment:fixed}button{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.3ch solid var(--bCol);display:inline-block;filter:drop-shadow(-5px -5px 5px var(--sCol));font-size:8vmin;height:13.86vh;width:95%;margin-top:2.4vh}
+body{text-align:center;background:var(--cCol);height:100%;margin:0;background-attachment:fixed}html{--h:11.55vh}button{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),Helvetica,sans-serif;border:.3ch solid var(--bCol);display:inline-block;filter:drop-shadow(-5px -5px 5px var(--sCol));font-size:8vmin;height:var(--h);width:95%;margin-top:2.4vh}
+
-
+
+
@@ -28,8 +28,7 @@ body{text-align:center;background:var(--cCol);height:100%;margin:0;background-at
const char PAGE_settings_wifi0[] PROGMEM = R"=====(
-
-
+
WiFi Settings
+
)=====";
const char PAGE_msg1[] PROGMEM = R"=====(
button{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.3ch solid var(--bCol);display:inline-block;filter:drop-shadow(-5px -5px 5px var(--sCol));font-size:20px;margin:8px;margin-top:12px}body{font-family:var(--cFn),sans-serif;text-align:center;background:var(--cCol);color:var(--tCol);line-height:200%;margin:0;background-attachment:fixed}
diff --git a/wled00/src/dependencies/webserver/WebServer.cpp b/wled00/src/dependencies/webserver/WebServer.cpp
index 8b825e67..83785bef 100644
--- a/wled00/src/dependencies/webserver/WebServer.cpp
+++ b/wled00/src/dependencies/webserver/WebServer.cpp
@@ -90,8 +90,8 @@ WebServer::~WebServer() {
void WebServer::begin() {
_currentStatus = HC_NONE;
_server.begin();
- if(!_headerKeysCount)
- collectHeaders(0, 0);
+ //if(!_headerKeysCount)
+ //collectHeaders(0, 0);
}
bool WebServer::authenticate(const char * username, const char * password){
@@ -408,15 +408,13 @@ String WebServer::header(String name) {
return String();
}
-void WebServer::collectHeaders(const char* headerKeys[], const size_t headerKeysCount) {
- _headerKeysCount = headerKeysCount + 1;
- if (_currentHeaders)
- delete[]_currentHeaders;
- _currentHeaders = new RequestArgument[_headerKeysCount];
+//Modified by Aircoookie to work for WLED
+void WebServer::collectHeaders(String headerKey) {
+ _headerKeysCount = 2;
+ if (_currentHeaders) delete[]_currentHeaders;
+ _currentHeaders = new RequestArgument[2];
_currentHeaders[0].key = AUTHORIZATION_HEADER;
- for (int i = 1; i < _headerKeysCount; i++){
- _currentHeaders[i].key = headerKeys[i-1];
- }
+ _currentHeaders[1].key = headerKey;
}
String WebServer::header(int i) {
diff --git a/wled00/src/dependencies/webserver/WebServer.h b/wled00/src/dependencies/webserver/WebServer.h
index 40807867..5a9ed0de 100644
--- a/wled00/src/dependencies/webserver/WebServer.h
+++ b/wled00/src/dependencies/webserver/WebServer.h
@@ -105,7 +105,7 @@ public:
String argName(int i); // get request argument name by number
int args(); // get arguments count
bool hasArg(String name); // check if argument exists
- void collectHeaders(const char* headerKeys[], const size_t headerKeysCount); // set the request headers to collect
+ void collectHeaders(String headerKey); // set the request headers to collect
String header(String name); // get request header value by name
String header(int i); // get request header value by number
String headerName(int i); // get request header name by number
diff --git a/wled00/wled00.ino b/wled00/wled00.ino
index 43b66f28..30108e70 100644
--- a/wled00/wled00.ino
+++ b/wled00/wled00.ino
@@ -3,10 +3,14 @@
*/
/*
* @title WLED project sketch
- * @version 0.6.4
+ * @version 0.7.0
* @author Christian Schwinne
*/
+//ESP8266-01 got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.3.0 and the setting 512K(64K SPIFFS).
+//Uncomment the following line to disable some features (currently Mobile UI) to compile for ESP8266-01
+//#define WLED_FLASH_512K_MODE
+
#include
#ifdef ARDUINO_ARCH_ESP32
#include
@@ -33,8 +37,8 @@
#include "WS2812FX.h"
//version in format yymmddb (b = daily build)
-#define VERSION 1804151
-const String versionString = "0.6.4";
+#define VERSION 1806240
+const String versionString = "0.7.0";
//AP and OTA default passwords (change them!)
String apPass = "wled1234";
@@ -54,8 +58,9 @@ byte auxDefaultState = 0; //0: input 1: high 2: low
byte auxTriggeredState = 0; //0: input 1: high 2: low
//Default CONFIG
-String serverDescription = versionString;
+String serverDescription = "WLED Light";
byte currentTheme = 0;
+byte uiConfiguration = 0; //0: auto 1: classic 2: mobile
String clientSSID = "Your_Network";
String clientPass = "";
String cmDNS = "led";
@@ -69,9 +74,9 @@ IPAddress staticIP(0, 0, 0, 0);
IPAddress staticGateway(0, 0, 0, 0);
IPAddress staticSubnet(255, 255, 255, 0);
IPAddress staticDNS(8, 8, 8, 8); //only for NTP
-bool useHSB = true, useHSBDefault = true, useRGBW = false;
+bool useHSB = true, useHSBDefault = true, useRGBW = false, autoRGBtoRGBW = false;
bool turnOnAtBoot = true;
-bool initLedsLast = false;
+bool initLedsLast = false, skipFirstLed = false;
byte bootPreset = 0;
byte colS[]{255, 159, 0};
byte colSecS[]{0, 0, 0};
@@ -81,6 +86,7 @@ byte briS = 127;
byte nightlightTargetBri = 0;
bool fadeTransition = true;
bool sweepTransition = false, sweepDirection = true;
+bool disableSecTransition = true;
uint16_t transitionDelay = 1200, transitionDelayDefault = transitionDelay;
bool reverseMode = false;
bool otaLock = false, wifiLock = false;
@@ -91,7 +97,7 @@ bool receiveNotifications = true, receiveNotificationBrightness = true, receiveN
byte briMultiplier = 100;
byte nightlightDelayMins = 60;
bool nightlightFade = true;
-uint16_t udpPort = 21324;
+uint16_t udpPort = 21324, udpRgbPort = 19446;
byte effectDefault = 0;
byte effectSpeedDefault = 75;
byte effectIntensityDefault = 128;
@@ -126,15 +132,19 @@ IPAddress hueIP = (0,0,0,0);
bool notifyHue = true;
bool hueApplyOnOff = true, hueApplyBri = true, hueApplyColor = true;
+uint16_t userVar0 = 0, userVar1 = 0;
+
//Internal vars
byte col[]{0, 0, 0};
byte colOld[]{0, 0, 0};
byte colT[]{0, 0, 0};
byte colIT[]{0, 0, 0};
byte colSec[]{0, 0, 0};
+byte colSecT[]{0, 0, 0};
+byte colSecOld[]{0, 0, 0};
byte colSecIT[]{0, 0, 0};
byte white, whiteOld, whiteT, whiteIT;
-byte whiteSec, whiteSecIT;
+byte whiteSec, whiteSecOld, whiteSecT, whiteSecIT;
byte lastRandomIndex = 0;
uint16_t transitionDelayTemp = transitionDelay;
unsigned long transitionStartTime;
@@ -153,20 +163,20 @@ byte notificationSentCallMode = 0;
bool notificationTwoRequired = false;
bool nightlightActive = false;
bool nightlightActiveOld = false;
-uint32_t nightlightDelayMs;
-byte briNlT;
+uint32_t nightlightDelayMs = 10;
+byte briNlT = 0;
byte effectCurrent = 0;
byte effectSpeed = 75;
byte effectIntensity = 128;
bool onlyAP = false;
-bool udpConnected = false;
+bool udpConnected = false, udpRgbConnected = false;
String cssCol[]={"","","","","",""};
String cssFont="Verdana";
String cssColorString="";
//NTP stuff
bool ntpConnected = false;
byte currentTimezone = 0;
-time_t local;
+time_t local = 0;
int utcOffsetSecs = 0;
//hue
@@ -207,15 +217,17 @@ bool presetCyclingEnabled = false;
byte presetCycleMin = 1, presetCycleMax = 5;
uint16_t presetCycleTime = 1250;
unsigned long presetCycledTime = 0; byte presetCycCurr = presetCycleMin;
-bool presetCycleBri, presetCycleCol, presetCycleFx;
+bool presetApplyBri = true, presetApplyCol = true, presetApplyFx = true;
+bool saveCurrPresetCycConf = false;
uint32_t arlsTimeoutMillis = 2500;
bool arlsTimeout = false;
-bool receiveDirect = true;
-unsigned long arlsTimeoutTime;
+bool receiveDirect = true, enableRealtimeUI = false;
+IPAddress realtimeIP = (0,0,0,0);
+unsigned long arlsTimeoutTime = 0;
byte auxTime = 0;
-unsigned long auxStartTime;
-bool auxActive, auxActiveBefore;
+unsigned long auxStartTime = 0;
+bool auxActive = false, auxActiveBefore = false;
bool showWelcomePage = false;
bool useGammaCorrectionBri = false;
@@ -240,7 +252,7 @@ ESP8266WebServer server(80);
#endif
HTTPClient hueClient;
ESP8266HTTPUpdateServer httpUpdater;
-WiFiUDP notifierUdp;
+WiFiUDP notifierUdp, rgbUdp;
WiFiUDP ntpUdp;
IPAddress ntpServerIP;
unsigned int ntpLocalPort = 2390;
@@ -294,14 +306,6 @@ String txd = "Please disable OTA Lock in security settings!";
void serveMessage(int,String,String,int=255);
-void down()
-{
- briT = 0;
- setAllLeds();
- DEBUG_PRINTLN("MODULE TERMINATED");
- while (1) {delay(1000);}
-}
-
void reset()
{
briT = 0;
@@ -323,7 +327,7 @@ void loop() {
yield();
handleButton();
handleNetworkTime();
- if (!otaLock && aOtaEnabled) ArduinoOTA.handle();
+ if (aOtaEnabled) ArduinoOTA.handle();
handleAlexa();
handleOverlays();
if (!arlsTimeout) //block stuff if WARLS/Adalight is enabled
diff --git a/wled00/wled01_eeprom.ino b/wled00/wled01_eeprom.ino
index 37743c06..a156efa3 100644
--- a/wled00/wled01_eeprom.ino
+++ b/wled00/wled01_eeprom.ino
@@ -148,6 +148,7 @@ void saveSettingsToEEPROM()
EEPROM.write(396, (utcOffsetSecs<0)); //is negative
EEPROM.write(397, initLedsLast);
EEPROM.write(398, (ledCount >> 8) & 0xFF);
+ EEPROM.write(399, disableSecTransition);
for (int k=0;k<6;k++){
int in = 900+k*8;
@@ -208,6 +209,25 @@ void saveSettingsToEEPROM()
EEPROM.write(2179, macroLongPress);
EEPROM.write(2180, macroCountdown);
EEPROM.write(2181, macroNl);
+
+ EEPROM.write(2200,!receiveDirect);
+ EEPROM.write(2201,enableRealtimeUI);
+ EEPROM.write(2202,uiConfiguration);
+ EEPROM.write(2203,autoRGBtoRGBW);
+ EEPROM.write(2204,skipFirstLed);
+
+ if (saveCurrPresetCycConf)
+ {
+ EEPROM.write(2205,presetCyclingEnabled);
+ EEPROM.write(2206,(presetCycleTime >> 0) & 0xFF);
+ EEPROM.write(2207,(presetCycleTime >> 8) & 0xFF);
+ EEPROM.write(2208,presetCycleMin);
+ EEPROM.write(2209,presetCycleMax);
+ EEPROM.write(2210,presetApplyBri);
+ EEPROM.write(2211,presetApplyCol);
+ EEPROM.write(2212,presetApplyFx);
+ saveCurrPresetCycConf = false;
+ }
EEPROM.commit();
}
@@ -260,7 +280,7 @@ void loadSettingsFromEEPROM(bool first)
if (apChannel > 13 || apChannel < 1) apChannel = 1;
apHide = EEPROM.read(228);
if (apHide > 1) apHide = 1;
- ledCount = ((EEPROM.read(229) << 0) & 0xFF) + ((EEPROM.read(398) << 8) & 0xFF00); if (ledCount > 1200) ledCount = 10;
+ ledCount = ((EEPROM.read(229) << 0) & 0xFF) + ((EEPROM.read(398) << 8) & 0xFF00); if (ledCount > 1200 || ledCount == 0) ledCount = 10;
notifyButton = EEPROM.read(230);
notifyTwice = EEPROM.read(231);
buttonEnabled = EEPROM.read(232);
@@ -416,14 +436,37 @@ void loadSettingsFromEEPROM(bool first)
macroCountdown = EEPROM.read(2180);
macroNl = EEPROM.read(2181);
}
+ receiveDirect = !EEPROM.read(2200);
+ enableRealtimeUI = EEPROM.read(2201);
+ uiConfiguration = EEPROM.read(2202);
+
+ #ifdef WLED_FLASH_512K_MODE
+ uiConfiguration = 1;
+ //force default UI since mobile is unavailable
+ #endif
+
+ autoRGBtoRGBW = EEPROM.read(2203);
+ skipFirstLed = EEPROM.read(2204);
+
+ if (EEPROM.read(2210) || EEPROM.read(2211) || EEPROM.read(2212))
+ {
+ presetCyclingEnabled = EEPROM.read(2205);
+ presetCycleTime = ((EEPROM.read(2206) << 0) & 0xFF) + ((EEPROM.read(2207) << 8) & 0xFF00);
+ presetCycleMin = EEPROM.read(2208);
+ presetCycleMax = EEPROM.read(2209);
+ presetApplyBri = EEPROM.read(2210);
+ presetApplyCol = EEPROM.read(2211);
+ presetApplyFx = EEPROM.read(2212);
+ }
bootPreset = EEPROM.read(389);
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);
+ disableSecTransition = EEPROM.read(399);
- //favorite setting memory (25 slots/ each 20byte)
+ //favorite setting (preset) memory (25 slots/ each 20byte)
//400 - 899 reserved
currentTheme = EEPROM.read(948);
diff --git a/wled00/wled02_xml.ino b/wled00/wled02_xml.ino
index 310e4a4c..7cefdd11 100644
--- a/wled00/wled02_xml.ino
+++ b/wled00/wled02_xml.ino
@@ -142,6 +142,7 @@ String getSettings(byte subPage)
resp += ds + "CB" + v + colS[2] +";";
resp += ds + "CA" + v + briS +";";
resp += ds + "EW" + c + useRGBW +";";
+ resp += ds + "AW" + c + autoRGBtoRGBW +";";
resp += ds + "CW" + v + whiteS +";";
resp += ds + "SR" + v + colSecS[0] +";";
resp += ds + "SG" + v + colSecS[1] +";";
@@ -158,6 +159,7 @@ String getSettings(byte subPage)
resp += ds + "TS" + c + sweepTransition +";";
resp += ds + "TI" + c + !sweepDirection +";";
resp += ds + "TD" + v + transitionDelay +";";
+ resp += ds + "T2" + c + !disableSecTransition +";";
resp += ds + "BF" + v + briMultiplier +";";
resp += ds + "TB" + v + nightlightTargetBri +";";
resp += ds + "TL" + v + nightlightDelayMins +";";
@@ -165,10 +167,12 @@ String getSettings(byte subPage)
resp += ds + "RV" + c + reverseMode +";";
resp += ds + "EI" + c + initLedsLast +";";
resp += ds + "WO" + v + arlsOffset +";";
+ resp += ds + "SL" + c + skipFirstLed +";";
}
if (subPage == 3)
{
+ resp += ds + "UI" + si + String(uiConfiguration) + ";";
resp += ds + "DS" + v + "\"" + serverDescription + "\";";
resp += ds + "MD" + c + useHSBDefault + ";";
resp += ds + "TH" + si + String(currentTheme) + ";";
@@ -188,6 +192,8 @@ String getSettings(byte subPage)
resp += ds + "SB" + c + notifyButton +";";
resp += ds + "SH" + c + notifyHue +";";
resp += ds + "S2" + c + notifyTwice +";";
+ resp += ds + "RD" + c + receiveDirect +";";
+ resp += ds + "RU" + c + enableRealtimeUI +";";
resp += ds + "AL" + c + alexaEnabled +";";
resp += ds + "AI" + v + "\"" + alexaInvocationName + "\";";
resp += ds + "SA" + c + alexaNotify +";";
diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino
index 966eb8b6..fa0c6fa2 100644
--- a/wled00/wled03_set.ino
+++ b/wled00/wled03_set.ino
@@ -121,7 +121,9 @@ void handleSettingsSet(byte subPage)
if (ledCount > 600) ledCount = 600;
#endif
}
+ ccIndex2 = ledCount -1;
useRGBW = server.hasArg("EW");
+ autoRGBtoRGBW = server.hasArg("AW");
if (server.hasArg("IS")) //ignore settings and save current brightness, colors and fx as default
{
colS[0] = col[0];
@@ -193,6 +195,7 @@ void handleSettingsSet(byte subPage)
if (i >= 0 && i <= 255) effectIntensityDefault = i;
}
}
+ saveCurrPresetCycConf = server.hasArg("PC");
turnOnAtBoot = server.hasArg("BO");
if (server.hasArg("BP"))
{
@@ -211,6 +214,7 @@ void handleSettingsSet(byte subPage)
transitionDelay = i;
}
}
+ disableSecTransition = !server.hasArg("T2");
if (server.hasArg("TB"))
{
nightlightTargetBri = server.arg("TB").toInt();
@@ -229,6 +233,7 @@ void handleSettingsSet(byte subPage)
int i = server.arg("WO").toInt();
if (i >= -255 && i <= 255) arlsOffset = i;
}
+ skipFirstLed = server.hasArg("SL");
if (server.hasArg("BF"))
{
int i = server.arg("BF").toInt();
@@ -239,6 +244,7 @@ void handleSettingsSet(byte subPage)
//UI
if (subPage == 3)
{
+ if (server.hasArg("UI")) uiConfiguration = server.arg("UI").toInt();
if (server.hasArg("DS")) serverDescription = server.arg("DS");
useHSBDefault = server.hasArg("MD");
useHSB = useHSBDefault;
@@ -267,6 +273,8 @@ void handleSettingsSet(byte subPage)
notifyDirect = notifyDirectDefault;
notifyButton = server.hasArg("SB");
notifyTwice = server.hasArg("S2");
+ receiveDirect = server.hasArg("RD");
+ enableRealtimeUI = server.hasArg("RU");
alexaEnabled = server.hasArg("AL");
if (server.hasArg("AI")) alexaInvocationName = server.arg("AI");
alexaNotify = server.hasArg("SA");
@@ -381,7 +389,7 @@ void handleSettingsSet(byte subPage)
}
}
saveSettingsToEEPROM();
- if (subPage == 2) strip.init(useRGBW,ledCount,PIN);
+ if (subPage == 2) strip.init(useRGBW,ledCount,PIN,skipFirstLed);
}
bool handleSet(String req)
@@ -703,6 +711,8 @@ bool handleSet(String req)
}
}
}
+ //deactivate nightlight if target brightness is reached
+ if (bri == nightlightTargetBri) nightlightActive = false;
//set time (unix timestamp)
pos = req.indexOf("ST=");
if (pos > 0) {
@@ -729,6 +739,12 @@ bool handleSet(String req)
if (_cc_updated) strip.setCustomChase(ccIndex1, ccIndex2, ccStart, ccNumPrimary, ccNumSecondary, ccStep, ccFromStart, ccFromEnd);
//set presets
+ pos = req.indexOf("P1="); //sets first preset for cycle
+ if (pos > 0) presetCycleMin = req.substring(pos + 3).toInt();
+
+ pos = req.indexOf("P2="); //sets last preset for cycle
+ if (pos > 0) presetCycleMax = req.substring(pos + 3).toInt();
+
if (req.indexOf("CY=") > 0) //preset cycle
{
presetCyclingEnabled = true;
@@ -736,61 +752,36 @@ bool handleSet(String req)
{
presetCyclingEnabled = false;
}
- bool all = true;
- if (req.indexOf("&PA") > 0)
- {
- presetCycleBri = true;
- all = false;
- }
- if (req.indexOf("&PC") > 0)
- {
- presetCycleCol = true;
- all = false;
- }
- if (req.indexOf("&PX") > 0)
- {
- presetCycleFx = true;
- all = false;
- }
- if (all)
- {
- presetCycleBri = true;
- presetCycleCol = true;
- presetCycleFx = true;
- }
+ presetCycCurr = presetCycleMin;
}
pos = req.indexOf("PT="); //sets cycle time in ms
if (pos > 0) {
int v = req.substring(pos + 3).toInt();
if (v > 49) presetCycleTime = v;
}
- pos = req.indexOf("P1="); //sets first preset for cycle
- if (pos > 0) presetCycleMin = req.substring(pos + 3).toInt();
-
- pos = req.indexOf("P2="); //sets last preset for cycle
- if (pos > 0) presetCycleMax = req.substring(pos + 3).toInt();
-
+ if (req.indexOf("PA=") > 0) //apply brightness from preset
+ {
+ presetApplyBri = true;
+ if (req.indexOf("PA=0") > 0) presetApplyBri = false;
+ }
+ if (req.indexOf("PC=") > 0) //apply color from preset
+ {
+ presetApplyCol = true;
+ if (req.indexOf("PC=0") > 0) presetApplyCol = false;
+ }
+ if (req.indexOf("PX=") > 0) //apply effects from preset
+ {
+ presetApplyFx = true;
+ if (req.indexOf("PX=0") > 0) presetApplyFx = false;
+ }
pos = req.indexOf("PS="); //saves current in preset
if (pos > 0) {
savePreset(req.substring(pos + 3).toInt());
}
pos = req.indexOf("PL="); //applies entire preset
if (pos > 0) {
- applyPreset(req.substring(pos + 3).toInt(), true, true, true);
- effectUpdated = true;
- }
- pos = req.indexOf("PA="); //applies brightness from preset
- if (pos > 0) {
- applyPreset(req.substring(pos + 3).toInt(), true, false, false);
- }
- pos = req.indexOf("PC="); //applies color from preset
- if (pos > 0) {
- applyPreset(req.substring(pos + 3).toInt(), false, true, false);
- }
- pos = req.indexOf("PX="); //applies effects from preset
- if (pos > 0) {
- applyPreset(req.substring(pos + 3).toInt(), false, false, true);
- effectUpdated = true;
+ applyPreset(req.substring(pos + 3).toInt(), presetApplyBri, presetApplyCol, presetApplyFx);
+ if (presetApplyFx) effectUpdated = true;
}
//cronixie
@@ -817,7 +808,16 @@ bool handleSet(String req)
if (overlayCurrent == 4) strip.setCronixieBacklight(cronixieBacklight);
overlayRefreshedTime = 0;
}
-
+ pos = req.indexOf("U0="); //user var 0
+ if (pos > 0) {
+ userVar0 = req.substring(pos + 3).toInt();
+ }
+ pos = req.indexOf("U1="); //user var 1
+ if (pos > 0) {
+ userVar1 = req.substring(pos + 3).toInt();
+ }
+ //you can add more if you need
+
//internal call, does not send XML response
pos = req.indexOf("IN");
if (pos < 1) XML_response();
diff --git a/wled00/wled04_file.ino b/wled00/wled04_file.ino
index a873b67e..f6d2b71d 100644
--- a/wled00/wled04_file.ino
+++ b/wled00/wled04_file.ino
@@ -13,7 +13,7 @@ void handleSerial()
strip.setMode(0);
}
arlsTimeout = true;
- arlsTimeoutTime = millis() + 4900;
+ arlsTimeoutTime = millis() + 5200;
delay(1);
byte hi = Serial.read();
byte ledc = Serial.read();
diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino
index 4d1a2278..2e230e7a 100644
--- a/wled00/wled05_init.ino
+++ b/wled00/wled05_init.ino
@@ -5,12 +5,12 @@
void wledInit()
{
EEPROM.begin(EEPSIZE);
- ledCount = ((EEPROM.read(229) << 0) & 0xFF) + ((EEPROM.read(398) << 8) & 0xFF00); if (ledCount > 1200) ledCount = 10;
+ ledCount = ((EEPROM.read(229) << 0) & 0xFF) + ((EEPROM.read(398) << 8) & 0xFF00); if (ledCount > 1200 || ledCount == 0) ledCount = 10;
//RMT eats up too much RAM
#ifdef ARDUINO_ARCH_ESP32
if (ledCount > 600) ledCount = 600;
#endif
- if (!EEPROM.read(397)) strip.init(EEPROM.read(372),ledCount,PIN); //quick init
+ if (!EEPROM.read(397)) strip.init(EEPROM.read(372),ledCount,PIN,EEPROM.read(2204)); //quick init
Serial.begin(115200);
Serial.setTimeout(50);
@@ -39,17 +39,11 @@ void wledInit()
hueIP[1] = WiFi.localIP()[1];
hueIP[2] = WiFi.localIP()[2];
}
-
- // Set up mDNS responder:
- if (cmDNS != NULL && !onlyAP && !MDNS.begin(cmDNS.c_str())) {
- DEBUG_PRINTLN("Error setting up MDNS responder!");
- down();
- }
- DEBUG_PRINTLN("mDNS responder started");
if (udpPort > 0 && udpPort != ntpLocalPort && WiFi.status() == WL_CONNECTED)
{
udpConnected = notifierUdp.begin(udpPort);
+ if (udpConnected && udpRgbPort != udpPort) udpRgbConnected = rgbUdp.begin(udpRgbPort);
}
if (ntpEnabled && WiFi.status() == WL_CONNECTED)
ntpConnected = ntpUdp.begin(ntpLocalPort);
@@ -170,16 +164,18 @@ void wledInit()
server.on("/freeheap", HTTP_GET, [](){
server.send(200, "text/plain", (String)ESP.getFreeHeap());
});
-
- server.on("/pdebug", HTTP_GET, [](){
- server.send(200, "text/plain", (String)presetCycleTime);
- });
server.on("/power", HTTP_GET, [](){
String val = (String)(int)strip.getPowerEstimate(ledCount,strip.getColor(),strip.getBrightness());
val += "mA currently";
serveMessage(200,val,"This is just an estimate (does not take into account several factors like effects and wire resistance). It is NOT an accurate measurement!",254);
});
+
+ server.on("/u", HTTP_GET, [](){
+ server.setContentLength(strlen_P(PAGE_usermod));
+ server.send(200, "text/html", "");
+ server.sendContent_P(PAGE_usermod);
+ });
server.on("/teapot", HTTP_GET, [](){
serveMessage(418, "418. I'm a teapot.","(Tangible Embedded Advanced Project Of Twinkling)",254);
@@ -199,8 +195,6 @@ void wledInit()
server.on("/edit", HTTP_POST, [](){ server.send(200, "text/plain", ""); }, handleFileUpload);
server.on("/list", HTTP_GET, handleFileList);
#endif
- server.on("/down", HTTP_GET, down);
- server.on("/cleareeprom", HTTP_GET, clearEEPROM);
//init ota page
httpUpdater.setup(&server);
} else
@@ -208,12 +202,6 @@ void wledInit()
server.on("/edit", HTTP_GET, [](){
serveMessage(500, "Access Denied", txd, 254);
});
- server.on("/down", HTTP_GET, [](){
- serveMessage(500, "Access Denied", txd, 254);
- });
- server.on("/cleareeprom", HTTP_GET, [](){
- serveMessage(500, "Access Denied", txd, 254);
- });
server.on("/update", HTTP_GET, [](){
serveMessage(500, "Access Denied", txd, 254);
});
@@ -231,14 +219,21 @@ void wledInit()
server.send(404, "text/plain", "Not Found");
}
});
+
+ #ifndef ARDUINO_ARCH_ESP32
+ const char * headerkeys[] = {"User-Agent"};
+ server.collectHeaders(headerkeys,sizeof(char*));
+ #else
+ String ua = "User-Agent";
+ server.collectHeaders(ua);
+ #endif
+
if (!initLedsLast) strip.service();
//init Alexa hue emulation
if (alexaEnabled) alexaInit();
server.begin();
DEBUG_PRINTLN("HTTP server started");
- // Add service to MDNS
- MDNS.addService("http", "tcp", 80);
//init ArduinoOTA
if (aOtaEnabled)
@@ -249,9 +244,20 @@ void wledInit()
#endif
DEBUG_PRINTLN("Start ArduinoOTA");
});
+ if (cmDNS.length() > 0) ArduinoOTA.setHostname(cmDNS.c_str());
ArduinoOTA.begin();
}
+ if (!initLedsLast) strip.service();
+ // Set up mDNS responder:
+ if (cmDNS.length() > 0 && !onlyAP)
+ {
+ MDNS.begin(cmDNS.c_str());
+ DEBUG_PRINTLN("mDNS responder started");
+ // Add service to MDNS
+ MDNS.addService("http", "tcp", 80);
+ }
+
if (initLedsLast) initStrip();
userBegin();
if (macroBoot>0) applyMacro(macroBoot);
@@ -261,13 +267,15 @@ void wledInit()
void initStrip()
{
// Initialize NeoPixel Strip and button
- if (initLedsLast) strip.init(useRGBW,ledCount,PIN);
+ if (initLedsLast) strip.init(useRGBW,ledCount,PIN,skipFirstLed);
strip.setReverseMode(reverseMode);
strip.setColor(0);
strip.setBrightness(255);
strip.start();
pinMode(buttonPin, INPUT_PULLUP);
+ pinMode(4,OUTPUT); //this is only needed in special cases
+ digitalWrite(4,LOW);
if (bootPreset>0) applyPreset(bootPreset, turnOnAtBoot, true, true);
colorUpdated(0);
@@ -305,7 +313,13 @@ void initCon()
}
int fail_count = 0;
if (clientSSID.length() <1 || clientSSID.equals("Your_Network")) fail_count = apWaitTimeSecs*2;
+ #ifndef ARDUINO_ARCH_ESP32
+ WiFi.hostname(serverDescription);
+ #endif
WiFi.begin(clientSSID.c_str(), clientPass.c_str());
+ #ifdef ARDUINO_ARCH_ESP32
+ WiFi.setHostname(serverDescription.c_str());
+ #endif
unsigned long lastTry = 0;
bool con = false;
while(!con)
@@ -386,19 +400,46 @@ void serveIndexOrWelcome()
}
}
+void serveRealtimeError(bool settings)
+{
+ String mesg = "The ";
+ mesg += (settings)?"settings":"WLED";
+ mesg += " UI is not available while receiving real-time data (UDP from ";
+ mesg += realtimeIP[0];
+ for (int i = 1; i < 4; i++)
+ {
+ mesg += ".";
+ mesg += realtimeIP[i];
+ }
+ mesg += ").";
+ server.send(200, "text/plain", mesg);
+}
+
void serveIndex()
{
- if (!arlsTimeout) //do not serve while receiving realtime
+ bool serveMobile = false;
+ if (uiConfiguration == 0) serveMobile = checkClientIsMobile(server.header("User-Agent"));
+ else if (uiConfiguration == 2) serveMobile = true;
+
+ if (!arlsTimeout || enableRealtimeUI) //do not serve while receiving realtime
{
- server.setContentLength(strlen_P(PAGE_index0) + cssColorString.length() + strlen_P(PAGE_index1) + strlen_P(PAGE_index2) + strlen_P(PAGE_index3));
- server.send(200, "text/html", "");
- server.sendContent_P(PAGE_index0);
- server.sendContent(cssColorString);
- server.sendContent_P(PAGE_index1);
- server.sendContent_P(PAGE_index2);
- server.sendContent_P(PAGE_index3);
+ if (serveMobile)
+ {
+ server.setContentLength(strlen_P(PAGE_indexM));
+ server.send(200, "text/html", "");
+ server.sendContent_P(PAGE_indexM);
+ } else
+ {
+ server.setContentLength(strlen_P(PAGE_index0) + cssColorString.length() + strlen_P(PAGE_index1) + strlen_P(PAGE_index2) + strlen_P(PAGE_index3));
+ server.send(200, "text/html", "");
+ server.sendContent_P(PAGE_index0);
+ server.sendContent(cssColorString);
+ server.sendContent_P(PAGE_index1);
+ server.sendContent_P(PAGE_index2);
+ server.sendContent_P(PAGE_index3);
+ }
} else {
- server.send(200, "text/plain", "The WLED UI is not available while receiving real-time data.");
+ serveRealtimeError(false);
}
}
@@ -436,7 +477,7 @@ void serveMessage(int code, String headl, String subl="", int optionType)
void serveSettings(byte subPage)
{
//0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec 255: welcomepage
- if (!arlsTimeout) //do not serve while receiving realtime
+ if (!arlsTimeout || enableRealtimeUI) //do not serve while receiving realtime
{
int pl0, pl1;
switch (subPage)
@@ -483,7 +524,7 @@ void serveSettings(byte subPage)
default: server.sendContent_P(PAGE_settings1);
}
} else {
- server.send(200, "text/plain", "The settings are not available while receiving real-time data.");
+ serveRealtimeError(true);
}
}
@@ -518,5 +559,14 @@ String getBuildInfo()
return info;
}
+bool checkClientIsMobile(String useragent)
+{
+ //to save complexity this function is not comprehensive
+ if (useragent.indexOf("Android") >= 0) return true;
+ if (useragent.indexOf("iPhone") >= 0) return true;
+ if (useragent.indexOf("iPod") >= 0) return true;
+ return false;
+}
+
diff --git a/wled00/wled06_usermod.ino b/wled00/wled06_usermod.ino
index f60d2e4f..1c75ad1d 100644
--- a/wled00/wled06_usermod.ino
+++ b/wled00/wled06_usermod.ino
@@ -4,9 +4,11 @@
* EEPROM bytes 2944 to 3071 are reserved for your custom use case.
*/
+//Use userVar0 and userVar1 (API calls &U0=,&U1=, uint16_t)
+
void userBeginPreConnection()
{
-
+
}
void userBegin()
@@ -18,4 +20,3 @@ void userLoop()
{
}
-
diff --git a/wled00/wled07_notify.ino b/wled00/wled07_notify.ino
index 924779b7..72965575 100644
--- a/wled00/wled07_notify.ino
+++ b/wled00/wled07_notify.ino
@@ -50,14 +50,60 @@ void notify(byte callMode, bool followUp=false)
notificationTwoRequired = (followUp)? false:notifyTwice;
}
+void arlsLock(uint32_t timeoutMs)
+{
+ if (!arlsTimeout){
+ strip.setRange(0, ledCount-1, 0);
+ strip.setMode(0);
+ }
+ arlsTimeout = true;
+ arlsTimeoutTime = millis() + timeoutMs;
+}
+
void handleNotifications()
{
+ //send second notification if enabled
if(udpConnected && notificationTwoRequired && millis()-notificationSentTime > 250){
notify(notificationSentCallMode,true);
}
-
+
+ //unlock strip when realtime UDP times out
+ if (arlsTimeout && millis() > arlsTimeoutTime)
+ {
+ strip.unlockAll();
+ if (bri == 0) strip.setBrightness(0);
+ arlsTimeout = false;
+ strip.setMode(effectCurrent);
+ }
+
+ //receive UDP notifications
if(udpConnected && (receiveNotifications || receiveDirect)){
uint16_t packetSize = notifierUdp.parsePacket();
+
+ //hyperion / raw RGB
+ if (!packetSize && udpRgbConnected) {
+ packetSize = rgbUdp.parsePacket();
+ if (!receiveDirect) return;
+ realtimeIP = rgbUdp.remoteIP();
+ if (packetSize > 1026 || packetSize < 3) return;
+ byte udpIn[packetSize];
+ rgbUdp.read(udpIn, packetSize);
+ arlsLock(5200);
+ uint16_t id = 0;
+ for (uint16_t i = 0; i < packetSize -2; i += 3)
+ {
+ if (useGammaCorrectionRGB)
+ {
+ strip.setPixelColor(id, gamma8[udpIn[i]], gamma8[udpIn[i+1]], gamma8[udpIn[i+2]]);
+ } else {
+ strip.setPixelColor(id, udpIn[i], udpIn[i+1], udpIn[i+2]);
+ }
+ id++; if (id >= ledCount) break;
+ }
+ strip.show();
+ return;
+ }
+
if (packetSize > 1026) return;
if(packetSize && notifierUdp.remoteIP() != WiFi.localIP()) //don't process broadcasts we send ourselves
{
@@ -107,23 +153,19 @@ void handleNotifications()
if (receiveNotificationBrightness) bri = udpIn[2];
colorUpdated(3);
}
- } else if (udpIn[0] > 0 && udpIn[0] < 4) //1 warls //2 drgb //3 drgbw
+ } else if (udpIn[0] > 0 && udpIn[0] < 4 && receiveDirect) //1 warls //2 drgb //3 drgbw
{
+ realtimeIP = notifierUdp.remoteIP();
if (packetSize > 1) {
if (udpIn[1] == 0)
{
arlsTimeout = false;
} else {
- if (!arlsTimeout){
- strip.setRange(0, ledCount-1, 0);
- strip.setMode(0);
- }
- arlsTimeout = true;
- arlsTimeoutTime = millis() + 1000*udpIn[1];
+ arlsLock(udpIn[1]*1000);
}
if (udpIn[0] == 1) //warls
{
- for (int i = 2; i < packetSize -3; i += 4)
+ for (uint16_t i = 2; i < packetSize -3; i += 4)
{
if (udpIn[i] + arlsOffset < ledCount && udpIn[i] + arlsOffset >= 0)
if (useGammaCorrectionRGB)
@@ -133,10 +175,10 @@ void handleNotifications()
strip.setPixelColor(udpIn[i] + arlsOffset, udpIn[i+1], udpIn[i+2], udpIn[i+3]);
}
}
- } else if (udpIn[0] == 2 && receiveDirect) //drgb
+ } else if (udpIn[0] == 2) //drgb
{
- int id = 0;
- for (int i = 2; i < packetSize -2; i += 3)
+ uint16_t id = 0;
+ for (uint16_t i = 2; i < packetSize -2; i += 3)
{
if (useGammaCorrectionRGB)
{
@@ -146,10 +188,10 @@ void handleNotifications()
}
id++; if (id >= ledCount) break;
}
- } else if (udpIn[0] == 3 && receiveDirect) //drgbw
+ } else if (udpIn[0] == 3) //drgbw
{
- int id = 0;
- for (int i = 2; i < packetSize -3; i += 4)
+ uint16_t id = 0;
+ for (uint16_t i = 2; i < packetSize -3; i += 4)
{
if (useGammaCorrectionRGB)
{
@@ -165,13 +207,6 @@ void handleNotifications()
}
}
}
- if (arlsTimeout && millis() > arlsTimeoutTime)
- {
- strip.unlockAll();
- if (bri == 0) strip.setBrightness(0);
- arlsTimeout = false;
- strip.setMode(effectCurrent);
- }
}
diff --git a/wled00/wled08_led.ino b/wled00/wled08_led.ino
index 7abea58a..f4e83cc9 100644
--- a/wled00/wled08_led.ino
+++ b/wled00/wled08_led.ino
@@ -12,28 +12,44 @@ void setAllLeds() {
} else {
strip.setBrightness(val);
}
+ if (disableSecTransition)
+ {
+ for (byte i = 0; i<3; i++)
+ {
+ colSecT[i] = colSec[i];
+ }
+ whiteSecT = whiteSec;
+ }
+ if (autoRGBtoRGBW)
+ {
+ colorRGBtoRGBW(colT,&whiteT);
+ colorRGBtoRGBW(colSecT,&whiteSecT);
+ }
if (useGammaCorrectionRGB)
{
strip.setColor(gamma8[colT[0]], gamma8[colT[1]], gamma8[colT[2]], gamma8[whiteT]);
- strip.setSecondaryColor(gamma8[colSec[0]], gamma8[colSec[1]], gamma8[colSec[2]], gamma8[whiteSec]);
+ strip.setSecondaryColor(gamma8[colSecT[0]], gamma8[colSecT[1]], gamma8[colSecT[2]], gamma8[whiteSecT]);
} else {
strip.setColor(colT[0], colT[1], colT[2], whiteT);
- strip.setSecondaryColor(colSec[0], colSec[1], colSec[2], whiteSec);
+ strip.setSecondaryColor(colSecT[0], colSecT[1], colSecT[2], whiteSecT);
}
}
void setLedsStandard()
{
- colOld[0] = col[0];
- colOld[1] = col[1];
- colOld[2] = col[2];
+ for (byte i = 0; i<3; i++)
+ {
+ colOld[i] = col[i];
+ colT[i] = col[i];
+ colSecOld[i] = colSec[i];
+ colSecT[i] = colSec[i];
+ }
whiteOld = white;
briOld = bri;
- colT[0] = col[0];
- colT[1] = col[1];
- colT[2] = col[2];
+ whiteSecOld = whiteSec;
whiteT = white;
briT = bri;
+ whiteSecT = whiteSec;
setAllLeds();
}
@@ -86,6 +102,10 @@ void colorUpdated(int callMode)
colOld[1] = colT[1];
colOld[2] = colT[2];
whiteOld = whiteT;
+ colSecOld[0] = colSecT[0];
+ colSecOld[1] = colSecT[1];
+ colSecOld[2] = colSecT[2];
+ whiteSecOld = whiteSecT;
briOld = briT;
tperLast = 0;
}
@@ -120,10 +140,13 @@ void handleTransitions()
tperLast = tper;
if (fadeTransition)
{
- colT[0] = colOld[0]+((col[0] - colOld[0])*tper);
- colT[1] = colOld[1]+((col[1] - colOld[1])*tper);
- colT[2] = colOld[2]+((col[2] - colOld[2])*tper);
+ for (byte i = 0; i<3; i++)
+ {
+ colT[i] = colOld[i]+((col[i] - colOld[i])*tper);
+ colSecT[i] = colSecOld[i]+((colSec[i] - colSecOld[i])*tper);
+ }
whiteT = whiteOld +((white - whiteOld )*tper);
+ whiteSecT = whiteSecOld +((whiteSec - whiteSecOld )*tper);
briT = briOld +((bri - briOld )*tper);
}
if (sweepTransition)
@@ -181,7 +204,7 @@ void handleNightlight()
//also handle preset cycle here
if (presetCyclingEnabled && (millis() - presetCycledTime > presetCycleTime))
{
- applyPreset(presetCycCurr,presetCycleBri,presetCycleCol,presetCycleFx);
+ applyPreset(presetCycCurr,presetApplyBri,presetApplyCol,presetApplyFx);
presetCycCurr++; if (presetCycCurr > presetCycleMax) presetCycCurr = presetCycleMin;
if (presetCycCurr > 25) presetCycCurr = 1;
colorUpdated(8);
diff --git a/wled00/wled14_colors.ino b/wled00/wled14_colors.ino
index 533cccc6..6f882299 100644
--- a/wled00/wled14_colors.ino
+++ b/wled00/wled14_colors.ino
@@ -115,8 +115,6 @@ void colorRGBtoXY(byte* rgb, float* xy) //rgb to coordinates (https://www.develo
xy[1] = Y / (X + Y + Z);
}
-/*//For some reason min and max are not declared here
-
float minf (float v, float w)
{
if (w > v) return v;
@@ -129,11 +127,12 @@ float maxf (float v, float w)
return v;
}
-void colorRGBtoRGBW(byte* rgb, byte* wht) //rgb to rgbw, untested and currently unused
+void colorRGBtoRGBW(byte* rgb, byte* wht) //rgb to rgbw (http://codewelt.com/rgbw)
{
- *wht = (float)minf(rgb[0],minf(rgb[1],rgb[2]))*0.95;
- rgb[0]-=wht;
- rgb[1]-=wht;
- rgb[2]-=wht;
-}*/
+ float low = minf(rgb[0],minf(rgb[1],rgb[2]));
+ float high = maxf(rgb[0],maxf(rgb[1],rgb[2]));
+ if (high < 0.1f) return;
+ float sat = 255.0f * ((high - low) / high);
+ *wht = (byte)((255.0f - sat) / 255.0f * (rgb[0] + rgb[1] + rgb[2]) / 3);
+}