From 72f203e4faf15544d4aca28366ec87f5a7964569 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Fri, 20 Jul 2018 19:35:31 +0200 Subject: [PATCH] Started optimizing code by converting String to char* --- wled00/wled00.ino | 32 ++- wled00/wled02_xml.ino | 429 ++++++++++++++++++++++------------------- wled00/wled05_init.ino | 48 +++-- 3 files changed, 284 insertions(+), 225 deletions(-) diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 10bfef78..2bf18c50 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -38,12 +38,12 @@ #include "src/dependencies/blynk/BlynkSimpleEsp.h" //version in format yymmddb (b = daily build) -#define VERSION 1807122 -const String versionString = "0.7.1"; +#define VERSION 1807201 +char versionString[] = "0.7.1"; //AP and OTA default passwords (change them!) -String apPass = "wled1234"; -String otaPass = "wledota"; +String apPass[65] = "wled1234"; +String otaPass[33] = "wledota"; //spiffs FS only useful for debug (only ESP8266) //#define USEFS @@ -224,7 +224,6 @@ uint16_t presetCycleTime = 1250; unsigned long presetCycledTime = 0; byte presetCycCurr = presetCycleMin; bool presetApplyBri = true, presetApplyCol = true, presetApplyFx = true; bool saveCurrPresetCycConf = false; - uint32_t arlsTimeoutMillis = 2500; bool arlsTimeout = false; bool receiveDirect = true, enableRealtimeUI = false; @@ -250,6 +249,11 @@ String escapedMac; DNSServer dnsServer; bool dnsActive = false; +//string temp buffer +#define OMAX 1750 +char obuf[OMAX]; +uint16_t olen = 0; + #ifdef ARDUINO_ARCH_ESP32 WebServer server(80); #else @@ -319,7 +323,25 @@ void reset() ESP.restart(); } +bool oappend(char* txt) //append new c string to temp buffer efficiently +{ + uint16_t len = strlen(txt); + if (olen + len >= OMAX) return false; //buffer full + strcpy(obuf + olen, txt); + olen += len; + return true; +} + +bool oappendi(int i) //append new number to temp buffer efficiently +{ + char s[11]; + sprintf(s,"%ld", i); + return oappend(s); +} + void setup() { + //init strings to defaults + wledInit(); } diff --git a/wled00/wled02_xml.ino b/wled00/wled02_xml.ino index 80767204..31592a98 100644 --- a/wled00/wled02_xml.ino +++ b/wled00/wled02_xml.ino @@ -4,258 +4,287 @@ void XML_response() { - String resp; - resp = resp + ""; - resp = resp + ""; - resp = resp + ""; + olen = 0; + oappend(""); if (nightlightActive && nightlightFade) { - resp = resp + briT; + oappendi(briT); } else { - resp = resp + bri; + oappendi(bri); } - resp = resp + ""; + oappend(""); for (int i = 0; i < 3; i++) { - resp = resp + ""; - resp = resp + col[i]; - resp = resp + ""; + oappend(""); + oappendi(col[i]); + oappend(""); } - resp = resp + ""; - resp = resp + notifyDirect; - resp = resp + ""; - resp = resp + receiveNotifications; - resp = resp + ""; - resp = resp + nightlightActive; - resp = resp + ""; - resp = resp + nightlightFade; - resp = resp + ""; - resp = resp + nightlightDelayMins; - resp = resp + ""; - resp = resp + nightlightTargetBri; - resp = resp + ""; - resp = resp + effectCurrent; - resp = resp + ""; - resp = resp + effectSpeed; - resp = resp + ""; - resp = resp + effectIntensity; - resp = resp + ""; + oappend(""); + oappendi(notifyDirect); + oappend(""); + oappendi(receiveNotifications); + oappend(""); + oappendi(nightlightActive); + oappend(""); + oappendi(nightlightFade); + oappend(""); + oappendi(nightlightDelayMins); + oappend(""); + oappendi(nightlightTargetBri); + oappend(""); + oappendi(effectCurrent); + oappend(""); + oappendi(effectSpeed); + oappend(""); + oappendi(effectIntensity); + oappend(""); if (useRGBW && !autoRGBtoRGBW) { - resp = resp + white; + oappendi(white); } else { - resp = resp + "-1"; + oappend("-1"); } - resp = resp + ""; - resp = resp + useHSB; - resp = resp + ""; - resp = resp + serverDescription; - resp = resp + ""; - resp = resp + ""; - server.send(200, "text/xml", resp); + oappend(""); + oappendi(useHSB); + oappend(""); + oappend((char*)serverDescription.c_str()); + oappend(""); + server.send(200, "text/xml", obuf); } -String getSettings(byte subPage) +void sappend(char stype, char* key, int val) //append a setting to string buffer +{ + char ds[] = "d.Sf."; + + switch(stype) + { + case 'c': //checkbox + oappend(ds); + oappend(key); + oappend(".checked="); + oappendi(val); + oappend(";"); + break; + case 'v': //numeric + oappend(ds); + oappend(key); + oappend(".value="); + oappendi(val); + oappend(";"); + break; + case 's': //string (we can interpret val as char*) + oappend(ds); + oappend(key); + oappend(".value=\""); + oappend((char*)val); + oappend("\";"); + break; + case 'i': //selectedIndex + oappend(ds); + oappend(key); + oappend(".selectedIndex="); + oappendi(val); + oappend(";"); + break; + case 'm': //message + oappend("d.getElementsByClassName"); + oappend(key); + oappend(".innerHTML=\""); + oappend((char*)val); + oappend("\";"); + break; + } +} + +void getSettingsJS(byte subPage) //get values for settings form in javascript { //0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec DEBUG_PRINT("settings resp"); DEBUG_PRINTLN(subPage); - String resp = ""; - if (subPage <1 || subPage >6) return resp; - - resp.reserve(1000); - String ds = "d.Sf."; - String dg = "d.getElementsByClassName"; - String v = ".value="; - String c = ".checked="; - String ih = ".innerHTML="; - String si = ".selectedIndex="; + olen = 0; obuf[0] = 0; //clear buffer + if (subPage <1 || subPage >6) return; if (subPage == 1) { - resp += ds + "CS" + v + "\"" + clientSSID + "\";"; - resp += ds + "CP" + v + "\""; - for (int i = 0; i < clientPass.length(); i++) + sappend('s',"CS",(int)clientSSID.c_str()); + + byte l = clientPass.length(); + char fpass[l+1]; //fill password field with *** + fpass[l] = 0; + memset(fpass,'*',l); + sappend('s',"CP",(int)fpass); + + char k[3]; k[2] = 0; //IP addresses + for (int i = 0; i<4; i++) { - resp += "*"; + k[1] = 48+i; //ascii 0,1,2,3 + k[0] = 'I'; sappend('v',k,staticIP[i]); + k[0] = 'G'; sappend('v',k,staticGateway[i]); + k[0] = 'S'; sappend('v',k,staticSubnet[i]); } - resp += "\";"; - resp += ds + "I0" + v + staticIP[0] +";"; - resp += ds + "I1" + v + staticIP[1] +";"; - resp += ds + "I2" + v + staticIP[2] +";"; - resp += ds + "I3" + v + staticIP[3] +";"; - resp += ds + "G0" + v + staticGateway[0] +";"; - resp += ds + "G1" + v + staticGateway[1] +";"; - resp += ds + "G2" + v + staticGateway[2] +";"; - resp += ds + "G3" + v + staticGateway[3] +";"; - resp += ds + "S0" + v + staticSubnet[0] +";"; - resp += ds + "S1" + v + staticSubnet[1] +";"; - resp += ds + "S2" + v + staticSubnet[2] +";"; - resp += ds + "S3" + v + staticSubnet[3] +";"; - resp += ds + "CM" + v + "\"" + cmDNS + "\";"; - resp += ds + "AT" + v + apWaitTimeSecs +";"; - resp += ds + "AS" + v + "\"" + apSSID + "\";"; - resp += ds + "AH" + c + apHide + ";"; - resp += ds + "AP" + v + "\""; - for (int i = 0; i < apPass.length(); i++) + + sappend('s',"CM",(int)cmDNS.c_str()); + sappend('v',"AT",apWaitTimeSecs); + sappend('s',"AS",(int)apSSID.c_str()); + sappend('c',"AH",apHide); + + l = apPass.length(); + char fapass[l+1]; //fill password field with *** + fapass[l] = 0; + memset(fapass,'*',l); + sappend('s',"AP",(int)fapass); + + sappend('v',"AC",apChannel); + + if (WiFi.localIP()[0] != 0) //is connected { - resp += "*"; - } - resp += "\";"; - resp += ds + "AC" + v + apChannel +";"; - resp += dg + "(\"sip\")[0]" + ih + "\""; - if (!WiFi.localIP()[0] == 0) - { - resp += WiFi.localIP()[0]; - resp += + "."; - resp += WiFi.localIP()[1]; - resp += "."; - resp += WiFi.localIP()[2]; - resp += "."; - resp += WiFi.localIP()[3]; + sappend('m',"(\"sip\")[0]",(int)WiFi.localIP().toString().c_str()); } else { - resp += "Not connected"; + sappend('m',"(\"sip\")[0]",(int)"Not connected"); } - resp += "\";"; - resp += dg + "(\"sip\")[1]" + ih + "\""; - if (!WiFi.softAPIP()[0] == 0) + + if (WiFi.softAPIP()[0] != 0) //is active { - resp += WiFi.softAPIP()[0]; - resp += + "."; - resp += WiFi.softAPIP()[1]; - resp += "."; - resp += WiFi.softAPIP()[2]; - resp += "."; - resp += WiFi.softAPIP()[3]; + sappend('m',"(\"sip\")[1]",(int)WiFi.softAPIP().toString().c_str()); } else { - resp += "Not active"; + sappend('m',"(\"sip\")[1]",(int)"Not active"); } - resp += "\";"; } if (subPage == 2) { - resp += ds + "LC" + v + ledCount +";"; - resp += ds + "CR" + v + colS[0] +";"; - resp += ds + "CG" + v + colS[1] +";"; - 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] +";"; - resp += ds + "SB" + v + colSecS[2] +";"; - resp += ds + "SW" + v + whiteSecS +";"; - resp += ds + "BO" + c + turnOnAtBoot +";"; - resp += ds + "BP" + v + bootPreset +";"; - resp += ds + "FX" + v + effectDefault +";"; - resp += ds + "SX" + v + effectSpeedDefault +";"; - resp += ds + "IX" + v + effectIntensityDefault +";"; - resp += ds + "GB" + c + useGammaCorrectionBri +";"; - resp += ds + "GC" + c + useGammaCorrectionRGB +";"; - resp += ds + "TF" + c + fadeTransition +";"; - 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 +";"; - resp += ds + "TW" + c + nightlightFade +";"; - resp += ds + "RV" + c + reverseMode +";"; - resp += ds + "EI" + c + initLedsLast +";"; - resp += ds + "WO" + v + arlsOffset +";"; - resp += ds + "SL" + c + skipFirstLed +";"; + sappend('v',"LC",ledCount); + sappend('v',"CR",colS[0]); + sappend('v',"CG",colS[1]); + sappend('v',"CB",colS[2]); + sappend('v',"CA",briS); + sappend('c',"EW",useRGBW); + sappend('c',"AW",autoRGBtoRGBW); + sappend('v',"CW",whiteS); + sappend('v',"SR",colSecS[0]); + sappend('v',"SG",colSecS[1]); + sappend('v',"SB",colSecS[2]); + sappend('v',"SW",whiteSecS); + sappend('c',"BO",turnOnAtBoot); + sappend('v',"BP",bootPreset); + sappend('v',"FX",effectDefault); + sappend('v',"SX",effectSpeedDefault); + sappend('v',"IX",effectIntensityDefault); + sappend('c',"GB",useGammaCorrectionBri); + sappend('c',"GC",useGammaCorrectionRGB); + sappend('c',"TF",fadeTransition); + sappend('c',"TS",sweepTransition); + sappend('c',"TI",!sweepDirection); + sappend('v',"TD",transitionDelay); + sappend('c',"T2",!disableSecTransition); + sappend('v',"BF",briMultiplier); + sappend('v',"TB",nightlightTargetBri); + sappend('v',"TL",nightlightDelayMins); + sappend('c',"TW",nightlightFade); + sappend('c',"RV",reverseMode); + sappend('c',"EI",initLedsLast); + sappend('v',"WO",arlsOffset); + sappend('c',"SL",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) + ";"; - for(int i=0;i<6;i++) - resp += ds + "C" + i + v + "\"" + cssCol[i] + "\";"; - resp += ds + "CF" + v + "\"" + cssFont + "\";"; + sappend('i',"UI",uiConfiguration); + sappend('s',"DS",(int)serverDescription.c_str()); + sappend('c',"MD",useHSBDefault); + sappend('i',"TH",currentTheme); + char k[3]; k[0] = 'C'; k[2] = 0; //keys + for (int i=0; i<6; i++) + { + k[1] = 48+i; //ascii 0,1,2,3,4,5 + sappend('s',k,(int)cssCol[i].c_str()); + } + sappend('s',"CF",(int)cssFont.c_str()); } if (subPage == 4) { - resp += ds + "BT" + c + buttonEnabled +";"; - resp += ds + "UP" + v + udpPort +";"; - resp += ds + "RB" + c + receiveNotificationBrightness +";"; - resp += ds + "RC" + c + receiveNotificationColor +";"; - resp += ds + "RX" + c + receiveNotificationEffects +";"; - resp += ds + "SD" + c + notifyDirectDefault +";"; - 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 +";"; - resp += ds + "BK" + v + "\"" + ((blynkEnabled)?"Hidden":"") + "\";"; - resp += ds + "H0" + v + hueIP[0] +";"; - resp += ds + "H1" + v + hueIP[1] +";"; - resp += ds + "H2" + v + hueIP[2] +";"; - resp += ds + "H3" + v + hueIP[3] +";"; - resp += ds + "HL" + v + huePollLightId +";"; - resp += ds + "HI" + v + huePollIntervalMs +";"; - resp += ds + "HP" + c + huePollingEnabled +";"; - resp += ds + "HO" + c + hueApplyOnOff +";"; - resp += ds + "HB" + c + hueApplyBri +";"; - resp += ds + "HC" + c + hueApplyColor +";"; - resp += dg + "(\"hms\")[0]" + ih + "\"" + hueError + "\";"; + sappend('c',"BT",buttonEnabled); + sappend('v',"UP",udpPort); + sappend('c',"RB",receiveNotificationBrightness); + sappend('c',"RC",receiveNotificationColor); + sappend('c',"RX",receiveNotificationEffects); + sappend('c',"SD",notifyDirectDefault); + sappend('c',"SB",notifyButton); + sappend('c',"SH",notifyHue); + sappend('c',"S2",notifyTwice); + sappend('c',"RD",receiveDirect); + sappend('c',"RU",enableRealtimeUI); + sappend('c',"AL",alexaEnabled); + sappend('s',"AI",(int)alexaInvocationName.c_str()); + sappend('c',"SA",alexaNotify); + sappend('s',"BK",(int)((blynkEnabled)?"Hidden":"")); + sappend('v',"H0",hueIP[0]); + sappend('v',"H1",hueIP[1]); + sappend('v',"H2",hueIP[2]); + sappend('v',"H3",hueIP[3]); + sappend('v',"HL",huePollLightId); + sappend('v',"HI",huePollIntervalMs); + sappend('c',"HP",huePollingEnabled); + sappend('c',"HO",hueApplyOnOff); + sappend('c',"HB",hueApplyBri); + sappend('c',"HC",hueApplyColor); + sappend('m',"(\"hms\")[0]",(int)hueError.c_str()); } if (subPage == 5) { - resp += ds + "NT" + c + ntpEnabled +";"; - resp += ds + "CF" + c + !useAMPM +";"; - resp += ds + "TZ" + si + String(currentTimezone) + ";"; - resp += ds + "UO" + v + utcOffsetSecs +";"; - resp += dg + "(\"times\")[0]" + ih + "\"" + getTimeString() + "\";"; - resp += ds + "OL" + si + String(overlayCurrent) + ";"; - resp += ds + "O1" + v + overlayMin +";"; - resp += ds + "O2" + v + overlayMax +";"; - resp += ds + "OM" + v + analogClock12pixel +";"; - resp += ds + "OS" + c + analogClockSecondsTrail +";"; - resp += ds + "O5" + c + analogClock5MinuteMarks +";"; - resp += ds + "CX" + v + "\"" + cronixieDisplay + "\";"; - resp += ds + "CB" + c + cronixieBacklight +";"; - resp += ds + "CE" + c + countdownMode +";"; - resp += ds + "CY" + v + countdownYear +";"; - resp += ds + "CI" + v + countdownMonth +";"; - resp += ds + "CD" + v + countdownDay +";"; - resp += ds + "CH" + v + countdownHour +";"; - resp += ds + "CM" + v + countdownMin +";"; - resp += ds + "CS" + v + countdownSec +";"; + sappend('c',"NT",ntpEnabled); + sappend('c',"CF",!useAMPM); + sappend('i',"TZ",currentTimezone); + sappend('v',"UO",utcOffsetSecs); + sappend('m',"(\"times\")[0]",(int)getTimeString().c_str()); + sappend('i',"OL",overlayCurrent); + sappend('v',"O1",overlayMin); + sappend('v',"O2",overlayMax); + sappend('v',"OM",analogClock12pixel); + sappend('c',"OS",analogClockSecondsTrail); + sappend('c',"O5",analogClock5MinuteMarks); + sappend('s',"CX",(int)cronixieDisplay.c_str()); + sappend('c',"CB",cronixieBacklight); + sappend('c',"CE",countdownMode); + sappend('v',"CY",countdownYear); + sappend('v',"CI",countdownMonth); + sappend('v',"CD",countdownDay); + sappend('v',"CH",countdownHour); + sappend('v',"CM",countdownMin); + sappend('v',"CS",countdownSec); + + char k[4]; k[0]= 'M'; for (int i=1;i<17;i++) { - resp += ds + "M" + String(i) + v + "\"" + loadMacro(i) + "\";"; + sprintf(k+1,"%i",i); + sappend('s',k,(int)loadMacro(i).c_str()); } - resp += ds + "MB" + v + macroBoot +";"; - resp += ds + "A0" + v + macroAlexaOn +";"; - resp += ds + "A1" + v + macroAlexaOff +";"; - resp += ds + "MP" + v + macroButton +";"; - resp += ds + "ML" + v + macroLongPress +";"; - resp += ds + "MC" + v + macroCountdown +";"; - resp += ds + "MN" + v + macroNl +";"; + + sappend('v',"MB",macroBoot); + sappend('v',"A0",macroAlexaOn); + sappend('v',"A1",macroAlexaOff); + sappend('v',"MP",macroButton); + sappend('v',"ML",macroLongPress); + sappend('v',"MC",macroCountdown); + sappend('v',"MN",macroNl); } if (subPage == 6) { - resp += ds + "NO" + c + otaLock +";"; - resp += ds + "OW" + c + wifiLock +";"; - resp += ds + "AO" + c + aOtaEnabled +";"; - resp += ds + "NA" + c + recoveryAPDisabled +";"; - resp += dg + "(\"msg\")[0]" + ih + "\"WLED "+ versionString +" (build " + VERSION + ") OK\";"; + sappend('c',"NO",otaLock); + sappend('c',"OW",wifiLock); + sappend('c',"AO",aOtaEnabled); + sappend('c',"NA",recoveryAPDisabled); + sappend('m',"(\"msg\")[0]",(int)"WLED "); + olen -= 2; //delete "; + oappend(versionString); + oappend(" (build "); + oappendi(VERSION); + oappend(") OK\";"); } - resp += "}"; - - return resp; + oappend("}"); } diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino index 97e11ab1..9b58affe 100644 --- a/wled00/wled05_init.ino +++ b/wled00/wled05_init.ino @@ -182,7 +182,8 @@ void wledInit() }); server.on("/build", HTTP_GET, [](){ - server.send(200, "text/plain", getBuildInfo()); + getBuildInfo(); + server.send(200, "text/plain", obuf); }); //if OTA is allowed if (!otaLock){ @@ -494,10 +495,10 @@ void serveSettings(byte subPage) default: pl0 = strlen_P(PAGE_settings0); pl1 = strlen_P(PAGE_settings1); } - String settingsBuffer = getSettings(subPage); + getSettingsJS(subPage); int sCssLength = (subPage >0 && subPage <7)?strlen_P(PAGE_settingsCss):0; - server.setContentLength(pl0 + cssColorString.length() + settingsBuffer.length() + sCssLength + pl1); + server.setContentLength(pl0 + cssColorString.length() + olen + sCssLength + pl1); server.send(200, "text/html", ""); switch (subPage) @@ -511,7 +512,7 @@ void serveSettings(byte subPage) case 255: server.sendContent_P(PAGE_welcome0); break; default: server.sendContent_P(PAGE_settings0); } - server.sendContent(settingsBuffer); + server.sendContent(obuf); server.sendContent(cssColorString); if (subPage >0 && subPage <7) server.sendContent_P(PAGE_settingsCss); switch (subPage) @@ -530,35 +531,42 @@ void serveSettings(byte subPage) } } -String getBuildInfo() +void getBuildInfo() { - String info = "hard-coded build info:\r\n\n"; + //fill string buffer with build info + olen = 0; + oappend("hard-coded build info:\r\n\n"); #ifdef ARDUINO_ARCH_ESP32 - info += "platform: esp32\r\n"; + oappend("platform: esp32"); #else - info += "platform: esp8266\r\n"; + oappend("platform: esp8266"); #endif - info += "version: " + versionString + "\r\n"; - info += "build: " + (String)VERSION + "\r\n"; - info += "eepver: " + String(EEPVER) + "\r\n"; + oappend("\r\nversion: "); + oappend(versionString); + oappend("\r\nbuild: "); + oappendi(VERSION); + oappend("\r\neepver: "); + oappendi(EEPVER); #ifdef USEFS - info += "spiffs: true\r\n"; + oappend("\r\nspiffs: true\r\n"); #else - info += "spiffs: false\r\n"; + oappend("\r\nspiffs: false\r\n"); #endif #ifdef DEBUG - info += "debug: true\r\n"; + oappend("debug: true\r\n"); #else - info += "debug: false\r\n"; + oappend("debug: false\r\n"); #endif - info += "button-pin: gpio" + String(buttonPin) + "\r\n"; + oappend("button-pin: gpio"); + oappendi(buttonPin); + oappend("\r\n"); #ifdef ARDUINO_ARCH_ESP32 - info += "strip-pin: gpio" + String(PIN) + "\r\n"; + oappend("strip-pin: gpio"); + oappendi(PIN); #else - info += "strip-pin: gpio2\r\n"; + oappend("strip-pin: gpio2"); #endif - info += "build-type: dev\r\n"; - return info; + oappend("\r\nbuild-type: dev\r\n"); } bool checkClientIsMobile(String useragent)