Refactored wled00.ino

Attempted to fix AP mode lags
This commit is contained in:
cschwinne 2018-09-15 17:29:01 +02:00
parent 4b31610169
commit 4715180a32
10 changed files with 298 additions and 193 deletions

View File

@ -1835,7 +1835,7 @@ uint16_t WS2812FX::mode_random_chase(void)
int b = random(6) != 0 ? (color & 0xFF) : random(256); int b = random(6) != 0 ? (color & 0xFF) : random(256);
setPixelColor(SEGMENT.start, r, g, b); setPixelColor(SEGMENT.start, r, g, b);
return 15 + (15 * (uint32_t)(255 - SEGMENT.speed)); return 15 + 2*(uint16_t)(255 - SEGMENT.speed);
} }
typedef struct Oscillator { typedef struct Oscillator {

View File

@ -1,5 +1,5 @@
/* /*
* Main sketch * Main sketch, global variable declarations
*/ */
/* /*
* @title WLED project sketch * @title WLED project sketch
@ -10,7 +10,10 @@
//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). //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 //Uncomment the following line to disable some features (currently Mobile UI) to compile for ESP8266-01
//#define WLED_FLASH_512K_MODE //#define WLED_FLASH_512K_MODE
//NOT SUPPORTED IN CURRENT VERSION
//library inclusions
#include <Arduino.h> #include <Arduino.h>
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
#include <WiFi.h> #include <WiFi.h>
@ -23,6 +26,7 @@
#include <ESP8266WebServer.h> #include <ESP8266WebServer.h>
#include <ESP8266HTTPClient.h> #include <ESP8266HTTPClient.h>
#endif #endif
#include <EEPROM.h> #include <EEPROM.h>
#include <ArduinoOTA.h> #include <ArduinoOTA.h>
#include <WiFiUDP.h> #include <WiFiUDP.h>
@ -38,141 +42,234 @@
#include "src/dependencies/blynk/BlynkSimpleEsp.h" #include "src/dependencies/blynk/BlynkSimpleEsp.h"
#include "src/dependencies/e131/E131.h" #include "src/dependencies/e131/E131.h"
//version in format yymmddb (b = daily build)
#define VERSION 1809103 //version code in format yymmddb (b = daily build)
#define VERSION 1809151
char versionString[] = "0.8.0-a"; char versionString[] = "0.8.0-a";
//AP and OTA default passwords (change them!)
//AP and OTA default passwords (for maximum change them!)
char apPass[65] = "wled1234"; char apPass[65] = "wled1234";
char otaPass[33] = "wledota"; char otaPass[33] = "wledota";
//spiffs FS only useful for debug (only ESP8266) //spiffs FS only useful for debug (only ESP8266)
//#define USEFS //#define USEFS
//to toggle usb serial debug (un)comment following line(s) //to toggle usb serial debug (un)comment following line(s)
//#define DEBUG #define DEBUG
//Hardware-settings (only changeble via code)
//strip pin changeable in NpbWrapper.h. Only change for ESP32
byte buttonPin = 0; //needs pull-up
byte auxPin = 15; //use e.g. for external relay
byte auxDefaultState = 0; //0: input 1: high 2: low
byte auxTriggeredState = 0; //0: input 1: high 2: low
//Default CONFIG //Hardware CONFIG (only changeble HERE, not at runtime)
char serverDescription[33] = "WLED Light"; //LED strip pin changeable in NpbWrapper.h. Only change for ESP32
byte currentTheme = 0; byte buttonPin = 0; //needs pull-up
byte uiConfiguration = 0; //0: auto 1: classic 2: mobile byte auxPin = 15; //debug feature, use e.g. for external relay with API call AX=
byte auxDefaultState = 0; //0: input 1: high 2: low
byte auxTriggeredState = 0; //0: input 1: high 2: low
char ntpServerName[] = "0.wled.pool.ntp.org"; //NTP server to use
//WiFi CONFIG (all these can be changed via web UI, no need to set them here)
char clientSSID[33] = "Your_Network"; char clientSSID[33] = "Your_Network";
char clientPass[65] = ""; char clientPass[65] = "";
char cmDNS[33] = "led"; char cmDNS[33] = "led"; //mDNS address (x.local), only for Apple and Windows, if Bonjour installed
uint16_t ledCount = 10; //lowered to prevent accidental overcurrent char apSSID[65] = ""; //AP off by default (unless setup)
char apSSID[65] = ""; //AP off by default (unless setup) byte apChannel = 1; //2.4GHz WiFi AP channel (1-13)
byte apChannel = 1; byte apHide = 0; //hidden AP SSID
byte apHide = 0; byte apWaitTimeSecs = 32; //time to wait for connection before opening AP
byte apWaitTimeSecs = 32; bool recoveryAPDisabled = false; //never open AP (not recommended)
bool recoveryAPDisabled = false; IPAddress staticIP(0, 0, 0, 0); //static IP of ESP
IPAddress staticIP(0, 0, 0, 0); IPAddress staticGateway(0, 0, 0, 0); //gateway (router) IP
IPAddress staticGateway(0, 0, 0, 0); IPAddress staticSubnet(255, 255, 255, 0); //most common subnet in home networks
IPAddress staticSubnet(255, 255, 255, 0); IPAddress staticDNS(8, 8, 8, 8); //only for NTP, google DNS server
IPAddress staticDNS(8, 8, 8, 8); //only for NTP
bool useHSB = true, useHSBDefault = true, useRGBW = false, autoRGBtoRGBW = false;
bool turnOnAtBoot = true; //LED CONFIG
bool initLedsLast = false, skipFirstLed = false; uint16_t ledCount = 10; //lowered to prevent accidental overcurrent
byte bootPreset = 0; bool useRGBW = false; //SK6812 strips can contain an extra White channel
byte colS[]{255, 159, 0}; bool autoRGBtoRGBW = false; //if RGBW enabled, calculate White channel from RGB
byte colSecS[]{0, 0, 0}; bool turnOnAtBoot = true; //turn on LEDs at power-up
byte whiteS = 0; byte bootPreset = 0; //save preset to load after power-up
byte whiteSecS = 0;
byte briS = 127; byte colS[]{255, 159, 0}; //default RGB color
byte nightlightTargetBri = 0; byte colSecS[]{0, 0, 0}; //default RGB secondary color
bool fadeTransition = true; byte whiteS = 0; //default White channel
bool disableSecTransition = true; byte whiteSecS = 0; //default secondary White channel
uint16_t transitionDelay = 1200, transitionDelayDefault = transitionDelay; byte briS = 127; //default brightness
bool reverseMode = false; byte effectDefault = 0;
bool otaLock = false, wifiLock = false;
bool aOtaEnabled = true;
bool buttonEnabled = true;
bool notifyDirect = true, notifyButton = true, notifyDirectDefault = true, alexaNotify = false, macroNotify = false, notifyTwice = false;
bool receiveNotifications = true, receiveNotificationBrightness = true, receiveNotificationColor = true, receiveNotificationEffects = true;
byte briMultiplier = 100;
byte nightlightDelayMins = 60;
bool nightlightFade = true;
uint16_t udpPort = 21324, udpRgbPort = 19446;
byte effectDefault = 0;
byte effectSpeedDefault = 75; byte effectSpeedDefault = 75;
byte effectIntensityDefault = 128; byte effectIntensityDefault = 128; //intensity is supported on some effects as an additional parameter (e.g. for blink you can change the duty cycle)
byte effectPaletteDefault = 0; byte effectPaletteDefault = 0; //palette is supported on the FastLED effects, otherwise it has no effect
//NTP stuff
bool ntpEnabled = false;
char ntpServerName[] = "0.wled.pool.ntp.org";
//alexa bool useGammaCorrectionBri = false; //gamma correct brightness (not recommended)
bool alexaEnabled = true; bool useGammaCorrectionRGB = true; //gamma correct colors (strongly recommended)
char alexaInvocationName[33] = "Light";
byte macroBoot = 0, macroNl = 0; byte nightlightTargetBri = 0; //brightness after nightlight is over
byte nightlightDelayMins = 60;
bool nightlightFade = true; //if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over
bool fadeTransition = true; //enable crossfading color transition
bool enableSecTransition = true; //also enable transition for secondary color
uint16_t transitionDelay = 1200; //default crossfade duration in ms
bool reverseMode = false; //flip entire LED strip (reverses all effect directions)
bool initLedsLast = false; //turn on LEDs only after WiFi connected/AP open
bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater)
byte briMultiplier = 100; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127)
//User Interface CONFIG
char serverDescription[33] = "WLED Light"; //Name of module
byte currentTheme = 0; //UI theme index for settings and classic UI
byte uiConfiguration = 0; //0: automatic (depends on user-agent) 1: classic UI 2: mobile UI
bool useHSB = true; //classic UI: use HSB sliders instead of RGB by default
char cssFont[33] = "Verdana"; //font to use in classic UI
bool useHSBDefault = useHSB;
//Sync CONFIG
bool buttonEnabled = true;
uint16_t udpPort = 21324; //WLED notifier default port
uint16_t udpRgbPort = 19446; //Hyperion port
bool receiveNotificationBrightness = true; //apply brightness from incoming notifications
bool receiveNotificationColor = true; //apply color
bool receiveNotificationEffects = true; //apply effects setup
bool notifyDirect = true; //send notification if change via UI or HTTP API
bool notifyButton = true;
bool notifyAlexa = false; //send notification if updated via Alexa
bool notifyMacro = false; //send notification for macro
bool notifyHue = true; //send notification if Hue light changes
bool notifyTwice = false; //notifications use UDP: enable if devices don't sync reliably
bool alexaEnabled = true; //enable device discovery by Amazon Echo
char alexaInvocationName[33] = "Light"; //speech control name of device. Choose something voice-to-text can understand
char blynkApiKey[36] = ""; //Auth token for Blynk server. If empty, no connection will be made
uint16_t realtimeTimeoutMs = 2500; //ms timeout of realtime mode before returning to normal mode
int arlsOffset = 0; //realtime LED offset
bool receiveDirect = true; //receive UDP realtime
bool enableRealtimeUI = false; //web UI accessible during realtime mode (works on ESP32, lags out ESP8266)
bool arlsDisableGammaCorrection = true; //activate if gamma correction is handled by the source
bool arlsForceMaxBri = false; //enable to force max brightness if source has very dark colors that would be black
bool e131Enabled = true; //settings for E1.31 (sACN) protocol
byte e131Universe = 1;
bool e131Multicast = false;
bool huePollingEnabled = false; //poll hue bridge for light state
uint16_t huePollIntervalMs = 2500; //low values (< 1sec) may cause lag but offer quicker response
char hueApiKey[65] = "api"; //key token will be obtained from bridge
byte huePollLightId = 1; //ID of hue lamp to sync to. Find the ID in the hue app ("about" section)
IPAddress hueIP = (0,0,0,0); //IP address of the bridge
bool hueApplyOnOff = true;
bool hueApplyBri = true;
bool hueApplyColor = true;
//Time CONFIG
bool ntpEnabled = false; //get internet time. Only required if you use clock overlays or time-activated macros
bool useAMPM = false; //12h/24h clock format
byte currentTimezone = 0; //Timezone ID. Refer to timezones array in wled10_ntp.ino
int utcOffsetSecs = 0; //Seconds to offset from UTC before timzone calculation
byte overlayDefault = 0; //0: no overlay 1: analog clock 2: single-digit clocl 3: cronixie
byte overlayMin = 0, overlayMax = ledCount-1; //boundaries of overlay mode
byte analogClock12pixel = 0; //The pixel in your strip where "midnight" would be
bool analogClockSecondsTrail = false; //Display seconds as trail of LEDs instead of a single pixel
bool analogClock5MinuteMarks = false; //Light pixels at every 5-minute position
char cronixieDisplay[] = "HHMMSS"; //Cronixie Display mask. See wled13_cronixie.ino
bool cronixieBacklight = true; //Allow digits to be back-illuminated
bool countdownMode = false; //Clock will count down towards date
byte countdownYear = 19, countdownMonth = 1; //Countdown target date, year is last two digits
byte countdownDay = 1, countdownHour = 0;
byte countdownMin = 0, countdownSec = 0;
byte macroBoot = 0; //macro loaded after startup
byte macroNl = 0; //after nightlight delay over
byte macroCountdown = 0;
byte macroAlexaOn = 0, macroAlexaOff = 0; byte macroAlexaOn = 0, macroAlexaOff = 0;
byte macroButton = 0, macroCountdown = 0, macroLongPress = 0; byte macroButton = 0, macroLongPress = 0;
unsigned long countdownTime = 1514764800L;
//hue //Security CONFIG
bool huePollingEnabled = false, hueAttempt = false; bool otaLock = false; //prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks
uint16_t huePollIntervalMs = 2500; bool wifiLock = false; //prevents access to WiFi settings when OTA lock is enabled
char hueApiKey[65] = "api"; bool aOtaEnabled = true; //ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on
byte huePollLightId = 1;
IPAddress hueIP = (0,0,0,0);
bool notifyHue = true;
bool hueApplyOnOff = true, hueApplyBri = true, hueApplyColor = true;
uint16_t userVar0 = 0, userVar1 = 0; uint16_t userVar0 = 0, userVar1 = 0;
//Internal vars
byte col[]{255, 159, 0};
byte colOld[]{0, 0, 0}; //internal global variable declarations
byte colT[]{0, 0, 0}; //color
byte colIT[]{0, 0, 0}; byte col[]{255, 159, 0}; //target RGB color
byte colOld[]{0, 0, 0}; //color before transition
byte colT[]{0, 0, 0}; //current color
byte colIT[]{0, 0, 0}; //color that was last sent to LEDs
byte colSec[]{0, 0, 0}; byte colSec[]{0, 0, 0};
byte colSecT[]{0, 0, 0}; byte colSecT[]{0, 0, 0};
byte colSecOld[]{0, 0, 0}; byte colSecOld[]{0, 0, 0};
byte colSecIT[]{0, 0, 0}; byte colSecIT[]{0, 0, 0};
byte white = 0, whiteOld, whiteT, whiteIT; byte white = whiteS, whiteOld, whiteT, whiteIT;
byte whiteSec = 0, whiteSecOld, whiteSecT, whiteSecIT; byte whiteSec = whiteSecS, whiteSecOld, whiteSecT, whiteSecIT;
byte lastRandomIndex = 0;
byte lastRandomIndex = 0; //used to save last random color so the new one is not the same
//transitions
bool transitionActive = false;
uint16_t transitionDelayDefault = transitionDelay;
uint16_t transitionDelayTemp = transitionDelay; uint16_t transitionDelayTemp = transitionDelay;
unsigned long transitionStartTime; unsigned long transitionStartTime;
unsigned long nightlightStartTime; float tperLast = 0; //crossfade transition progress, 0.0f - 1.0f
float tperLast = 0;
byte bri = 127; //nightlight
byte briOld = 0;
byte briT = 0;
byte briIT = 0;
byte briLast = 127;
bool transitionActive = false;
bool buttonPressedBefore = false;
unsigned long buttonPressedTime = 0;
unsigned long notificationSentTime = 0;
byte notificationSentCallMode = 0;
bool notificationTwoRequired = false;
bool nightlightActive = false; bool nightlightActive = false;
bool nightlightActiveOld = false; bool nightlightActiveOld = false;
uint32_t nightlightDelayMs = 10; uint32_t nightlightDelayMs = 10;
byte briNlT = 0; unsigned long nightlightStartTime;
byte effectCurrent = 0; byte briNlT = 0; //current nightlight brightness
byte effectSpeed = 75;
byte effectIntensity = 128; //brightness
byte effectPalette = 0; byte bri = briS;
bool onlyAP = false; byte briOld = 0;
byte briT = 0;
byte briIT = 0;
byte briLast = 127; //brightness before turned off. Used for toggle function
//button
bool buttonPressedBefore = false;
unsigned long buttonPressedTime = 0;
//notifications
bool notifyDirectDefault = notifyDirect;
bool receiveNotifications = true;
unsigned long notificationSentTime = 0;
byte notificationSentCallMode = 0;
bool notificationTwoRequired = false;
//effects
byte effectCurrent = effectDefault;
byte effectSpeed = effectSpeedDefault;
byte effectIntensity = effectIntensityDefault;
byte effectPalette = effectPaletteDefault;
//network
bool onlyAP = false; //only Access Point active, no connection to home network
bool udpConnected = false, udpRgbConnected = false; bool udpConnected = false, udpRgbConnected = false;
//ui style
char cssCol[9][5]={"","","","","",""}; char cssCol[9][5]={"","","","","",""};
char cssFont[33]="Verdana";
String cssColorString=""; String cssColorString="";
//NTP stuff bool showWelcomePage = false;
bool ntpConnected = false;
byte currentTimezone = 0;
time_t local = 0;
int utcOffsetSecs = 0;
//hue //hue
char hueError[25] = "Inactive"; char hueError[25] = "Inactive";
@ -180,25 +277,12 @@ uint16_t hueFailCount = 0;
float hueXLast=0, hueYLast=0; float hueXLast=0, hueYLast=0;
uint16_t hueHueLast=0, hueCtLast=0; uint16_t hueHueLast=0, hueCtLast=0;
byte hueSatLast=0, hueBriLast=0; byte hueSatLast=0, hueBriLast=0;
long hueLastRequestSent = 0; unsigned long hueLastRequestSent = 0;
uint32_t huePollIntervalMsTemp = huePollIntervalMs; unsigned long huePollIntervalMsTemp = huePollIntervalMs;
bool hueAttempt = false;
//blynk //overlays
char blynkApiKey[36] = ""; byte overlayCurrent = overlayDefault;
bool blynkEnabled = false;
//e1.31
bool e131Enabled = true;
byte e131Universe = 1;
bool e131Multicast = false;
//overlay stuff
byte overlayDefault = 0;
byte overlayCurrent = 0;
byte overlayMin = 0, overlayMax = ledCount-1;
byte analogClock12pixel = 0;
bool analogClockSecondsTrail = false;
bool analogClock5MinuteMarks = false;
byte overlaySpeed = 200; byte overlaySpeed = 200;
unsigned long overlayRefreshMs = 200; unsigned long overlayRefreshMs = 200;
unsigned long overlayRefreshedTime; unsigned long overlayRefreshedTime;
@ -206,37 +290,36 @@ int overlayArr[6];
uint16_t overlayDur[6]; uint16_t overlayDur[6];
uint16_t overlayPauseDur[6]; uint16_t overlayPauseDur[6];
int nixieClockI = -1; int nixieClockI = -1;
bool nixiePause; bool nixiePause = false;
byte countdownYear=19, countdownMonth=1, countdownDay=1, countdownHour=0, countdownMin=0, countdownSec=0; //year is actual year -2000
bool countdownOverTriggered = true;
//cronixie //cronixie
char cronixieDisplay[] = "HHMMSS";
byte dP[]{0,0,0,0,0,0}; byte dP[]{0,0,0,0,0,0};
bool useAMPM = false;
bool cronixieBacklight = true;
bool countdownMode = false;
bool cronixieInit = false; bool cronixieInit = false;
//countdown
unsigned long countdownTime = 1514764800L;
bool countdownOverTriggered = true;
//blynk
bool blynkEnabled = false;
//preset cycling
bool presetCyclingEnabled = false; bool presetCyclingEnabled = false;
byte presetCycleMin = 1, presetCycleMax = 5; byte presetCycleMin = 1, presetCycleMax = 5;
uint16_t presetCycleTime = 1250; uint16_t presetCycleTime = 1250;
unsigned long presetCycledTime = 0; byte presetCycCurr = presetCycleMin; unsigned long presetCycledTime = 0; byte presetCycCurr = presetCycleMin;
bool presetApplyBri = true, presetApplyCol = true, presetApplyFx = true; bool presetApplyBri = true, presetApplyCol = true, presetApplyFx = true;
bool saveCurrPresetCycConf = false; bool saveCurrPresetCycConf = false;
uint16_t arlsTimeoutMillis = 2500;
bool arlsTimeout = false; //realtime
bool receiveDirect = true, enableRealtimeUI = false; bool realtimeActive = false;
bool arlsDisableGammaCorrection = true, arlsForceMaxBri = false;
IPAddress realtimeIP = (0,0,0,0); IPAddress realtimeIP = (0,0,0,0);
unsigned long arlsTimeoutTime = 0; unsigned long realtimeTimeout = 0;
//auxiliary debug pin
byte auxTime = 0; byte auxTime = 0;
unsigned long auxStartTime = 0; unsigned long auxStartTime = 0;
bool auxActive = false, auxActiveBefore = false; bool auxActive = false, auxActiveBefore = false;
bool showWelcomePage = false;
bool useGammaCorrectionBri = false;
bool useGammaCorrectionRGB = true;
int arlsOffset = 0;
//alexa udp //alexa udp
WiFiUDP UDP; WiFiUDP UDP;
@ -248,50 +331,58 @@ String escapedMac;
DNSServer dnsServer; DNSServer dnsServer;
bool dnsActive = false; bool dnsActive = false;
//network time
bool ntpConnected = false;
time_t local = 0;
unsigned long ntpLastSyncTime = 999000000L;
unsigned long ntpPacketSentTime = 999000000L;
IPAddress ntpServerIP;
unsigned int ntpLocalPort = 2390;
#define NTP_PACKET_SIZE 48
//string temp buffer //string temp buffer
#define OMAX 1750 #define OMAX 1750
char obuf[OMAX]; char obuf[OMAX];
uint16_t olen = 0; uint16_t olen = 0;
//server library objects
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
WebServer server(80); WebServer server(80);
#else #else
ESP8266WebServer server(80); ESP8266WebServer server(80);
#endif #endif
E131 e131;
HTTPClient hueClient; HTTPClient hueClient;
ESP8266HTTPUpdateServer httpUpdater; ESP8266HTTPUpdateServer httpUpdater;
//udp interface objects
WiFiUDP notifierUdp, rgbUdp; WiFiUDP notifierUdp, rgbUdp;
WiFiUDP ntpUdp; WiFiUDP ntpUdp;
IPAddress ntpServerIP; E131 e131;
unsigned int ntpLocalPort = 2390;
#define NTP_PACKET_SIZE 48
unsigned long ntpLastSyncTime = 999000000L;
unsigned long ntpPacketSentTime = 999000000L;
//led fx library object
WS2812FX strip = WS2812FX(); WS2812FX strip = WS2812FX();
//debug macros
#ifdef DEBUG #ifdef DEBUG
#define DEBUG_PRINT(x) Serial.print (x) #define DEBUG_PRINT(x) Serial.print (x)
#define DEBUG_PRINTLN(x) Serial.println (x) #define DEBUG_PRINTLN(x) Serial.println (x)
#define DEBUG_PRINTF(x) Serial.printf (x) #define DEBUG_PRINTF(x) Serial.printf (x)
unsigned long debugTime = 0;
int lastWifiState = 3;
unsigned long wifiStateChangedTime = 0;
#else #else
#define DEBUG_PRINT(x) #define DEBUG_PRINT(x)
#define DEBUG_PRINTLN(x) #define DEBUG_PRINTLN(x)
#define DEBUG_PRINTF(x) #define DEBUG_PRINTF(x)
#endif #endif
//filesystem
#ifdef USEFS #ifdef USEFS
#include <FS.h>; #include <FS.h>;
File fsUploadFile; File fsUploadFile;
#endif #endif
#ifdef DEBUG //gamma 2.4 lookup table used for color correction
long debugTime = 0;
int lastWifiState = 3;
long wifiStateChangedTime = 0;
#endif
const byte gamma8[] = { const byte gamma8[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
@ -312,8 +403,11 @@ const byte gamma8[] = {
String txd = "Please disable OTA Lock in security settings!"; String txd = "Please disable OTA Lock in security settings!";
//function prototypes
void serveMessage(int,String,String,int=255); void serveMessage(int,String,String,int=255);
//turns all LEDs off and restarts ESP
void reset() void reset()
{ {
briT = 0; briT = 0;
@ -322,7 +416,9 @@ void reset()
ESP.restart(); ESP.restart();
} }
bool oappend(char* txt) //append new c string to temp buffer efficiently
//append new c string to temp buffer efficiently
bool oappend(char* txt)
{ {
uint16_t len = strlen(txt); uint16_t len = strlen(txt);
if (olen + len >= OMAX) return false; //buffer full if (olen + len >= OMAX) return false; //buffer full
@ -331,30 +427,38 @@ bool oappend(char* txt) //append new c string to temp buffer efficiently
return true; return true;
} }
bool oappendi(int i) //append new number to temp buffer efficiently
//append new number to temp buffer efficiently
bool oappendi(int i)
{ {
char s[11]; char s[11];
sprintf(s,"%ld", i); sprintf(s,"%ld", i);
return oappend(s); return oappend(s);
} }
//boot starts here
void setup() { void setup() {
wledInit(); wledInit();
} }
//main program loop
void loop() { void loop() {
server.handleClient(); server.handleClient();
handleSerial(); handleSerial();
handleNotifications(); handleNotifications();
handleTransitions(); handleTransitions();
userLoop(); userLoop();
yield(); yield();
handleButton(); handleButton();
handleNetworkTime(); handleNetworkTime();
if (aOtaEnabled) ArduinoOTA.handle(); if (aOtaEnabled) ArduinoOTA.handle();
handleAlexa(); handleAlexa();
handleOverlays(); handleOverlays();
if (!arlsTimeout) //block stuff if WARLS/Adalight is enabled
if (!realtimeActive) //block stuff if WARLS/Adalight is enabled
{ {
if (dnsActive) dnsServer.processNextRequest(); if (dnsActive) dnsServer.processNextRequest();
handleHue(); handleHue();
@ -363,7 +467,7 @@ void loop() {
if (briT) strip.service(); //do not update strip if off, prevents flicker on ESP32 if (briT) strip.service(); //do not update strip if off, prevents flicker on ESP32
} }
//DEBUG //DEBUG serial logging
#ifdef DEBUG #ifdef DEBUG
if (millis() - debugTime > 5000) if (millis() - debugTime > 5000)
{ {
@ -377,7 +481,7 @@ void loop() {
wifiStateChangedTime = millis(); wifiStateChangedTime = millis();
} }
lastWifiState = WiFi.status(); lastWifiState = WiFi.status();
DEBUG_PRINT("Wifi state: "); DEBUG_PRINTLN(wifiStateChangedTime); DEBUG_PRINT("State time: "); DEBUG_PRINTLN(wifiStateChangedTime);
DEBUG_PRINT("NTP last sync: "); DEBUG_PRINTLN(ntpLastSyncTime); DEBUG_PRINT("NTP last sync: "); DEBUG_PRINTLN(ntpLastSyncTime);
DEBUG_PRINT("Client IP: "); DEBUG_PRINTLN(WiFi.localIP()); DEBUG_PRINT("Client IP: "); DEBUG_PRINTLN(WiFi.localIP());
debugTime = millis(); debugTime = millis();

View File

@ -113,7 +113,7 @@ void saveSettingsToEEPROM()
{ {
EEPROM.write(i, alexaInvocationName[i-334]); EEPROM.write(i, alexaInvocationName[i-334]);
} }
EEPROM.write(366, alexaNotify); EEPROM.write(366, notifyAlexa);
EEPROM.write(367, (arlsOffset>=0)); EEPROM.write(367, (arlsOffset>=0));
EEPROM.write(368, abs(arlsOffset)); EEPROM.write(368, abs(arlsOffset));
EEPROM.write(369, turnOnAtBoot); EEPROM.write(369, turnOnAtBoot);
@ -141,7 +141,7 @@ void saveSettingsToEEPROM()
EEPROM.write(396, (utcOffsetSecs<0)); //is negative EEPROM.write(396, (utcOffsetSecs<0)); //is negative
EEPROM.write(397, initLedsLast); EEPROM.write(397, initLedsLast);
EEPROM.write(398, (ledCount >> 8) & 0xFF); EEPROM.write(398, (ledCount >> 8) & 0xFF);
EEPROM.write(399, disableSecTransition); EEPROM.write(399, !enableSecTransition);
for (int k=0;k<6;k++){ for (int k=0;k<6;k++){
int in = 900+k*8; int in = 900+k*8;
@ -206,8 +206,8 @@ void saveSettingsToEEPROM()
EEPROM.write(2190, (e131Universe >> 0) & 0xFF); EEPROM.write(2190, (e131Universe >> 0) & 0xFF);
EEPROM.write(2191, (e131Universe >> 8) & 0xFF); EEPROM.write(2191, (e131Universe >> 8) & 0xFF);
EEPROM.write(2192, e131Multicast); EEPROM.write(2192, e131Multicast);
EEPROM.write(2193, (arlsTimeoutMillis >> 0) & 0xFF); EEPROM.write(2193, (realtimeTimeoutMs >> 0) & 0xFF);
EEPROM.write(2194, (arlsTimeoutMillis >> 8) & 0xFF); EEPROM.write(2194, (realtimeTimeoutMs >> 8) & 0xFF);
EEPROM.write(2195, arlsForceMaxBri); EEPROM.write(2195, arlsForceMaxBri);
EEPROM.write(2196, arlsDisableGammaCorrection); EEPROM.write(2196, arlsDisableGammaCorrection);
@ -349,7 +349,7 @@ void loadSettingsFromEEPROM(bool first)
alexaInvocationName[i-334] = EEPROM.read(i); alexaInvocationName[i-334] = EEPROM.read(i);
if (alexaInvocationName[i-334] == 0) break; if (alexaInvocationName[i-334] == 0) break;
} }
alexaNotify = EEPROM.read(366); notifyAlexa = EEPROM.read(366);
arlsOffset = EEPROM.read(368); arlsOffset = EEPROM.read(368);
if (!EEPROM.read(367)) arlsOffset = -arlsOffset; if (!EEPROM.read(367)) arlsOffset = -arlsOffset;
turnOnAtBoot = EEPROM.read(369); turnOnAtBoot = EEPROM.read(369);
@ -441,7 +441,7 @@ void loadSettingsFromEEPROM(bool first)
{ {
e131Universe = ((EEPROM.read(2190) << 0) & 0xFF) + ((EEPROM.read(2191) << 8) & 0xFF00); e131Universe = ((EEPROM.read(2190) << 0) & 0xFF) + ((EEPROM.read(2191) << 8) & 0xFF00);
e131Multicast = EEPROM.read(2192); e131Multicast = EEPROM.read(2192);
arlsTimeoutMillis = ((EEPROM.read(2193) << 0) & 0xFF) + ((EEPROM.read(2194) << 8) & 0xFF00); realtimeTimeoutMs = ((EEPROM.read(2193) << 0) & 0xFF) + ((EEPROM.read(2194) << 8) & 0xFF00);
arlsForceMaxBri = EEPROM.read(2195); arlsForceMaxBri = EEPROM.read(2195);
arlsDisableGammaCorrection = EEPROM.read(2196); arlsDisableGammaCorrection = EEPROM.read(2196);
} }
@ -486,7 +486,7 @@ void loadSettingsFromEEPROM(bool first)
utcOffsetSecs = ((EEPROM.read(394) << 0) & 0xFF) + ((EEPROM.read(395) << 8) & 0xFF00); utcOffsetSecs = ((EEPROM.read(394) << 0) & 0xFF) + ((EEPROM.read(395) << 8) & 0xFF00);
if (EEPROM.read(396)) utcOffsetSecs = -utcOffsetSecs; //negative if (EEPROM.read(396)) utcOffsetSecs = -utcOffsetSecs; //negative
initLedsLast = EEPROM.read(397); initLedsLast = EEPROM.read(397);
disableSecTransition = EEPROM.read(399); enableSecTransition = !EEPROM.read(399);
//favorite setting (preset) memory (25 slots/ each 20byte) //favorite setting (preset) memory (25 slots/ each 20byte)
//400 - 899 reserved //400 - 899 reserved
@ -594,7 +594,7 @@ void applyMacro(byte index)
String mc="win&"; String mc="win&";
mc += loadMacro(index+1); mc += loadMacro(index+1);
mc += "&IN"; //internal, no XML response mc += "&IN"; //internal, no XML response
if (!macroNotify) mc += "&NN"; if (!notifyMacro) mc += "&NN";
String forbidden = "&M="; //dont apply if called by the macro itself to prevent loop String forbidden = "&M="; //dont apply if called by the macro itself to prevent loop
/* /*
* NOTE: loop is still possible if you call a different macro from a macro, which then calls the first macro again. * NOTE: loop is still possible if you call a different macro from a macro, which then calls the first macro again.

View File

@ -193,7 +193,7 @@ void getSettingsJS(byte subPage) //get values for settings form in javascript
sappend('c',"TF",fadeTransition); sappend('c',"TF",fadeTransition);
sappend('v',"TD",transitionDelay); sappend('v',"TD",transitionDelay);
sappend('c',"PF",strip.paletteFade); sappend('c',"PF",strip.paletteFade);
sappend('c',"T2",!disableSecTransition); sappend('c',"T2",enableSecTransition);
sappend('v',"BF",briMultiplier); sappend('v',"BF",briMultiplier);
sappend('v',"TB",nightlightTargetBri); sappend('v',"TB",nightlightTargetBri);
sappend('v',"TL",nightlightDelayMins); sappend('v',"TL",nightlightDelayMins);
@ -233,14 +233,14 @@ void getSettingsJS(byte subPage) //get values for settings form in javascript
sappend('c',"RD",receiveDirect); sappend('c',"RD",receiveDirect);
sappend('c',"EM",e131Multicast); sappend('c',"EM",e131Multicast);
sappend('v',"EU",e131Universe); sappend('v',"EU",e131Universe);
sappend('v',"ET",arlsTimeoutMillis); sappend('v',"ET",realtimeTimeoutMs);
sappend('c',"FB",arlsForceMaxBri); sappend('c',"FB",arlsForceMaxBri);
sappend('c',"RG",arlsDisableGammaCorrection); sappend('c',"RG",arlsDisableGammaCorrection);
sappend('v',"WO",arlsOffset); sappend('v',"WO",arlsOffset);
sappend('c',"RU",enableRealtimeUI); sappend('c',"RU",enableRealtimeUI);
sappend('c',"AL",alexaEnabled); sappend('c',"AL",alexaEnabled);
sappends('s',"AI",alexaInvocationName); sappends('s',"AI",alexaInvocationName);
sappend('c',"SA",alexaNotify); sappend('c',"SA",notifyAlexa);
sappends('s',"BK",(char*)((blynkEnabled)?"Hidden":"")); sappends('s',"BK",(char*)((blynkEnabled)?"Hidden":""));
sappend('v',"H0",hueIP[0]); sappend('v',"H0",hueIP[0]);
sappend('v',"H1",hueIP[1]); sappend('v',"H1",hueIP[1]);

View File

@ -172,7 +172,7 @@ void handleSettingsSet(byte subPage)
} }
} }
strip.paletteFade = server.hasArg("PF"); strip.paletteFade = server.hasArg("PF");
disableSecTransition = !server.hasArg("T2"); enableSecTransition = server.hasArg("T2");
if (server.hasArg("TB")) if (server.hasArg("TB"))
{ {
nightlightTargetBri = server.arg("TB").toInt(); nightlightTargetBri = server.arg("TB").toInt();
@ -239,12 +239,12 @@ void handleSettingsSet(byte subPage)
if (server.hasArg("EU")) if (server.hasArg("EU"))
{ {
int i = server.arg("EU").toInt(); int i = server.arg("EU").toInt();
if (i > 0 && i <= 63999) arlsTimeoutMillis = i; if (i > 0 && i <= 63999) realtimeTimeoutMs = i;
} }
if (server.hasArg("ET")) if (server.hasArg("ET"))
{ {
int i = server.arg("ET").toInt(); int i = server.arg("ET").toInt();
if (i > 99 && i <= 65000) arlsTimeoutMillis = i; if (i > 99 && i <= 65000) realtimeTimeoutMs = i;
} }
arlsForceMaxBri = server.hasArg("FB"); arlsForceMaxBri = server.hasArg("FB");
arlsDisableGammaCorrection = server.hasArg("RG"); arlsDisableGammaCorrection = server.hasArg("RG");
@ -256,7 +256,7 @@ void handleSettingsSet(byte subPage)
enableRealtimeUI = server.hasArg("RU"); enableRealtimeUI = server.hasArg("RU");
alexaEnabled = server.hasArg("AL"); alexaEnabled = server.hasArg("AL");
if (server.hasArg("AI")) strcpy(alexaInvocationName,server.arg("AI").c_str()); if (server.hasArg("AI")) strcpy(alexaInvocationName,server.arg("AI").c_str());
alexaNotify = server.hasArg("SA"); notifyAlexa = server.hasArg("SA");
if (server.hasArg("BK") && !server.arg("BK").equals("Hidden")) {strcpy(blynkApiKey,server.arg("BK").c_str()); initBlynk(blynkApiKey);} if (server.hasArg("BK") && !server.arg("BK").equals("Hidden")) {strcpy(blynkApiKey,server.arg("BK").c_str()); initBlynk(blynkApiKey);}
notifyHue = server.hasArg("SH"); notifyHue = server.hasArg("SH");
for (int i=0;i<4;i++){ for (int i=0;i<4;i++){

View File

@ -7,12 +7,12 @@ void handleSerial()
{ {
if (Serial.find("Ada")) if (Serial.find("Ada"))
{ {
if (!arlsTimeout){ if (!realtimeActive){
if (bri == 0) strip.setBrightness(briLast); if (bri == 0) strip.setBrightness(briLast);
strip.setRange(0, ledCount-1, 0); strip.setRange(0, ledCount-1, 0);
strip.setMode(0); strip.setMode(0);
} }
arlsLock(arlsTimeoutMillis); arlsLock(realtimeTimeoutMs);
delay(1); delay(1);
byte hi = Serial.read(); byte hi = Serial.read();
byte ledc = Serial.read(); byte ledc = Serial.read();

View File

@ -52,7 +52,7 @@ void wledInit()
//start captive portal //start captive portal
if (onlyAP || strlen(apSSID) > 0) if (onlyAP || strlen(apSSID) > 0)
{ {
dnsServer.setErrorReplyCode(DNSReplyCode::NoError); //dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
dnsServer.start(53, "*", WiFi.softAPIP()); dnsServer.start(53, "*", WiFi.softAPIP());
dnsActive = true; dnsActive = true;
} }
@ -260,9 +260,11 @@ void wledInit()
MDNS.addService("http", "tcp", 80); MDNS.addService("http", "tcp", 80);
} }
initBlynk(blynkApiKey); if (!onlyAP)
{
initE131(); initBlynk(blynkApiKey);
initE131();
}
if (initLedsLast) initStrip(); if (initLedsLast) initStrip();
userBegin(); userBegin();
@ -428,7 +430,7 @@ void serveIndex()
if (uiConfiguration == 0) serveMobile = checkClientIsMobile(server.header("User-Agent")); if (uiConfiguration == 0) serveMobile = checkClientIsMobile(server.header("User-Agent"));
else if (uiConfiguration == 2) serveMobile = true; else if (uiConfiguration == 2) serveMobile = true;
if (!arlsTimeout || enableRealtimeUI) //do not serve while receiving realtime if (!realtimeActive || enableRealtimeUI) //do not serve while receiving realtime
{ {
if (serveMobile) if (serveMobile)
{ {
@ -484,7 +486,7 @@ void serveMessage(int code, String headl, String subl="", int optionType)
void serveSettings(byte subPage) void serveSettings(byte subPage)
{ {
//0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec 255: welcomepage //0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec 255: welcomepage
if (!arlsTimeout || enableRealtimeUI) //do not serve while receiving realtime if (!realtimeActive || enableRealtimeUI) //do not serve while receiving realtime
{ {
int pl0, pl1; int pl0, pl1;
switch (subPage) switch (subPage)

View File

@ -54,12 +54,12 @@ void notify(byte callMode, bool followUp=false)
void arlsLock(uint32_t timeoutMs) void arlsLock(uint32_t timeoutMs)
{ {
if (!arlsTimeout){ if (!realtimeActive){
strip.setRange(0, ledCount-1, 0); strip.setRange(0, ledCount-1, 0);
strip.setMode(0); strip.setMode(0);
} }
arlsTimeout = true; realtimeActive = true;
arlsTimeoutTime = millis() + timeoutMs; realtimeTimeout = millis() + timeoutMs;
if (arlsForceMaxBri) strip.setBrightness(255); if (arlsForceMaxBri) strip.setBrightness(255);
} }
@ -83,7 +83,7 @@ void handleNotifications()
if(e131Enabled) { if(e131Enabled) {
uint16_t len = e131.parsePacket(); uint16_t len = e131.parsePacket();
if (len && e131.universe == e131Universe) { if (len && e131.universe == e131Universe) {
arlsLock(arlsTimeoutMillis); arlsLock(realtimeTimeoutMs);
if (len > ledCount) len = ledCount; if (len > ledCount) len = ledCount;
for (uint16_t i = 0; i < len; i++) { for (uint16_t i = 0; i < len; i++) {
int j = i * 3; int j = i * 3;
@ -95,11 +95,11 @@ void handleNotifications()
} }
//unlock strip when realtime UDP times out //unlock strip when realtime UDP times out
if (arlsTimeout && millis() > arlsTimeoutTime) if (realtimeActive && millis() > realtimeTimeout)
{ {
strip.unlockAll(); strip.unlockAll();
strip.setBrightness(bri); strip.setBrightness(bri);
arlsTimeout = false; realtimeActive = false;
strip.setMode(effectCurrent); strip.setMode(effectCurrent);
realtimeIP[0] = 0; realtimeIP[0] = 0;
} }
@ -116,7 +116,7 @@ void handleNotifications()
if (packetSize > 1026 || packetSize < 3) return; if (packetSize > 1026 || packetSize < 3) return;
byte udpIn[packetSize]; byte udpIn[packetSize];
rgbUdp.read(udpIn, packetSize); rgbUdp.read(udpIn, packetSize);
arlsLock(arlsTimeoutMillis); arlsLock(realtimeTimeoutMs);
uint16_t id = 0; uint16_t id = 0;
for (uint16_t i = 0; i < packetSize -2; i += 3) for (uint16_t i = 0; i < packetSize -2; i += 3)
{ {
@ -133,7 +133,7 @@ void handleNotifications()
{ {
byte udpIn[packetSize]; byte udpIn[packetSize];
notifierUdp.read(udpIn, packetSize); notifierUdp.read(udpIn, packetSize);
if (udpIn[0] == 0 && !arlsTimeout && receiveNotifications) //wled notifier, block if realtime packets active if (udpIn[0] == 0 && !realtimeActive && receiveNotifications) //wled notifier, block if realtime packets active
{ {
if (receiveNotificationColor) if (receiveNotificationColor)
{ {
@ -188,7 +188,7 @@ void handleNotifications()
if (packetSize > 1) { if (packetSize > 1) {
if (udpIn[1] == 0) if (udpIn[1] == 0)
{ {
arlsTimeout = false; realtimeActive = false;
} else { } else {
arlsLock(udpIn[1]*1000); arlsLock(udpIn[1]*1000);
} }

View File

@ -3,7 +3,7 @@
*/ */
void setAllLeds() { void setAllLeds() {
if (!arlsTimeout || !arlsForceMaxBri) if (!realtimeActive || !arlsForceMaxBri)
{ {
double d = briT*briMultiplier; double d = briT*briMultiplier;
int val = d/100; int val = d/100;
@ -15,7 +15,7 @@ void setAllLeds() {
strip.setBrightness(val); strip.setBrightness(val);
} }
} }
if (disableSecTransition) if (!enableSecTransition)
{ {
for (byte i = 0; i<3; i++) for (byte i = 0; i<3; i++)
{ {
@ -152,7 +152,6 @@ void handleTransitions()
whiteSecT = whiteSecOld +((whiteSec - whiteSecOld )*tper); whiteSecT = whiteSecOld +((whiteSec - whiteSecOld )*tper);
briT = briOld +((bri - briOld )*tper); briT = briOld +((bri - briOld )*tper);
} }
//TODO: properly remove sweep transition
if (fadeTransition) setAllLeds(); if (fadeTransition) setAllLeds();
} }
} }

View File

@ -47,7 +47,7 @@ void alexaOn()
{ {
if (macroAlexaOn == 0) if (macroAlexaOn == 0)
{ {
handleSet((alexaNotify)?"win&T=1&IN":"win&T=1&NN&IN"); handleSet((notifyAlexa)?"win&T=1&IN":"win&T=1&NN&IN");
} else } else
{ {
applyMacro(macroAlexaOn); applyMacro(macroAlexaOn);
@ -60,7 +60,7 @@ void alexaOff()
{ {
if (macroAlexaOff == 0) if (macroAlexaOff == 0)
{ {
handleSet((alexaNotify)?"win&T=0&IN":"win&T=0&NN&IN"); handleSet((notifyAlexa)?"win&T=0&IN":"win&T=0&NN&IN");
} else } else
{ {
applyMacro(macroAlexaOff); applyMacro(macroAlexaOff);
@ -78,7 +78,7 @@ void alexaDim(byte briL)
server.send(200, "application/json", obuf); server.send(200, "application/json", obuf);
String ct = (alexaNotify)?"win&IN&A=":"win&NN&IN&A="; String ct = (notifyAlexa)?"win&IN&A=":"win&NN&IN&A=";
if (briL < 255) if (briL < 255)
{ {
ct = ct + (briL+1); ct = ct + (briL+1);