WLED/wled00/wled01_eeprom.ino
cschwinne 4b31610169 Updated UI with all new palettes
FastLED effects now have default palettes per effect
Fire2012 can now use Palettes
Option for palette blending added
Added new Palettes
2018-09-11 00:20:29 +02:00

620 lines
18 KiB
C++

/*
* Methods to handle saving and loading to non-volatile memory
* EEPROM Map: https://github.com/Aircoookie/WLED/wiki/EEPROM-Map
*/
#define EEPSIZE 3072
//eeprom Version code, enables default settings instead of 0 init on update
#define EEPVER 8
//0 -> old version, default
//1 -> 0.4p 1711272 and up
//2 -> 0.4p 1711302 and up
//3 -> 0.4 1712121 and up
//4 -> 0.5.0 and up
//5 -> 0.5.1 and up
//6 -> 0.6.0 and up
//7 -> 0.7.1 and up
//8 -> 0.8.0 and up
/*
* Erase all configuration data
*/
void clearEEPROM()
{
for (int i = 0; i < EEPSIZE; i++)
{
EEPROM.write(i, 0);
}
EEPROM.commit();
}
/*
* Write configuration to flash
*/
void saveSettingsToEEPROM()
{
if (EEPROM.read(233) != 233) //set no first boot flag
{
clearEEPROM();
EEPROM.write(233, 233);
}
for (int i = 0; i < 32; ++i)
{
EEPROM.write(i, clientSSID[i]);
}
for (int i = 32; i < 96; ++i)
{
EEPROM.write(i, clientPass[i-32]);
}
for (int i = 96; i < 128; ++i)
{
EEPROM.write(i, cmDNS[i-96]);
}
for (int i = 128; i < 160; ++i)
{
EEPROM.write(i, apSSID[i-128]);
}
for (int i = 160; i < 224; ++i)
{
EEPROM.write(i, apPass[i-160]);
}
EEPROM.write(224, nightlightDelayMins);
EEPROM.write(225, nightlightFade);
EEPROM.write(226, notifyDirectDefault);
EEPROM.write(227, apChannel);
EEPROM.write(228, apHide);
EEPROM.write(229, (ledCount >> 0) & 0xFF);
EEPROM.write(230, notifyButton);
EEPROM.write(231, notifyTwice);
EEPROM.write(232, buttonEnabled);
//233 reserved for first boot flag
for (int i = 0; i<4; i++) //ip addresses
{
EEPROM.write(234+i, staticIP[i]);
EEPROM.write(238+i, staticGateway[i]);
EEPROM.write(242+i, staticSubnet[i]);
}
EEPROM.write(246, colS[0]);
EEPROM.write(247, colS[1]);
EEPROM.write(248, colS[2]);
EEPROM.write(249, briS);
EEPROM.write(250, receiveNotificationBrightness);
EEPROM.write(251, fadeTransition);
EEPROM.write(252, reverseMode);
EEPROM.write(253, (transitionDelayDefault >> 0) & 0xFF);
EEPROM.write(254, (transitionDelayDefault >> 8) & 0xFF);
EEPROM.write(255, briMultiplier);
//255,250,231,230,226 notifier bytes
for (int i = 256; i < 288; ++i)
{
EEPROM.write(i, otaPass[i-256]);
}
EEPROM.write(288, nightlightTargetBri);
EEPROM.write(289, otaLock);
EEPROM.write(290, (udpPort >> 0) & 0xFF);
EEPROM.write(291, (udpPort >> 8) & 0xFF);
for (int i = 292; i < 324; ++i)
{
EEPROM.write(i, serverDescription[i-292]);
}
EEPROM.write(324, effectDefault);
EEPROM.write(325, effectSpeedDefault);
EEPROM.write(326, effectIntensityDefault);
EEPROM.write(327, ntpEnabled);
EEPROM.write(328, currentTimezone);
EEPROM.write(329, useAMPM);
EEPROM.write(330, useGammaCorrectionBri);
EEPROM.write(331, useGammaCorrectionRGB);
EEPROM.write(332, overlayDefault);
EEPROM.write(333, alexaEnabled);
for (int i = 334; i < 366; ++i)
{
EEPROM.write(i, alexaInvocationName[i-334]);
}
EEPROM.write(366, alexaNotify);
EEPROM.write(367, (arlsOffset>=0));
EEPROM.write(368, abs(arlsOffset));
EEPROM.write(369, turnOnAtBoot);
EEPROM.write(370, useHSBDefault);
EEPROM.write(371, whiteS);
EEPROM.write(372, useRGBW);
EEPROM.write(373, effectPaletteDefault);
EEPROM.write(374, strip.paletteFade);
EEPROM.write(375, apWaitTimeSecs);
EEPROM.write(376, recoveryAPDisabled);
EEPROM.write(377, EEPVER); //eeprom was updated to latest
EEPROM.write(378, colSecS[0]);
EEPROM.write(379, colSecS[1]);
EEPROM.write(380, colSecS[2]);
EEPROM.write(381, whiteSecS);
EEPROM.write(382, strip.paletteBlend);
EEPROM.write(389, bootPreset);
EEPROM.write(390, aOtaEnabled);
EEPROM.write(391, receiveNotificationColor);
EEPROM.write(392, receiveNotificationEffects);
EEPROM.write(393, wifiLock);
EEPROM.write(394, (abs(utcOffsetSecs) >> 0) & 0xFF);
EEPROM.write(395, (abs(utcOffsetSecs) >> 8) & 0xFF);
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;
for (int i=in; i < in+8; ++i)
{
EEPROM.write(i, cssCol[i-in][k]);
}}
EEPROM.write(948,currentTheme);
for (int i = 950; i < 982; ++i)
{
EEPROM.write(i, cssFont[i-950]);
}
EEPROM.write(2048, huePollingEnabled);
//EEPROM.write(2049, hueUpdatingEnabled);
for (int i = 2050; i < 2054; ++i)
{
EEPROM.write(i, hueIP[i-2050]);
}
for (int i = 2054; i < 2100; ++i)
{
EEPROM.write(i, hueApiKey[i-2054]);
}
EEPROM.write(2100, (huePollIntervalMs >> 0) & 0xFF);
EEPROM.write(2101, (huePollIntervalMs >> 8) & 0xFF);
EEPROM.write(2102, notifyHue);
EEPROM.write(2103, hueApplyOnOff);
EEPROM.write(2104, hueApplyBri);
EEPROM.write(2105, hueApplyColor);
EEPROM.write(2106, huePollLightId);
EEPROM.write(2150, overlayMin);
EEPROM.write(2151, overlayMax);
EEPROM.write(2152, analogClock12pixel);
EEPROM.write(2153, analogClock5MinuteMarks);
EEPROM.write(2154, analogClockSecondsTrail);
EEPROM.write(2155, countdownMode);
EEPROM.write(2156, countdownYear);
EEPROM.write(2157, countdownMonth);
EEPROM.write(2158, countdownDay);
EEPROM.write(2159, countdownHour);
EEPROM.write(2160, countdownMin);
EEPROM.write(2161, countdownSec);
setCountdown();
for (int i = 2165; i < 2171; ++i)
{
EEPROM.write(i, cronixieDisplay[i-2165]);
}
EEPROM.write(2171, cronixieBacklight);
setCronixie();
EEPROM.write(2175, macroBoot);
EEPROM.write(2176, macroAlexaOn);
EEPROM.write(2177, macroAlexaOff);
EEPROM.write(2178, macroButton);
EEPROM.write(2179, macroLongPress);
EEPROM.write(2180, macroCountdown);
EEPROM.write(2181, macroNl);
EEPROM.write(2190, (e131Universe >> 0) & 0xFF);
EEPROM.write(2191, (e131Universe >> 8) & 0xFF);
EEPROM.write(2192, e131Multicast);
EEPROM.write(2193, (arlsTimeoutMillis >> 0) & 0xFF);
EEPROM.write(2194, (arlsTimeoutMillis >> 8) & 0xFF);
EEPROM.write(2195, arlsForceMaxBri);
EEPROM.write(2196, arlsDisableGammaCorrection);
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;
}
for (int i = 2220; i < 2255; ++i)
{
EEPROM.write(i, blynkApiKey[i-2220]);
}
EEPROM.commit();
}
/*
* Read all configuration from flash
*/
void loadSettingsFromEEPROM(bool first)
{
if (EEPROM.read(233) != 233) //first boot/reset to default
{
saveSettingsToEEPROM();
return;
}
int lastEEPROMversion = EEPROM.read(377); //last EEPROM version before update
for (int i = 0; i < 32; ++i)
{
clientSSID[i] = EEPROM.read(i);
if (clientSSID[i] == 0) break;
}
for (int i = 32; i < 96; ++i)
{
clientPass[i-32] = EEPROM.read(i);
if (clientPass[i-32] == 0) break;
}
for (int i = 96; i < 128; ++i)
{
cmDNS[i-96] = EEPROM.read(i);
if (cmDNS[i-96] == 0) break;
}
for (int i = 128; i < 160; ++i)
{
apSSID[i-128] = EEPROM.read(i);
if (apSSID[i-128] == 0) break;
}
for (int i = 160; i < 224; ++i)
{
apPass[i-160] = EEPROM.read(i);
if (apPass[i-160] == 0) break;
}
nightlightDelayMins = EEPROM.read(224);
nightlightFade = EEPROM.read(225);
notifyDirectDefault = EEPROM.read(226);
notifyDirect = notifyDirectDefault;
apChannel = EEPROM.read(227);
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 == 0) ledCount = 10;
notifyButton = EEPROM.read(230);
notifyTwice = EEPROM.read(231);
buttonEnabled = EEPROM.read(232);
staticIP[0] = EEPROM.read(234);
staticIP[1] = EEPROM.read(235);
staticIP[2] = EEPROM.read(236);
staticIP[3] = EEPROM.read(237);
staticGateway[0] = EEPROM.read(238);
staticGateway[1] = EEPROM.read(239);
staticGateway[2] = EEPROM.read(240);
staticGateway[3] = EEPROM.read(241);
staticSubnet[0] = EEPROM.read(242);
staticSubnet[1] = EEPROM.read(243);
staticSubnet[2] = EEPROM.read(244);
staticSubnet[3] = EEPROM.read(245);
colS[0] = EEPROM.read(246); col[0] = colS[0];
colS[1] = EEPROM.read(247); col[1] = colS[1];
colS[2] = EEPROM.read(248); col[2] = colS[2];
briS = EEPROM.read(249); bri = briS;
if (!EEPROM.read(369) && first)
{
bri = 0; briLast = briS;
}
receiveNotificationBrightness = EEPROM.read(250);
fadeTransition = EEPROM.read(251);
reverseMode = EEPROM.read(252);
transitionDelayDefault = ((EEPROM.read(253) << 0) & 0xFF) + ((EEPROM.read(254) << 8) & 0xFF00);
transitionDelay = transitionDelayDefault;
briMultiplier = EEPROM.read(255);
for (int i = 256; i < 288; ++i)
{
otaPass[i-256] = EEPROM.read(i);
if (otaPass[i-256] == 0) break;
}
nightlightTargetBri = EEPROM.read(288);
otaLock = EEPROM.read(289);
udpPort = ((EEPROM.read(290) << 0) & 0xFF) + ((EEPROM.read(291) << 8) & 0xFF00);
for (int i = 292; i < 324; ++i)
{
serverDescription[i-292] = EEPROM.read(i);
if (serverDescription[i-292] == 0) break;
}
effectDefault = EEPROM.read(324); effectCurrent = effectDefault;
effectSpeedDefault = EEPROM.read(325); effectSpeed = effectSpeedDefault;
ntpEnabled = EEPROM.read(327);
currentTimezone = EEPROM.read(328);
useAMPM = EEPROM.read(329);
useGammaCorrectionBri = EEPROM.read(330);
useGammaCorrectionRGB = EEPROM.read(331);
overlayDefault = EEPROM.read(332);
if (lastEEPROMversion < 8 && overlayDefault > 0) overlayDefault--; //overlay mode 1 (solid) was removed
alexaEnabled = EEPROM.read(333);
for (int i = 334; i < 366; ++i)
{
alexaInvocationName[i-334] = EEPROM.read(i);
if (alexaInvocationName[i-334] == 0) break;
}
alexaNotify = EEPROM.read(366);
arlsOffset = EEPROM.read(368);
if (!EEPROM.read(367)) arlsOffset = -arlsOffset;
turnOnAtBoot = EEPROM.read(369);
useHSBDefault = EEPROM.read(370);
whiteS = EEPROM.read(371); white = whiteS;
useRGBW = EEPROM.read(372);
effectPaletteDefault = EEPROM.read(373); effectPalette = effectPaletteDefault;
//374 - strip.paletteFade
if (lastEEPROMversion > 0) {
apWaitTimeSecs = EEPROM.read(375);
recoveryAPDisabled = EEPROM.read(376);
}
//377 = lastEEPROMversion
if (lastEEPROMversion > 1) {
colSecS[0] = EEPROM.read(378); colSec[0] = colSecS[0];
colSecS[1] = EEPROM.read(379); colSec[1] = colSecS[1];
colSecS[2] = EEPROM.read(380); colSec[2] = colSecS[2];
whiteSecS = EEPROM.read(381); whiteSec = whiteSecS;
}
if (lastEEPROMversion > 3) {
effectIntensityDefault = EEPROM.read(326); effectIntensity = effectIntensityDefault;
aOtaEnabled = EEPROM.read(390);
receiveNotificationColor = EEPROM.read(391);
receiveNotificationEffects = EEPROM.read(392);
for (int i = 950; i < 982; ++i)
{
cssFont[i-950] = EEPROM.read(i);
if (cssFont[i-950] == 0) break;
}
} else //keep receiving notification behavior from pre0.5.0 after update
{
receiveNotificationColor = receiveNotificationBrightness;
receiveNotificationEffects = receiveNotificationBrightness;
}
receiveNotifications = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects);
if (lastEEPROMversion > 4) {
huePollingEnabled = EEPROM.read(2048);
//hueUpdatingEnabled = EEPROM.read(2049);
for (int i = 2050; i < 2054; ++i)
{
hueIP[i-2050] = EEPROM.read(i);
}
for (int i = 2054; i < 2100; ++i)
{
hueApiKey[i-2054] = EEPROM.read(i);
if (hueApiKey[i-2054] == 0) break;
}
huePollIntervalMs = ((EEPROM.read(2100) << 0) & 0xFF) + ((EEPROM.read(2101) << 8) & 0xFF00);
notifyHue = EEPROM.read(2102);
hueApplyOnOff = EEPROM.read(2103);
hueApplyBri = EEPROM.read(2104);
hueApplyColor = EEPROM.read(2105);
huePollLightId = EEPROM.read(2106);
}
if (lastEEPROMversion > 5) {
overlayMin = EEPROM.read(2150);
overlayMax = EEPROM.read(2151);
analogClock12pixel = EEPROM.read(2152);
analogClock5MinuteMarks = EEPROM.read(2153);
analogClockSecondsTrail = EEPROM.read(2154);
countdownMode = EEPROM.read(2155);
countdownYear = EEPROM.read(2156);
countdownMonth = EEPROM.read(2157);
countdownDay = EEPROM.read(2158);
countdownHour = EEPROM.read(2159);
countdownMin = EEPROM.read(2160);
countdownSec = EEPROM.read(2161);
setCountdown();
for (int i = 2165; i < 2171; ++i)
{
cronixieDisplay[i-2165] = EEPROM.read(i);
}
cronixieBacklight = EEPROM.read(2171);
macroBoot = EEPROM.read(2175);
macroAlexaOn = EEPROM.read(2176);
macroAlexaOff = EEPROM.read(2177);
macroButton = EEPROM.read(2178);
macroLongPress = EEPROM.read(2179);
macroCountdown = EEPROM.read(2180);
macroNl = EEPROM.read(2181);
}
if (lastEEPROMversion > 6)
{
e131Universe = ((EEPROM.read(2190) << 0) & 0xFF) + ((EEPROM.read(2191) << 8) & 0xFF00);
e131Multicast = EEPROM.read(2192);
arlsTimeoutMillis = ((EEPROM.read(2193) << 0) & 0xFF) + ((EEPROM.read(2194) << 8) & 0xFF00);
arlsForceMaxBri = EEPROM.read(2195);
arlsDisableGammaCorrection = EEPROM.read(2196);
}
if (lastEEPROMversion > 7)
{
strip.paletteFade = EEPROM.read(374);
strip.paletteBlend = EEPROM.read(382);
}
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);
}
for (int i = 2220; i < 2255; ++i)
{
blynkApiKey[i-2220] = EEPROM.read(i);
if (blynkApiKey[i-2220] == 0) break;
}
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 (preset) memory (25 slots/ each 20byte)
//400 - 899 reserved
currentTheme = EEPROM.read(948);
for (int k=0;k<6;k++){
int in=900+k*8;
for (int i=in; i < in+8; ++i)
{
if (EEPROM.read(i) == 0) break;
cssCol[i-in][k] =EEPROM.read(i);
}}
//custom macro memory (16 slots/ each 64byte)
//1024-2047 reserved
//user MOD memory
//2944 - 3071 reserved
useHSB = useHSBDefault;
strip.setMode(effectCurrent);
strip.setSpeed(effectSpeed);
strip.setIntensity(effectIntensity);
strip.setPalette(effectPalette);
overlayCurrent = overlayDefault;
}
//PRESET PROTOCOL 20 bytes
//0: preset purpose byte 0:invalid 1:valid preset 1.0
//1:a 2:r 3:g 4:b 5:w 6:er 7:eg 8:eb 9:ew 10:fx 11:sx | custom chase 12:numP 13:numS 14:(0:fs 1:both 2:fe) 15:step 16:ix 17: fp 18-19:Zeros
void applyPreset(byte index, bool loadBri, bool loadCol, bool loadFX)
{
if (index == 255 || index == 0) loadSettingsFromEEPROM(false);//load boot defaults
if (index > 25 || index < 1) return;
uint16_t i = 380 + index*20;
if (EEPROM.read(i) == 0) return;
if (loadBri) bri = EEPROM.read(i+1);
if (loadCol)
{
col[0] = EEPROM.read(i+2);
col[1] = EEPROM.read(i+3);
col[2] = EEPROM.read(i+4);
white = EEPROM.read(i+5);
colSec[0] = EEPROM.read(i+6);
colSec[1] = EEPROM.read(i+7);
colSec[2] = EEPROM.read(i+8);
whiteSec = EEPROM.read(i+9);
}
if (loadFX)
{
byte lastfx = effectCurrent;
effectCurrent = EEPROM.read(i+10);
effectSpeed = EEPROM.read(i+11);
effectIntensity = EEPROM.read(i+16);
if (lastfx != effectCurrent) strip.setMode(effectCurrent);
strip.setSpeed(effectSpeed);
strip.setIntensity(effectIntensity);
strip.setPalette(effectPalette);
}
}
void savePreset(byte index)
{
if (index > 25) return;
if (index < 1) {saveSettingsToEEPROM();return;}
uint16_t i = 380 + index*20;//min400
EEPROM.write(i, 1);
EEPROM.write(i+1, bri);
EEPROM.write(i+2, col[0]);
EEPROM.write(i+3, col[1]);
EEPROM.write(i+4, col[2]);
EEPROM.write(i+5, white);
EEPROM.write(i+6, colSec[0]);
EEPROM.write(i+7, colSec[1]);
EEPROM.write(i+8, colSec[2]);
EEPROM.write(i+9, whiteSec);
EEPROM.write(i+10, effectCurrent);
EEPROM.write(i+11, effectSpeed);
EEPROM.write(i+16, effectIntensity);
EEPROM.write(i+17, effectPalette);
EEPROM.commit();
}
String loadMacro(byte index)
{
index-=1;
String m="";
if (index > 15) return m;
for (int i = 1024+64*index; i < 1088+64*index; i++)
{
if (EEPROM.read(i) == 0) break;
m += char(EEPROM.read(i));
}
if (m.charAt(0) < 65 || m.charAt(0) > 90) return ""; //do simple check if macro is valid (capital first letter)
return m;
}
void applyMacro(byte index)
{
index-=1;
if (index > 15) return;
String mc="win&";
mc += loadMacro(index+1);
mc += "&IN"; //internal, no XML response
if (!macroNotify) mc += "&NN";
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.
* To prevent that, but also disable calling macros within macros, comment the next line out.
*/
forbidden = forbidden + index;
if (mc.indexOf(forbidden) >= 0) return;
handleSet(mc);
}
void saveMacro(byte index, String mc, bool sing=true) //only commit on single save, not in settings
{
index-=1;
if (index > 15) return;
int s = 1024+index*64;
for (int i = s; i < s+64; i++)
{
EEPROM.write(i, mc.charAt(i-s));
}
if (sing) EEPROM.commit();
}