diff --git a/CHANGELOG.md b/CHANGELOG.md index 4dad83d9b..c570ac1f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ ## WLED changelog +#### Build 2410270 +- WLED 0.15.0-b7 release +- Re-license the WLED project from MIT to EUPL (#4194 by @Aircoookie) +- Fix alexa devices invisible/uncontrollable (#4214 by @Svennte) +- Add visual expand button on hover (#4172) +- Usermod: Audioreactive tuning and performance enhancements (by @softhack007) +- `/json/live` (JSON live data/peek) only enabled when WebSockets are disabled +- Various bugfixes and optimisations: #4179, #4215, #4219, #4222, #4223, #4224, #4228, #4230 + #### Build 2410140 - WLED 0.15.0-b6 release - Added BRT timezone (#4188 by @LuisFadini) diff --git a/package-lock.json b/package-lock.json index e85857017..db709485c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "wled", - "version": "0.15.0-b6", + "version": "0.15.0-b7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "wled", - "version": "0.15.0-b6", + "version": "0.15.0-b7", "license": "ISC", "dependencies": { "clean-css": "^5.3.3", diff --git a/package.json b/package.json index d76d87687..a11a13553 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wled", - "version": "0.15.0-b6", + "version": "0.15.0-b7", "description": "Tools for WLED project", "main": "tools/cdata.js", "directories": { @@ -27,5 +27,8 @@ "html-minifier-terser": "^7.2.0", "inliner": "^1.13.1", "nodemon": "^3.1.7" + }, + "engines": { + "node": ">=20.0.0" } } diff --git a/platformio.ini b/platformio.ini index 3005ba220..6d4aa1dc1 100644 --- a/platformio.ini +++ b/platformio.ini @@ -197,6 +197,7 @@ build_flags = ; decrease code cache size and increase IRAM to fit all pixel functions -D PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48 ;; in case of linker errors like "section `.text1' will not fit in region `iram1_0_seg'" ; -D PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48_SECHEAP_SHARED ;; (experimental) adds some extra heap, but may cause slowdown + -D NON32XFER_HANDLER ;; ask forgiveness for PROGMEM misuse lib_deps = #https://github.com/lorol/LITTLEFS.git @@ -259,7 +260,8 @@ lib_deps = https://github.com/pbolduc/AsyncTCP.git @ 1.2.0 ${env.lib_deps} # additional build flags for audioreactive -AR_build_flags = -D USERMOD_AUDIOREACTIVE +AR_build_flags = -D USERMOD_AUDIOREACTIVE + -D sqrt_internal=sqrtf ;; -fsingle-precision-constant ;; forces ArduinoFFT to use float math (2x faster) AR_lib_deps = kosme/arduinoFFT @ 2.0.1 [esp32_idf_V4] @@ -554,6 +556,33 @@ board_build.f_flash = 80000000L board_build.flash_mode = qio monitor_filters = esp32_exception_decoder +[env:esp32S3_wroom2] +;; For ESP32-S3 WROOM-2, a.k.a. ESP32-S3 DevKitC-1 v1.1 +;; with >= 16MB FLASH and >= 8MB PSRAM (memory_type: opi_opi) +platform = ${esp32s3.platform} +platform_packages = ${esp32s3.platform_packages} +board = esp32s3camlcd ;; this is the only standard board with "opi_opi" +board_build.arduino.memory_type = opi_opi +upload_speed = 921600 +build_unflags = ${common.build_unflags} +build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=ESP32-S3_WROOM-2 + -D CONFIG_LITTLEFS_FOR_IDF_3_2 -D WLED_WATCHDOG_TIMEOUT=0 + -D ARDUINO_USB_CDC_ON_BOOT=0 ;; -D ARDUINO_USB_MODE=1 ;; for boards with serial-to-USB chip + ;; -D ARDUINO_USB_CDC_ON_BOOT=1 -D ARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB") + -DBOARD_HAS_PSRAM + -D LEDPIN=38 -D DATA_PINS=38 ;; buildin WS2812b LED + -D BTNPIN=0 -D RLYPIN=16 -D IRPIN=17 -D AUDIOPIN=-1 + -D WLED_DEBUG + ${esp32.AR_build_flags} + -D SR_DMTYPE=1 -D I2S_SDPIN=13 -D I2S_CKPIN=14 -D I2S_WSPIN=15 -D MCLK_PIN=4 ;; I2S mic +lib_deps = ${esp32s3.lib_deps} + ${esp32.AR_lib_deps} + +board_build.partitions = ${esp32.extreme_partitions} +board_upload.flash_size = 16MB +board_upload.maximum_size = 16777216 +monitor_filters = esp32_exception_decoder + [env:esp32s3_4M_qspi] ;; ESP32-S3, with 4MB FLASH and <= 4MB PSRAM (memory_type: qio_qspi) board = lolin_s3_mini ;; -S3 mini, 4MB flash 2MB PSRAM diff --git a/tools/cdata.js b/tools/cdata.js index d65573a8e..c5d3c6aa5 100644 --- a/tools/cdata.js +++ b/tools/cdata.js @@ -101,6 +101,7 @@ function adoptVersionAndRepo(html) { async function minify(str, type = "plain") { const options = { collapseWhitespace: true, + conservativeCollapse: true, // preserve spaces in text collapseBooleanAttributes: true, collapseInlineTagWhitespace: true, minifyCSS: true, diff --git a/usermods/Animated_Staircase/Animated_Staircase.h b/usermods/Animated_Staircase/Animated_Staircase.h index d1ec9bb7f..54a9b3331 100644 --- a/usermods/Animated_Staircase/Animated_Staircase.h +++ b/usermods/Animated_Staircase/Animated_Staircase.h @@ -425,10 +425,10 @@ class Animated_Staircase : public Usermod { } void appendConfigData() { - //oappend(SET_F("dd=addDropdown('staircase','selectfield');")); - //oappend(SET_F("addOption(dd,'1st value',0);")); - //oappend(SET_F("addOption(dd,'2nd value',1);")); - //oappend(SET_F("addInfo('staircase:selectfield',1,'additional info');")); // 0 is field type, 1 is actual field + //oappend(F("dd=addDropdown('staircase','selectfield');")); + //oappend(F("addOption(dd,'1st value',0);")); + //oappend(F("addOption(dd,'2nd value',1);")); + //oappend(F("addInfo('staircase:selectfield',1,'additional info');")); // 0 is field type, 1 is actual field } diff --git a/usermods/BME68X_v2/usermod_bme68x.h b/usermods/BME68X_v2/usermod_bme68x.h index 8e360515a..aca24d0a2 100644 --- a/usermods/BME68X_v2/usermod_bme68x.h +++ b/usermods/BME68X_v2/usermod_bme68x.h @@ -767,22 +767,22 @@ void UsermodBME68X::appendConfigData() { // snprintf_P(charbuffer, 127, PSTR("addInfo('%s:%s',1,'*) Set to minus to deactivate (all sensors)');"), UMOD_NAME, _nameTemp); oappend(charbuffer); /* Dropdown for Celsius/Fahrenheit*/ - oappend(SET_F("dd=addDropdown('")); + oappend(F("dd=addDropdown('")); oappend(UMOD_NAME); - oappend(SET_F("','")); + oappend(F("','")); oappend(_nameTempScale); - oappend(SET_F("');")); - oappend(SET_F("addOption(dd,'Celsius',0);")); - oappend(SET_F("addOption(dd,'Fahrenheit',1);")); + oappend(F("');")); + oappend(F("addOption(dd,'Celsius',0);")); + oappend(F("addOption(dd,'Fahrenheit',1);")); /* i²C Address*/ - oappend(SET_F("dd=addDropdown('")); + oappend(F("dd=addDropdown('")); oappend(UMOD_NAME); - oappend(SET_F("','")); + oappend(F("','")); oappend(_nameI2CAdr); - oappend(SET_F("');")); - oappend(SET_F("addOption(dd,'0x76',0x76);")); - oappend(SET_F("addOption(dd,'0x77',0x77);")); + oappend(F("');")); + oappend(F("addOption(dd,'0x76',0x76);")); + oappend(F("addOption(dd,'0x77',0x77);")); } /** diff --git a/usermods/Battery/usermod_v2_Battery.h b/usermods/Battery/usermod_v2_Battery.h index e91de850c..b36c5f4d6 100644 --- a/usermods/Battery/usermod_v2_Battery.h +++ b/usermods/Battery/usermod_v2_Battery.h @@ -478,29 +478,29 @@ class UsermodBattery : public Usermod void appendConfigData() { // Total: 462 Bytes - oappend(SET_F("td=addDropdown('Battery','type');")); // 34 Bytes - oappend(SET_F("addOption(td,'Unkown','0');")); // 28 Bytes - oappend(SET_F("addOption(td,'LiPo','1');")); // 26 Bytes - oappend(SET_F("addOption(td,'LiOn','2');")); // 26 Bytes - oappend(SET_F("addInfo('Battery:type',1,'requires reboot');")); // 81 Bytes - oappend(SET_F("addInfo('Battery:min-voltage',1,'v');")); // 38 Bytes - oappend(SET_F("addInfo('Battery:max-voltage',1,'v');")); // 38 Bytes - oappend(SET_F("addInfo('Battery:interval',1,'ms');")); // 36 Bytes - oappend(SET_F("addInfo('Battery:HA-discovery',1,'');")); // 38 Bytes - oappend(SET_F("addInfo('Battery:auto-off:threshold',1,'%');")); // 45 Bytes - oappend(SET_F("addInfo('Battery:indicator:threshold',1,'%');")); // 46 Bytes - oappend(SET_F("addInfo('Battery:indicator:duration',1,'s');")); // 45 Bytes + oappend(F("td=addDropdown('Battery','type');")); // 34 Bytes + oappend(F("addOption(td,'Unkown','0');")); // 28 Bytes + oappend(F("addOption(td,'LiPo','1');")); // 26 Bytes + oappend(F("addOption(td,'LiOn','2');")); // 26 Bytes + oappend(F("addInfo('Battery:type',1,'requires reboot');")); // 81 Bytes + oappend(F("addInfo('Battery:min-voltage',1,'v');")); // 38 Bytes + oappend(F("addInfo('Battery:max-voltage',1,'v');")); // 38 Bytes + oappend(F("addInfo('Battery:interval',1,'ms');")); // 36 Bytes + oappend(F("addInfo('Battery:HA-discovery',1,'');")); // 38 Bytes + oappend(F("addInfo('Battery:auto-off:threshold',1,'%');")); // 45 Bytes + oappend(F("addInfo('Battery:indicator:threshold',1,'%');")); // 46 Bytes + oappend(F("addInfo('Battery:indicator:duration',1,'s');")); // 45 Bytes // this option list would exeed the oappend() buffer // a list of all presets to select one from - // oappend(SET_F("bd=addDropdown('Battery:low-power-indicator', 'preset');")); - // the loop generates: oappend(SET_F("addOption(bd, 'preset name', preset id);")); + // oappend(F("bd=addDropdown('Battery:low-power-indicator', 'preset');")); + // the loop generates: oappend(F("addOption(bd, 'preset name', preset id);")); // for(int8_t i=1; i < 42; i++) { - // oappend(SET_F("addOption(bd, 'Preset#")); + // oappend(F("addOption(bd, 'Preset#")); // oappendi(i); - // oappend(SET_F("',")); + // oappend(F("',")); // oappendi(i); - // oappend(SET_F(");")); + // oappend(F(");")); // } } diff --git a/usermods/EXAMPLE_v2/usermod_v2_example.h b/usermods/EXAMPLE_v2/usermod_v2_example.h index 3d562b585..df05f3e3d 100644 --- a/usermods/EXAMPLE_v2/usermod_v2_example.h +++ b/usermods/EXAMPLE_v2/usermod_v2_example.h @@ -287,11 +287,11 @@ class MyExampleUsermod : public Usermod { */ void appendConfigData() override { - oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":great")); oappend(SET_F("',1,'(this is a great config value)');")); - oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":testString")); oappend(SET_F("',1,'enter any string you want');")); - oappend(SET_F("dd=addDropdown('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F("','testInt');")); - oappend(SET_F("addOption(dd,'Nothing',0);")); - oappend(SET_F("addOption(dd,'Everything',42);")); + oappend(F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(F(":great")); oappend(F("',1,'(this is a great config value)');")); + oappend(F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(F(":testString")); oappend(F("',1,'enter any string you want');")); + oappend(F("dd=addDropdown('")); oappend(String(FPSTR(_name)).c_str()); oappend(F("','testInt');")); + oappend(F("addOption(dd,'Nothing',0);")); + oappend(F("addOption(dd,'Everything',42);")); } diff --git a/usermods/Internal_Temperature_v2/usermod_internal_temperature.h b/usermods/Internal_Temperature_v2/usermod_internal_temperature.h index 2236bfeab..c24b4c628 100644 --- a/usermods/Internal_Temperature_v2/usermod_internal_temperature.h +++ b/usermods/Internal_Temperature_v2/usermod_internal_temperature.h @@ -149,11 +149,11 @@ public: void appendConfigData() { // Display 'ms' next to the 'Loop Interval' setting - oappend(SET_F("addInfo('Internal Temperature:Loop Interval', 1, 'ms');")); + oappend(F("addInfo('Internal Temperature:Loop Interval', 1, 'ms');")); // Display '°C' next to the 'Activation Threshold' setting - oappend(SET_F("addInfo('Internal Temperature:Activation Threshold', 1, '°C');")); + oappend(F("addInfo('Internal Temperature:Activation Threshold', 1, '°C');")); // Display '0 = Disabled' next to the 'Preset To Activate' setting - oappend(SET_F("addInfo('Internal Temperature:Preset To Activate', 1, '0 = unused');")); + oappend(F("addInfo('Internal Temperature:Preset To Activate', 1, '0 = unused');")); } bool readFromConfig(JsonObject &root) diff --git a/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h b/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h index 29070cf84..0deda181c 100644 --- a/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h +++ b/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h @@ -511,8 +511,8 @@ void PIRsensorSwitch::addToConfig(JsonObject &root) void PIRsensorSwitch::appendConfigData() { - oappend(SET_F("addInfo('PIRsensorSwitch:HA-discovery',1,'HA=Home Assistant');")); // 0 is field type, 1 is actual field - oappend(SET_F("addInfo('PIRsensorSwitch:override',1,'Cancel timer on change');")); // 0 is field type, 1 is actual field + oappend(F("addInfo('PIRsensorSwitch:HA-discovery',1,'HA=Home Assistant');")); // 0 is field type, 1 is actual field + oappend(F("addInfo('PIRsensorSwitch:override',1,'Cancel timer on change');")); // 0 is field type, 1 is actual field for (int i = 0; i < PIR_SENSOR_MAX_SENSORS; i++) { char str[128]; sprintf_P(str, PSTR("addInfo('PIRsensorSwitch:pin[]',%d,'','#%d');"), i, i); diff --git a/usermods/ST7789_display/ST7789_display.h b/usermods/ST7789_display/ST7789_display.h index 0dbada382..65f4cae5d 100644 --- a/usermods/ST7789_display/ST7789_display.h +++ b/usermods/ST7789_display/ST7789_display.h @@ -377,10 +377,10 @@ class St7789DisplayUsermod : public Usermod { void appendConfigData() override { - oappend(SET_F("addInfo('ST7789:pin[]',0,'','SPI CS');")); - oappend(SET_F("addInfo('ST7789:pin[]',1,'','SPI DC');")); - oappend(SET_F("addInfo('ST7789:pin[]',2,'','SPI RST');")); - oappend(SET_F("addInfo('ST7789:pin[]',3,'','SPI BL');")); + oappend(F("addInfo('ST7789:pin[]',0,'','SPI CS');")); + oappend(F("addInfo('ST7789:pin[]',1,'','SPI DC');")); + oappend(F("addInfo('ST7789:pin[]',2,'','SPI RST');")); + oappend(F("addInfo('ST7789:pin[]',3,'','SPI BL');")); } /* diff --git a/usermods/Temperature/usermod_temperature.h b/usermods/Temperature/usermod_temperature.h index ad755eaee..178bc05a0 100644 --- a/usermods/Temperature/usermod_temperature.h +++ b/usermods/Temperature/usermod_temperature.h @@ -435,10 +435,10 @@ bool UsermodTemperature::readFromConfig(JsonObject &root) { } void UsermodTemperature::appendConfigData() { - oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":")); oappend(String(FPSTR(_parasite)).c_str()); - oappend(SET_F("',1,'(if no Vcc connected)');")); // 0 is field type, 1 is actual field - oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":")); oappend(String(FPSTR(_parasitePin)).c_str()); - oappend(SET_F("',1,'(for external MOSFET)');")); // 0 is field type, 1 is actual field + oappend(F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(F(":")); oappend(String(FPSTR(_parasite)).c_str()); + oappend(F("',1,'(if no Vcc connected)');")); // 0 is field type, 1 is actual field + oappend(F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(F(":")); oappend(String(FPSTR(_parasitePin)).c_str()); + oappend(F("',1,'(for external MOSFET)');")); // 0 is field type, 1 is actual field } float UsermodTemperature::getTemperature() { diff --git a/usermods/audioreactive/audio_reactive.h b/usermods/audioreactive/audio_reactive.h index fde7afded..ad449fc83 100644 --- a/usermods/audioreactive/audio_reactive.h +++ b/usermods/audioreactive/audio_reactive.h @@ -191,8 +191,8 @@ constexpr uint16_t samplesFFT_2 = 256; // meaningfull part of FFT resul #define LOG_256 5.54517744f // log(256) // These are the input and output vectors. Input vectors receive computed results from FFT. -static float vReal[samplesFFT] = {0.0f}; // FFT sample inputs / freq output - these are our raw result bins -static float vImag[samplesFFT] = {0.0f}; // imaginary parts +static float* vReal = nullptr; // FFT sample inputs / freq output - these are our raw result bins +static float* vImag = nullptr; // imaginary parts // Create FFT object // lib_deps += https://github.com/kosme/arduinoFFT#develop @ 1.9.2 @@ -200,14 +200,9 @@ static float vImag[samplesFFT] = {0.0f}; // imaginary parts // #define FFT_SPEED_OVER_PRECISION // enables use of reciprocals (1/x etc) - not faster on ESP32 // #define FFT_SQRT_APPROXIMATION // enables "quake3" style inverse sqrt - slower on ESP32 // Below options are forcing ArduinoFFT to use sqrtf() instead of sqrt() -#define sqrt(x) sqrtf(x) // little hack that reduces FFT time by 10-50% on ESP32 -#define sqrt_internal sqrtf // see https://github.com/kosme/arduinoFFT/pull/83 - -#include - -/* Create FFT object with weighing factor storage */ -static ArduinoFFT FFT = ArduinoFFT( vReal, vImag, samplesFFT, SAMPLE_RATE, true); +// #define sqrt_internal sqrtf // see https://github.com/kosme/arduinoFFT/pull/83 - since v2.0.0 this must be done in build_flags +#include // FFT object is created in FFTcode // Helper functions // compute average of several FFT result bins @@ -226,6 +221,18 @@ void FFTcode(void * parameter) { DEBUGSR_PRINT("FFT started on core: "); DEBUGSR_PRINTLN(xPortGetCoreID()); + // allocate FFT buffers on first call + if (vReal == nullptr) vReal = (float*) calloc(sizeof(float), samplesFFT); + if (vImag == nullptr) vImag = (float*) calloc(sizeof(float), samplesFFT); + if ((vReal == nullptr) || (vImag == nullptr)) { + // something went wrong + if (vReal) free(vReal); vReal = nullptr; + if (vImag) free(vImag); vImag = nullptr; + return; + } + // Create FFT object with weighing factor storage + ArduinoFFT FFT = ArduinoFFT( vReal, vImag, samplesFFT, SAMPLE_RATE, true); + // see https://www.freertos.org/vtaskdelayuntil.html const TickType_t xFrequency = FFT_MIN_CYCLE * portTICK_PERIOD_MS; @@ -247,6 +254,7 @@ void FFTcode(void * parameter) // get a fresh batch of samples from I2S if (audioSource) audioSource->getSamples(vReal, samplesFFT); + memset(vImag, 0, samplesFFT * sizeof(float)); // set imaginary parts to 0 #if defined(WLED_DEBUG) || defined(SR_DEBUG) if (start < esp_timer_get_time()) { // filter out overflows @@ -265,8 +273,6 @@ void FFTcode(void * parameter) // find highest sample in the batch float maxSample = 0.0f; // max sample from FFT batch for (int i=0; i < samplesFFT; i++) { - // set imaginary parts to 0 - vImag[i] = 0; // pick our our current mic sample - we take the max value from all samples that go into FFT if ((vReal[i] <= (INT16_MAX - 1024)) && (vReal[i] >= (INT16_MIN + 1024))) //skip extreme values - normally these are artefacts if (fabsf((float)vReal[i]) > maxSample) maxSample = fabsf((float)vReal[i]); @@ -297,7 +303,7 @@ void FFTcode(void * parameter) #endif } else { // noise gate closed - only clear results as FFT was skipped. MIC samples are still valid when we do this. - memset(vReal, 0, sizeof(vReal)); + memset(vReal, 0, samplesFFT * sizeof(float)); FFT_MajorPeak = 1; FFT_Magnitude = 0.001; } @@ -1879,57 +1885,59 @@ class AudioReactive : public Usermod { } - void appendConfigData() override + void appendConfigData(Print& uiScript) override { -#ifdef ARDUINO_ARCH_ESP32 - oappend(SET_F("dd=addDropdown('AudioReactive','digitalmic:type');")); + uiScript.print(F("ux='AudioReactive';")); // ux = shortcut for Audioreactive - fingers crossed that "ux" isn't already used as JS var, html post parameter or css style +#ifdef ARDUINO_ARCH_ESP32 + uiScript.print(F("uxp=ux+':digitalmic:pin[]';")); // uxp = shortcut for AudioReactive:digitalmic:pin[] + uiScript.print(F("dd=addDropdown(ux,'digitalmic:type');")); #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3) - oappend(SET_F("addOption(dd,'Generic Analog',0);")); + uiScript.print(F("addOption(dd,'Generic Analog',0);")); #endif - oappend(SET_F("addOption(dd,'Generic I2S',1);")); - oappend(SET_F("addOption(dd,'ES7243',2);")); - oappend(SET_F("addOption(dd,'SPH0654',3);")); - oappend(SET_F("addOption(dd,'Generic I2S with Mclk',4);")); + uiScript.print(F("addOption(dd,'Generic I2S',1);")); + uiScript.print(F("addOption(dd,'ES7243',2);")); + uiScript.print(F("addOption(dd,'SPH0654',3);")); + uiScript.print(F("addOption(dd,'Generic I2S with Mclk',4);")); #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) - oappend(SET_F("addOption(dd,'Generic I2S PDM',5);")); + uiScript.print(F("addOption(dd,'Generic I2S PDM',5);")); #endif - oappend(SET_F("addOption(dd,'ES8388',6);")); + uiScript.print(F("addOption(dd,'ES8388',6);")); - oappend(SET_F("dd=addDropdown('AudioReactive','config:AGC');")); - oappend(SET_F("addOption(dd,'Off',0);")); - oappend(SET_F("addOption(dd,'Normal',1);")); - oappend(SET_F("addOption(dd,'Vivid',2);")); - oappend(SET_F("addOption(dd,'Lazy',3);")); + uiScript.print(F("dd=addDropdown(ux,'config:AGC');")); + uiScript.print(F("addOption(dd,'Off',0);")); + uiScript.print(F("addOption(dd,'Normal',1);")); + uiScript.print(F("addOption(dd,'Vivid',2);")); + uiScript.print(F("addOption(dd,'Lazy',3);")); - oappend(SET_F("dd=addDropdown('AudioReactive','dynamics:limiter');")); - oappend(SET_F("addOption(dd,'Off',0);")); - oappend(SET_F("addOption(dd,'On',1);")); - oappend(SET_F("addInfo('AudioReactive:dynamics:limiter',0,' On ');")); // 0 is field type, 1 is actual field - oappend(SET_F("addInfo('AudioReactive:dynamics:rise',1,'ms (♪ effects only)');")); - oappend(SET_F("addInfo('AudioReactive:dynamics:fall',1,'ms (♪ effects only)');")); + uiScript.print(F("dd=addDropdown(ux,'dynamics:limiter');")); + uiScript.print(F("addOption(dd,'Off',0);")); + uiScript.print(F("addOption(dd,'On',1);")); + uiScript.print(F("addInfo(ux+':dynamics:limiter',0,' On ');")); // 0 is field type, 1 is actual field + uiScript.print(F("addInfo(ux+':dynamics:rise',1,'ms (♪ effects only)');")); + uiScript.print(F("addInfo(ux+':dynamics:fall',1,'ms (♪ effects only)');")); - oappend(SET_F("dd=addDropdown('AudioReactive','frequency:scale');")); - oappend(SET_F("addOption(dd,'None',0);")); - oappend(SET_F("addOption(dd,'Linear (Amplitude)',2);")); - oappend(SET_F("addOption(dd,'Square Root (Energy)',3);")); - oappend(SET_F("addOption(dd,'Logarithmic (Loudness)',1);")); + uiScript.print(F("dd=addDropdown(ux,'frequency:scale');")); + uiScript.print(F("addOption(dd,'None',0);")); + uiScript.print(F("addOption(dd,'Linear (Amplitude)',2);")); + uiScript.print(F("addOption(dd,'Square Root (Energy)',3);")); + uiScript.print(F("addOption(dd,'Logarithmic (Loudness)',1);")); #endif - oappend(SET_F("dd=addDropdown('AudioReactive','sync:mode');")); - oappend(SET_F("addOption(dd,'Off',0);")); + uiScript.print(F("dd=addDropdown(ux,'sync:mode');")); + uiScript.print(F("addOption(dd,'Off',0);")); #ifdef ARDUINO_ARCH_ESP32 - oappend(SET_F("addOption(dd,'Send',1);")); + uiScript.print(F("addOption(dd,'Send',1);")); #endif - oappend(SET_F("addOption(dd,'Receive',2);")); + uiScript.print(F("addOption(dd,'Receive',2);")); #ifdef ARDUINO_ARCH_ESP32 - oappend(SET_F("addInfo('AudioReactive:digitalmic:type',1,'requires reboot!');")); // 0 is field type, 1 is actual field - oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',0,'sd/data/dout','I2S SD');")); - oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',1,'ws/clk/lrck','I2S WS');")); - oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',2,'sck/bclk','I2S SCK');")); + uiScript.print(F("addInfo(ux+':digitalmic:type',1,'requires reboot!');")); // 0 is field type, 1 is actual field + uiScript.print(F("addInfo(uxp,0,'sd/data/dout','I2S SD');")); + uiScript.print(F("addInfo(uxp,1,'ws/clk/lrck','I2S WS');")); + uiScript.print(F("addInfo(uxp,2,'sck/bclk','I2S SCK');")); #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3) - oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',3,'only use -1, 0, 1 or 3','I2S MCLK');")); + uiScript.print(F("addInfo(uxp,3,'only use -1, 0, 1 or 3','I2S MCLK');")); #else - oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',3,'master clock','I2S MCLK');")); + uiScript.print(F("addInfo(uxp,3,'master clock','I2S MCLK');")); #endif #endif } diff --git a/usermods/audioreactive/readme.md b/usermods/audioreactive/readme.md index 4668ca881..aad269c67 100644 --- a/usermods/audioreactive/readme.md +++ b/usermods/audioreactive/readme.md @@ -30,7 +30,7 @@ There are however plans to create a lightweight audioreactive for the 8266, with ### using latest _arduinoFFT_ library version 2.x The latest arduinoFFT release version should be used for audioreactive. -* `build_flags` = `-D USERMOD_AUDIOREACTIVE` +* `build_flags` = `-D USERMOD_AUDIOREACTIVE -D sqrt_internal=sqrtf` * `lib_deps`= `kosme/arduinoFFT @ 2.0.1` ## Configuration diff --git a/usermods/boblight/boblight.h b/usermods/boblight/boblight.h index 916f7da98..b04b78fac 100644 --- a/usermods/boblight/boblight.h +++ b/usermods/boblight/boblight.h @@ -305,14 +305,14 @@ class BobLightUsermod : public Usermod { } void appendConfigData() override { - //oappend(SET_F("dd=addDropdown('usermod','selectfield');")); - //oappend(SET_F("addOption(dd,'1st value',0);")); - //oappend(SET_F("addOption(dd,'2nd value',1);")); - oappend(SET_F("addInfo('BobLight:top',1,'LEDs');")); // 0 is field type, 1 is actual field - oappend(SET_F("addInfo('BobLight:bottom',1,'LEDs');")); // 0 is field type, 1 is actual field - oappend(SET_F("addInfo('BobLight:left',1,'LEDs');")); // 0 is field type, 1 is actual field - oappend(SET_F("addInfo('BobLight:right',1,'LEDs');")); // 0 is field type, 1 is actual field - oappend(SET_F("addInfo('BobLight:pct',1,'Depth of scan [%]');")); // 0 is field type, 1 is actual field + //oappend(F("dd=addDropdown('usermod','selectfield');")); + //oappend(F("addOption(dd,'1st value',0);")); + //oappend(F("addOption(dd,'2nd value',1);")); + oappend(F("addInfo('BobLight:top',1,'LEDs');")); // 0 is field type, 1 is actual field + oappend(F("addInfo('BobLight:bottom',1,'LEDs');")); // 0 is field type, 1 is actual field + oappend(F("addInfo('BobLight:left',1,'LEDs');")); // 0 is field type, 1 is actual field + oappend(F("addInfo('BobLight:right',1,'LEDs');")); // 0 is field type, 1 is actual field + oappend(F("addInfo('BobLight:pct',1,'Depth of scan [%]');")); // 0 is field type, 1 is actual field } void addToConfig(JsonObject& root) override { diff --git a/usermods/multi_relay/usermod_multi_relay.h b/usermods/multi_relay/usermod_multi_relay.h index 33a6cf85e..c4446c7a2 100644 --- a/usermods/multi_relay/usermod_multi_relay.h +++ b/usermods/multi_relay/usermod_multi_relay.h @@ -264,7 +264,7 @@ void MultiRelay::handleOffTimer() { void MultiRelay::InitHtmlAPIHandle() { // https://github.com/me-no-dev/ESPAsyncWebServer DEBUG_PRINTLN(F("Relays: Initialize HTML API")); - server.on(SET_F("/relays"), HTTP_GET, [this](AsyncWebServerRequest *request) { + server.on(F("/relays"), HTTP_GET, [this](AsyncWebServerRequest *request) { DEBUG_PRINTLN(F("Relays: HTML API")); String janswer; String error = ""; @@ -765,10 +765,10 @@ void MultiRelay::addToConfig(JsonObject &root) { } void MultiRelay::appendConfigData() { - oappend(SET_F("addInfo('MultiRelay:PCF8574-address',1,'(not hex!)');")); - oappend(SET_F("addInfo('MultiRelay:broadcast-sec',1,'(MQTT message)');")); - //oappend(SET_F("addInfo('MultiRelay:relay-0:pin',1,'(use -1 for PCF8574)');")); - oappend(SET_F("d.extra.push({'MultiRelay':{pin:[['P0',100],['P1',101],['P2',102],['P3',103],['P4',104],['P5',105],['P6',106],['P7',107]]}});")); + oappend(F("addInfo('MultiRelay:PCF8574-address',1,'(not hex!)');")); + oappend(F("addInfo('MultiRelay:broadcast-sec',1,'(MQTT message)');")); + //oappend(F("addInfo('MultiRelay:relay-0:pin',1,'(use -1 for PCF8574)');")); + oappend(F("d.extra.push({'MultiRelay':{pin:[['P0',100],['P1',101],['P2',102],['P3',103],['P4',104],['P5',105],['P6',106],['P7',107]]}});")); } /** diff --git a/usermods/pixels_dice_tray/pixels_dice_tray.h b/usermods/pixels_dice_tray/pixels_dice_tray.h index a1e45ba33..61348ebb8 100644 --- a/usermods/pixels_dice_tray/pixels_dice_tray.h +++ b/usermods/pixels_dice_tray/pixels_dice_tray.h @@ -387,23 +387,23 @@ class PixelsDiceTrayUsermod : public Usermod { // To work around this, add info text to the end of the preceding item. // // See addInfo in wled00/data/settings_um.htm for details on what this function does. - oappend(SET_F( + oappend(F( "addInfo('DiceTray:ble_scan_duration',1,'

Set to \"*\" to " "connect to any die.
Leave Blank to disable.

Saving will replace \"*\" with die names.','');")); #if USING_TFT_DISPLAY - oappend(SET_F("ddr=addDropdown('DiceTray','rotation');")); - oappend(SET_F("addOption(ddr,'0 deg',0);")); - oappend(SET_F("addOption(ddr,'90 deg',1);")); - oappend(SET_F("addOption(ddr,'180 deg',2);")); - oappend(SET_F("addOption(ddr,'270 deg',3);")); - oappend(SET_F( + oappend(F("ddr=addDropdown('DiceTray','rotation');")); + oappend(F("addOption(ddr,'0 deg',0);")); + oappend(F("addOption(ddr,'90 deg',1);")); + oappend(F("addOption(ddr,'180 deg',2);")); + oappend(F("addOption(ddr,'270 deg',3);")); + oappend(F( "addInfo('DiceTray:rotation',1,'
DO NOT CHANGE " "SPI PINS.
CHANGES ARE IGNORED.','');")); - oappend(SET_F("addInfo('TFT:pin[]',0,'','SPI CS');")); - oappend(SET_F("addInfo('TFT:pin[]',1,'','SPI DC');")); - oappend(SET_F("addInfo('TFT:pin[]',2,'','SPI RST');")); - oappend(SET_F("addInfo('TFT:pin[]',3,'','SPI BL');")); + oappend(F("addInfo('TFT:pin[]',0,'','SPI CS');")); + oappend(F("addInfo('TFT:pin[]',1,'','SPI DC');")); + oappend(F("addInfo('TFT:pin[]',2,'','SPI RST');")); + oappend(F("addInfo('TFT:pin[]',3,'','SPI BL');")); #endif } diff --git a/usermods/sht/usermod_sht.h b/usermods/sht/usermod_sht.h index c6e17221b..f10c78a25 100644 --- a/usermods/sht/usermod_sht.h +++ b/usermods/sht/usermod_sht.h @@ -310,22 +310,22 @@ void ShtUsermod::onMqttConnect(bool sessionPresent) { * @return void */ void ShtUsermod::appendConfigData() { - oappend(SET_F("dd=addDropdown('")); + oappend(F("dd=addDropdown('")); oappend(_name); - oappend(SET_F("','")); + oappend(F("','")); oappend(_shtType); - oappend(SET_F("');")); - oappend(SET_F("addOption(dd,'SHT30',0);")); - oappend(SET_F("addOption(dd,'SHT31',1);")); - oappend(SET_F("addOption(dd,'SHT35',2);")); - oappend(SET_F("addOption(dd,'SHT85',3);")); - oappend(SET_F("dd=addDropdown('")); + oappend(F("');")); + oappend(F("addOption(dd,'SHT30',0);")); + oappend(F("addOption(dd,'SHT31',1);")); + oappend(F("addOption(dd,'SHT35',2);")); + oappend(F("addOption(dd,'SHT85',3);")); + oappend(F("dd=addDropdown('")); oappend(_name); - oappend(SET_F("','")); + oappend(F("','")); oappend(_unitOfTemp); - oappend(SET_F("');")); - oappend(SET_F("addOption(dd,'Celsius',0);")); - oappend(SET_F("addOption(dd,'Fahrenheit',1);")); + oappend(F("');")); + oappend(F("addOption(dd,'Celsius',0);")); + oappend(F("addOption(dd,'Fahrenheit',1);")); } /** diff --git a/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h b/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h index f712316b8..707479df1 100644 --- a/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h +++ b/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h @@ -96,7 +96,7 @@ void setup() { jsonTransitionOnce = true; strip.setTransition(0); //no transition effectCurrent = FX_MODE_COLOR_WIPE; - resetTimebase(); //make sure wipe starts from beginning + strip.resetTimebase(); //make sure wipe starts from beginning //set wipe direction Segment& seg = strip.getSegment(0); diff --git a/usermods/stairway_wipe_basic/wled06_usermod.ino b/usermods/stairway_wipe_basic/wled06_usermod.ino index c1264ebfb..dc2159ee9 100644 --- a/usermods/stairway_wipe_basic/wled06_usermod.ino +++ b/usermods/stairway_wipe_basic/wled06_usermod.ino @@ -86,7 +86,7 @@ void startWipe() bri = briLast; //turn on transitionDelayTemp = 0; //no transition effectCurrent = FX_MODE_COLOR_WIPE; - resetTimebase(); //make sure wipe starts from beginning + strip.resetTimebase(); //make sure wipe starts from beginning //set wipe direction Segment& seg = strip.getSegment(0); diff --git a/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h b/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h index dfab7e6ff..684dd86e4 100644 --- a/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h +++ b/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h @@ -1202,21 +1202,21 @@ void FourLineDisplayUsermod::onUpdateBegin(bool init) { //} void FourLineDisplayUsermod::appendConfigData() { - oappend(SET_F("dd=addDropdown('4LineDisplay','type');")); - oappend(SET_F("addOption(dd,'None',0);")); - oappend(SET_F("addOption(dd,'SSD1306',1);")); - oappend(SET_F("addOption(dd,'SH1106',2);")); - oappend(SET_F("addOption(dd,'SSD1306 128x64',3);")); - oappend(SET_F("addOption(dd,'SSD1305',4);")); - oappend(SET_F("addOption(dd,'SSD1305 128x64',5);")); - oappend(SET_F("addOption(dd,'SSD1309 128x64',9);")); - oappend(SET_F("addOption(dd,'SSD1306 SPI',6);")); - oappend(SET_F("addOption(dd,'SSD1306 SPI 128x64',7);")); - oappend(SET_F("addOption(dd,'SSD1309 SPI 128x64',8);")); - oappend(SET_F("addInfo('4LineDisplay:type',1,'
Change may require reboot','');")); - oappend(SET_F("addInfo('4LineDisplay:pin[]',0,'','SPI CS');")); - oappend(SET_F("addInfo('4LineDisplay:pin[]',1,'','SPI DC');")); - oappend(SET_F("addInfo('4LineDisplay:pin[]',2,'','SPI RST');")); + oappend(F("dd=addDropdown('4LineDisplay','type');")); + oappend(F("addOption(dd,'None',0);")); + oappend(F("addOption(dd,'SSD1306',1);")); + oappend(F("addOption(dd,'SH1106',2);")); + oappend(F("addOption(dd,'SSD1306 128x64',3);")); + oappend(F("addOption(dd,'SSD1305',4);")); + oappend(F("addOption(dd,'SSD1305 128x64',5);")); + oappend(F("addOption(dd,'SSD1309 128x64',9);")); + oappend(F("addOption(dd,'SSD1306 SPI',6);")); + oappend(F("addOption(dd,'SSD1306 SPI 128x64',7);")); + oappend(F("addOption(dd,'SSD1309 SPI 128x64',8);")); + oappend(F("addInfo('4LineDisplay:type',1,'
Change may require reboot','');")); + oappend(F("addInfo('4LineDisplay:pin[]',0,'','SPI CS');")); + oappend(F("addInfo('4LineDisplay:pin[]',1,'','SPI DC');")); + oappend(F("addInfo('4LineDisplay:pin[]',2,'','SPI RST');")); } /* diff --git a/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h b/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h index 55715b7c7..383c1193e 100644 --- a/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h +++ b/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h @@ -1090,8 +1090,8 @@ void RotaryEncoderUIUsermod::addToConfig(JsonObject &root) { } void RotaryEncoderUIUsermod::appendConfigData() { - oappend(SET_F("addInfo('Rotary-Encoder:PCF8574-address',1,'(not hex!)');")); - oappend(SET_F("d.extra.push({'Rotary-Encoder':{pin:[['P0',100],['P1',101],['P2',102],['P3',103],['P4',104],['P5',105],['P6',106],['P7',107]]}});")); + oappend(F("addInfo('Rotary-Encoder:PCF8574-address',1,'(not hex!)');")); + oappend(F("d.extra.push({'Rotary-Encoder':{pin:[['P0',100],['P1',101],['P2',102],['P3',103],['P4',104],['P5',105],['P6',106],['P7',107]]}});")); } /** diff --git a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.h b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.h index b66be290a..7ecec08e5 100644 --- a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.h +++ b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.h @@ -433,8 +433,8 @@ class WordClockUsermod : public Usermod void appendConfigData() { - oappend(SET_F("addInfo('WordClockUsermod:ledOffset', 1, 'Number of LEDs before the letters');")); - oappend(SET_F("addInfo('WordClockUsermod:Norddeutsch', 1, 'Viertel vor instead of Dreiviertel');")); + oappend(F("addInfo('WordClockUsermod:ledOffset', 1, 'Number of LEDs before the letters');")); + oappend(F("addInfo('WordClockUsermod:Norddeutsch', 1, 'Viertel vor instead of Dreiviertel');")); } /* diff --git a/usermods/wireguard/wireguard.h b/usermods/wireguard/wireguard.h index 8c88d0001..8656a704a 100644 --- a/usermods/wireguard/wireguard.h +++ b/usermods/wireguard/wireguard.h @@ -54,13 +54,13 @@ class WireguardUsermod : public Usermod { } void appendConfigData() { - oappend(SET_F("addInfo('WireGuard:host',1,'Server Hostname');")); // 0 is field type, 1 is actual field - oappend(SET_F("addInfo('WireGuard:port',1,'Server Port');")); // 0 is field type, 1 is actual field - oappend(SET_F("addInfo('WireGuard:ip',1,'Device IP');")); // 0 is field type, 1 is actual field - oappend(SET_F("addInfo('WireGuard:psk',1,'Pre Shared Key (optional)');")); // 0 is field type, 1 is actual field - oappend(SET_F("addInfo('WireGuard:pem',1,'Private Key');")); // 0 is field type, 1 is actual field - oappend(SET_F("addInfo('WireGuard:pub',1,'Public Key');")); // 0 is field type, 1 is actual field - oappend(SET_F("addInfo('WireGuard:tz',1,'POSIX timezone string');")); // 0 is field type, 1 is actual field + oappend(F("addInfo('WireGuard:host',1,'Server Hostname');")); // 0 is field type, 1 is actual field + oappend(F("addInfo('WireGuard:port',1,'Server Port');")); // 0 is field type, 1 is actual field + oappend(F("addInfo('WireGuard:ip',1,'Device IP');")); // 0 is field type, 1 is actual field + oappend(F("addInfo('WireGuard:psk',1,'Pre Shared Key (optional)');")); // 0 is field type, 1 is actual field + oappend(F("addInfo('WireGuard:pem',1,'Private Key');")); // 0 is field type, 1 is actual field + oappend(F("addInfo('WireGuard:pub',1,'Public Key');")); // 0 is field type, 1 is actual field + oappend(F("addInfo('WireGuard:tz',1,'POSIX timezone string');")); // 0 is field type, 1 is actual field } void addToConfig(JsonObject& root) { diff --git a/wled00/FX.cpp b/wled00/FX.cpp index d4b83de6c..2f24f745a 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -2506,9 +2506,9 @@ static uint16_t ripple_base() { #endif { int left = rippleorigin - propI -1; - int right = rippleorigin + propI +3; + int right = rippleorigin + propI +2; for (int v = 0; v < 4; v++) { - unsigned mag = scale8(cubicwave8((propF>>2)+(v-left)*64), amp); + unsigned mag = scale8(cubicwave8((propF>>2) + v * 64), amp); SEGMENT.setPixelColor(left + v, color_blend(SEGMENT.getPixelColor(left + v), col, mag)); // TODO SEGMENT.setPixelColor(right - v, color_blend(SEGMENT.getPixelColor(right - v), col, mag)); // TODO } diff --git a/wled00/FX.h b/wled00/FX.h index 385c52476..545161546 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -47,6 +47,15 @@ #define FRAMETIME_FIXED (1000/WLED_FPS) #define FRAMETIME strip.getFrameTime() +// FPS calculation (can be defined as compile flag for debugging) +#ifndef FPS_CALC_AVG +#define FPS_CALC_AVG 7 // average FPS calculation over this many frames (moving average) +#endif +#ifndef FPS_MULTIPLIER +#define FPS_MULTIPLIER 1 // dev option: multiplier to get sub-frame FPS without floats +#endif +#define FPS_CALC_SHIFT 7 // bit shift for fixed point math + /* each segment uses 82 bytes of SRAM memory, so if you're application fails because of insufficient memory, decreasing MAX_NUM_SEGMENTS may help */ #ifdef ESP8266 @@ -525,12 +534,12 @@ typedef struct Segment { inline static const CRGBPalette16 &getCurrentPalette() { return Segment::_currentPalette; } void setUp(uint16_t i1, uint16_t i2, uint8_t grp=1, uint8_t spc=0, uint16_t ofs=UINT16_MAX, uint16_t i1Y=0, uint16_t i2Y=1); - bool setColor(uint8_t slot, uint32_t c); //returns true if changed - void setCCT(uint16_t k); - void setOpacity(uint8_t o); - void setOption(uint8_t n, bool val); - void setMode(uint8_t fx, bool loadDefaults = false); - void setPalette(uint8_t pal); + Segment &setColor(uint8_t slot, uint32_t c); + Segment &setCCT(uint16_t k); + Segment &setOpacity(uint8_t o); + Segment &setOption(uint8_t n, bool val); + Segment &setMode(uint8_t fx, bool loadDefaults = false); + Segment &setPalette(uint8_t pal); uint8_t differs(Segment& b) const; void refreshLightCapabilities(); @@ -545,7 +554,7 @@ typedef struct Segment { * Call resetIfRequired before calling the next effect function. * Safe to call from interrupts and network requests. */ - inline void markForReset() { reset = true; } // setOption(SEG_OPTION_RESET, true) + inline Segment &markForReset() { reset = true; return *this; } // setOption(SEG_OPTION_RESET, true) // transition functions void startTransition(uint16_t dur); // transition has to start before actual segment values change @@ -599,9 +608,15 @@ typedef struct Segment { } // 2D matrix - [[gnu::hot]] uint16_t virtualWidth() const; // segment width in virtual pixels (accounts for groupping and spacing) - [[gnu::hot]] uint16_t virtualHeight() const; // segment height in virtual pixels (accounts for groupping and spacing) - uint16_t nrOfVStrips() const; // returns number of virtual vertical strips in 2D matrix (used to expand 1D effects into 2D) + [[gnu::hot]] unsigned virtualWidth() const; // segment width in virtual pixels (accounts for groupping and spacing) + [[gnu::hot]] unsigned virtualHeight() const; // segment height in virtual pixels (accounts for groupping and spacing) + inline unsigned nrOfVStrips() const { // returns number of virtual vertical strips in 2D matrix (used to expand 1D effects into 2D) + #ifndef WLED_DISABLE_2D + return (is2D() && map1D2D == M12_pBar) ? virtualWidth() : 1; + #else + return 1; + #endif + } #ifndef WLED_DISABLE_2D [[gnu::hot]] uint16_t XY(int x, int y); // support function to get relative index within segment [[gnu::hot]] void setPixelColorXY(int x, int y, uint32_t c); // set relative pixel within segment with color @@ -723,7 +738,7 @@ class WS2812FX { // 96 bytes _transitionDur(750), _targetFps(WLED_FPS), _frametime(FRAMETIME_FIXED), - _cumulativeFps(2), + _cumulativeFps(50 << FPS_CALC_SHIFT), _isServicing(false), _isOffRefreshRequired(false), _hasWhiteChannel(false), @@ -778,7 +793,8 @@ class WS2812FX { // 96 bytes setTargetFps(uint8_t fps), setupEffectData(); // add default effects to the list; defined in FX.cpp - inline void restartRuntime() { for (Segment &seg : _segments) seg.markForReset(); } + inline void resetTimebase() { timebase = 0UL - millis(); } + inline void restartRuntime() { for (Segment &seg : _segments) { seg.markForReset().resetIfRequired(); } } inline void setTransitionMode(bool t) { for (Segment &seg : _segments) seg.startTransition(t ? _transitionDur : 0); } inline void setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setColor(slot, RGBW32(r,g,b,w)); } inline void setPixelColor(unsigned n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); } @@ -834,10 +850,8 @@ class WS2812FX { // 96 bytes inline uint16_t getLength() const { return _length; } // returns actual amount of LEDs on a strip (2D matrix may have less LEDs than W*H) inline uint16_t getTransition() const { return _transitionDur; } // returns currently set transition time (in ms) - uint32_t - now, - timebase, - getPixelColor(uint16_t) const; + unsigned long now, timebase; + uint32_t getPixelColor(unsigned) const; inline uint32_t getLastShow() const { return _lastShow; } // returns millis() timestamp of last strip.show() call inline uint32_t segColor(uint8_t i) const { return _colors_t[i]; } // returns currently valid color (for slot i) AKA SEGCOLOR(); may be blended between two colors while in transition diff --git a/wled00/FX_2Dfcn.cpp b/wled00/FX_2Dfcn.cpp index e38602ebc..7c1ae366b 100644 --- a/wled00/FX_2Dfcn.cpp +++ b/wled00/FX_2Dfcn.cpp @@ -156,7 +156,7 @@ uint16_t IRAM_ATTR_YN Segment::XY(int x, int y) void IRAM_ATTR_YN Segment::setPixelColorXY(int x, int y, uint32_t col) { if (!isActive()) return; // not active - if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return; // if pixel would fall out of virtual segment just exit + if ((unsigned)x >= virtualWidth() || (unsigned)y >= virtualHeight() || x<0 || y<0) return; // if pixel would fall out of virtual segment just exit uint8_t _bri_t = currentBri(); if (_bri_t < 255) { @@ -251,7 +251,7 @@ void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa) // returns RGBW values of pixel uint32_t IRAM_ATTR_YN Segment::getPixelColorXY(int x, int y) const { if (!isActive()) return 0; // not active - if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return 0; // if pixel would fall out of virtual segment just exit + if ((unsigned)x >= virtualWidth() || (unsigned)y >= virtualHeight() || x<0 || y<0) return 0; // if pixel would fall out of virtual segment just exit if (reverse ) x = virtualWidth() - x - 1; if (reverse_y) y = virtualHeight() - y - 1; if (transpose) { std::swap(x,y); } // swap X & Y if segment transposed diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 79189ef57..e706f2b43 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -509,46 +509,53 @@ void Segment::setUp(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t } -bool Segment::setColor(uint8_t slot, uint32_t c) { //returns true if changed - if (slot >= NUM_COLORS || c == colors[slot]) return false; +Segment &Segment::setColor(uint8_t slot, uint32_t c) { + if (slot >= NUM_COLORS || c == colors[slot]) return *this; if (!_isRGB && !_hasW) { - if (slot == 0 && c == BLACK) return false; // on/off segment cannot have primary color black - if (slot == 1 && c != BLACK) return false; // on/off segment cannot have secondary color non black + if (slot == 0 && c == BLACK) return *this; // on/off segment cannot have primary color black + if (slot == 1 && c != BLACK) return *this; // on/off segment cannot have secondary color non black } if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change colors[slot] = c; stateChanged = true; // send UDP/WS broadcast - return true; + return *this; } -void Segment::setCCT(uint16_t k) { +Segment &Segment::setCCT(uint16_t k) { if (k > 255) { //kelvin value, convert to 0-255 if (k < 1900) k = 1900; if (k > 10091) k = 10091; k = (k - 1900) >> 5; } - if (cct == k) return; - if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change - cct = k; - stateChanged = true; // send UDP/WS broadcast + if (cct != k) { + //DEBUGFX_PRINTF_P(PSTR("- Starting CCT transition: %d\n"), k); + startTransition(strip.getTransition()); // start transition prior to change + cct = k; + stateChanged = true; // send UDP/WS broadcast + } + return *this; } -void Segment::setOpacity(uint8_t o) { - if (opacity == o) return; - if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change - opacity = o; - stateChanged = true; // send UDP/WS broadcast +Segment &Segment::setOpacity(uint8_t o) { + if (opacity != o) { + //DEBUGFX_PRINTF_P(PSTR("- Starting opacity transition: %d\n"), o); + startTransition(strip.getTransition()); // start transition prior to change + opacity = o; + stateChanged = true; // send UDP/WS broadcast + } + return *this; } -void Segment::setOption(uint8_t n, bool val) { +Segment &Segment::setOption(uint8_t n, bool val) { bool prevOn = on; if (fadeTransition && n == SEG_OPTION_ON && val != prevOn) startTransition(strip.getTransition()); // start transition prior to change if (val) options |= 0x01 << n; else options &= ~(0x01 << n); if (!(n == SEG_OPTION_SELECTED || n == SEG_OPTION_RESET)) stateChanged = true; // send UDP/WS broadcast + return *this; } -void Segment::setMode(uint8_t fx, bool loadDefaults) { +Segment &Segment::setMode(uint8_t fx, bool loadDefaults) { // skip reserved while (fx < strip.getModeCount() && strncmp_P("RSVD", strip.getModeData(fx), 4) == 0) fx++; if (fx >= strip.getModeCount()) fx = 0; // set solid mode @@ -580,9 +587,10 @@ void Segment::setMode(uint8_t fx, bool loadDefaults) { markForReset(); stateChanged = true; // send UDP/WS broadcast } + return *this; } -void Segment::setPalette(uint8_t pal) { +Segment &Segment::setPalette(uint8_t pal) { if (pal < 245 && pal > GRADIENT_PALETTE_COUNT+13) pal = 0; // built in palettes if (pal > 245 && (strip.customPalettes.size() == 0 || 255U-pal > strip.customPalettes.size()-1)) pal = 0; // custom palettes if (pal != palette) { @@ -590,37 +598,24 @@ void Segment::setPalette(uint8_t pal) { palette = pal; stateChanged = true; // send UDP/WS broadcast } + return *this; } // 2D matrix -uint16_t IRAM_ATTR Segment::virtualWidth() const { +unsigned IRAM_ATTR Segment::virtualWidth() const { unsigned groupLen = groupLength(); unsigned vWidth = ((transpose ? height() : width()) + groupLen - 1) / groupLen; if (mirror) vWidth = (vWidth + 1) /2; // divide by 2 if mirror, leave at least a single LED return vWidth; } -uint16_t IRAM_ATTR Segment::virtualHeight() const { +unsigned IRAM_ATTR Segment::virtualHeight() const { unsigned groupLen = groupLength(); unsigned vHeight = ((transpose ? width() : height()) + groupLen - 1) / groupLen; if (mirror_y) vHeight = (vHeight + 1) /2; // divide by 2 if mirror, leave at least a single LED return vHeight; } -uint16_t IRAM_ATTR_YN Segment::nrOfVStrips() const { - unsigned vLen = 1; -#ifndef WLED_DISABLE_2D - if (is2D()) { - switch (map1D2D) { - case M12_pBar: - vLen = virtualWidth(); - break; - } - } -#endif - return vLen; -} - // Constants for mapping mode "Pinwheel" #ifndef WLED_DISABLE_2D constexpr int Pinwheel_Steps_Small = 72; // no holes up to 16x16 @@ -1187,10 +1182,7 @@ uint32_t Segment::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_ //do not call this method from system context (network callback) void WS2812FX::finalizeInit() { //reset segment runtimes - for (segment &seg : _segments) { - seg.markForReset(); - seg.resetIfRequired(); - } + restartRuntime(); // for the lack of better place enumerate ledmaps here // if we do it in json.cpp (serializeInfo()) we are getting flashes on LEDs @@ -1337,7 +1329,7 @@ void WS2812FX::service() { if (nowUp > seg.next_time || _triggered || (doShow && seg.mode == FX_MODE_STATIC)) { doShow = true; - unsigned delay = FRAMETIME; + unsigned frameDelay = FRAMETIME; if (!seg.freeze) { //only run effect function if not frozen int oldCCT = BusManager::getSegmentCCT(); // store original CCT value (actually it is not Segment based) @@ -1357,7 +1349,7 @@ void WS2812FX::service() { // overwritten by later effect. To enable seamless blending for every effect, additional LED buffer // would need to be allocated for each effect and then blended together for each pixel. [[maybe_unused]] uint8_t tmpMode = seg.currentMode(); // this will return old mode while in transition - delay = (*_mode[seg.mode])(); // run new/current mode + frameDelay = (*_mode[seg.mode])(); // run new/current mode #ifndef WLED_DISABLE_MODE_BLEND if (modeBlending && seg.mode != tmpMode) { Segment::tmpsegd_t _tmpSegData; @@ -1366,16 +1358,16 @@ void WS2812FX::service() { _virtualSegmentLength = seg.virtualLength(); // update SEGLEN (mapping may have changed) unsigned d2 = (*_mode[tmpMode])(); // run old mode seg.restoreSegenv(_tmpSegData); // restore mode state (will also update transitional state) - delay = MIN(delay,d2); // use shortest delay + frameDelay = min(frameDelay,d2); // use shortest delay Segment::modeBlend(false); // unset semaphore } #endif seg.call++; - if (seg.isInTransition() && delay > FRAMETIME) delay = FRAMETIME; // force faster updates during transition + if (seg.isInTransition() && frameDelay > FRAMETIME) frameDelay = FRAMETIME; // force faster updates during transition BusManager::setSegmentCCT(oldCCT); // restore old CCT for ABL adjustments } - seg.next_time = nowUp + delay; + seg.next_time = nowUp + frameDelay; } _segment_index++; } @@ -1402,7 +1394,7 @@ void IRAM_ATTR WS2812FX::setPixelColor(unsigned i, uint32_t col) { BusManager::setPixelColor(i, col); } -uint32_t IRAM_ATTR WS2812FX::getPixelColor(uint16_t i) const { +uint32_t IRAM_ATTR WS2812FX::getPixelColor(unsigned i) const { i = getMappedPixelIndex(i); if (i >= _length) return 0; return BusManager::getPixelColor(i); @@ -1420,10 +1412,12 @@ void WS2812FX::show() { unsigned long showNow = millis(); size_t diff = showNow - _lastShow; - size_t fpsCurr = 200; - if (diff > 0) fpsCurr = 1000 / diff; - _cumulativeFps = (3 * _cumulativeFps + fpsCurr +2) >> 2; // "+2" for proper rounding (2/4 = 0.5) - _lastShow = showNow; + + if (diff > 0) { // skip calculation if no time has passed + size_t fpsCurr = (1000 << FPS_CALC_SHIFT) / diff; // fixed point math + _cumulativeFps = (FPS_CALC_AVG * _cumulativeFps + fpsCurr + FPS_CALC_AVG / 2) / (FPS_CALC_AVG + 1); // "+FPS_CALC_AVG/2" for proper rounding + _lastShow = showNow; + } } /** @@ -1440,7 +1434,7 @@ bool WS2812FX::isUpdating() const { */ uint16_t WS2812FX::getFps() const { if (millis() - _lastShow > 2000) return 0; - return _cumulativeFps +1; + return (FPS_MULTIPLIER * _cumulativeFps) >> FPS_CALC_SHIFT; // _cumulativeFps is stored in fixed point } void WS2812FX::setTargetFps(uint8_t fps) { diff --git a/wled00/button.cpp b/wled00/button.cpp index f02ed3d6d..4d6f954f6 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -215,6 +215,7 @@ void handleAnalog(uint8_t b) briLast = bri; bri = 0; } else { + if (bri == 0) strip.restartRuntime(); bri = aRead; } } else if (macroDoublePress[b] == 249) { diff --git a/wled00/const.h b/wled00/const.h index 14ec23b58..07873deca 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -53,7 +53,7 @@ #else #define WLED_MAX_ANALOG_CHANNELS (LEDC_CHANNEL_MAX*LEDC_SPEED_MODE_MAX) #if defined(CONFIG_IDF_TARGET_ESP32C3) // 2 RMT, 6 LEDC, only has 1 I2S but NPB does not support it ATM - #define WLED_MAX_BUSSES 4 // will allow 2 digital & 2 analog RGB + #define WLED_MAX_BUSSES 6 // will allow 2 digital & 2 analog RGB or 6 PWM white #define WLED_MAX_DIGITAL_CHANNELS 2 //#define WLED_MAX_ANALOG_CHANNELS 6 #define WLED_MIN_VIRTUAL_BUSSES 3 diff --git a/wled00/data/index.css b/wled00/data/index.css index 2ae17ffe5..31e2daa92 100644 --- a/wled00/data/index.css +++ b/wled00/data/index.css @@ -1041,7 +1041,7 @@ textarea { .segname .flr, .pname .flr { transform: rotate(0deg); - right: -6px; + /*right: -6px;*/ } /* segment power wrapper */ @@ -1344,6 +1344,11 @@ TD .checkmark, TD .radiomark { box-shadow: 0 0 10px 4px var(--c-1); } +.lstI .flr:hover { + background: var(--c-6); + border-radius: 100%; +} + #pcont .selected:not([class*="expanded"]) { bottom: 52px; top: 42px; diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index 71b00599c..1855a8b63 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -169,7 +169,6 @@ bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient = 0); void setValuesFromSegment(uint8_t s); void setValuesFromMainSeg(); void setValuesFromFirstSelectedSeg(); -void resetTimebase(); void toggleOnOff(); void applyBri(); void applyFinalBri(); @@ -324,6 +323,10 @@ class Usermod { protected: // Shim for oappend(), which used to exist in utils.cpp template static inline void oappend(const T& t) { oappend_shim->print(t); }; +#ifdef ESP8266 + // Handle print(PSTR()) without crashing by detecting PROGMEM strings + static void oappend(const char* c) { if ((intptr_t) c >= 0x40000000) oappend_shim->print(FPSTR(c)); else oappend_shim->print(c); }; +#endif }; class UsermodManager { diff --git a/wled00/json.cpp b/wled00/json.cpp index 06eb3015e..288059653 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -346,7 +346,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId) } } - int tr = -1; + long tr = -1; if (!presetId || currentPlaylist < 0) { //do not apply transition time from preset if playlist active, as it would override playlist transition times tr = root[F("transition")] | -1; if (tr >= 0) { @@ -363,7 +363,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId) } tr = root[F("tb")] | -1; - if (tr >= 0) strip.timebase = ((uint32_t)tr) - millis(); + if (tr >= 0) strip.timebase = (unsigned long)tr - millis(); JsonObject nl = root["nl"]; nightlightActive = getBoolVal(nl["on"], nightlightActive); diff --git a/wled00/led.cpp b/wled00/led.cpp index 9de0495b4..9b97091e6 100644 --- a/wled00/led.cpp +++ b/wled00/led.cpp @@ -47,17 +47,12 @@ void applyValuesToSelectedSegs() } -void resetTimebase() -{ - strip.timebase = 0 - millis(); -} - - void toggleOnOff() { if (bri == 0) { bri = briLast; + strip.restartRuntime(); } else { briLast = bri; @@ -122,7 +117,7 @@ void stateUpdated(byte callMode) { nightlightStartTime = millis(); } if (briT == 0) { - if (callMode != CALL_MODE_NOTIFICATION) resetTimebase(); //effect start from beginning + if (callMode != CALL_MODE_NOTIFICATION) strip.resetTimebase(); //effect start from beginning } if (bri > 0) briLast = bri; diff --git a/wled00/pin_manager.cpp b/wled00/pin_manager.cpp index 793b5440c..0d4c2ad5c 100644 --- a/wled00/pin_manager.cpp +++ b/wled00/pin_manager.cpp @@ -201,7 +201,12 @@ bool PinManager::isPinOk(byte gpio, bool output) if (gpio > 18 && gpio < 21) return false; // 19 + 20 = USB-JTAG. Not recommended for other uses. #endif if (gpio > 21 && gpio < 33) return false; // 22 to 32: not connected + SPI FLASH - if (gpio > 32 && gpio < 38) return !psramFound(); // 33 to 37: not available if using _octal_ SPI Flash or _octal_ PSRAM + #if CONFIG_ESPTOOLPY_FLASHMODE_OPI // 33-37: never available if using _octal_ Flash (opi_opi) + if (gpio > 32 && gpio < 38) return false; + #endif + #if CONFIG_SPIRAM_MODE_OCT // 33-37: not available if using _octal_ PSRAM (qio_opi), but free to use on _quad_ PSRAM (qio_qspi) + if (gpio > 32 && gpio < 38) return !psramFound(); + #endif // 38 to 48 are for general use. Be careful about straping pins GPIO45 and GPIO46 - these may be pull-up or pulled-down on your board. #elif defined(CONFIG_IDF_TARGET_ESP32S2) // strapping pins: 0, 45 & 46 diff --git a/wled00/presets.cpp b/wled00/presets.cpp index 20edfd91e..04474113d 100644 --- a/wled00/presets.cpp +++ b/wled00/presets.cpp @@ -143,6 +143,7 @@ void applyPresetWithFallback(uint8_t index, uint8_t callMode, uint8_t effectID, void handlePresets() { + byte presetErrFlag = ERR_NONE; if (presetToSave) { strip.suspend(); doSaveState(); @@ -166,14 +167,16 @@ void handlePresets() #ifdef ARDUINO_ARCH_ESP32 if (tmpPreset==255 && tmpRAMbuffer!=nullptr) { deserializeJson(*pDoc,tmpRAMbuffer); - errorFlag = ERR_NONE; } else #endif { - errorFlag = readObjectFromFileUsingId(getPresetsFileName(tmpPreset < 255), tmpPreset, pDoc) ? ERR_NONE : ERR_FS_PLOAD; + presetErrFlag = readObjectFromFileUsingId(getPresetsFileName(tmpPreset < 255), tmpPreset, pDoc) ? ERR_NONE : ERR_FS_PLOAD; } fdo = pDoc->as(); + // only reset errorflag if previous error was preset-related + if ((errorFlag == ERR_NONE) || (errorFlag == ERR_FS_PLOAD)) errorFlag = presetErrFlag; + //HTTP API commands const char* httpwin = fdo["win"]; if (httpwin) { diff --git a/wled00/set.cpp b/wled00/set.cpp index c446a2eff..712e5f254 100644 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -1191,7 +1191,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply) // internal call, does not send XML response pos = req.indexOf(F("IN")); - if (pos < 1) { + if ((request != nullptr) && (pos < 1)) { auto response = request->beginResponseStream("text/xml"); XML_response(*response); request->send(response); diff --git a/wled00/src/dependencies/espalexa/Espalexa.h b/wled00/src/dependencies/espalexa/Espalexa.h index 5c780e248..ae761e9fa 100644 --- a/wled00/src/dependencies/espalexa/Espalexa.h +++ b/wled00/src/dependencies/espalexa/Espalexa.h @@ -120,10 +120,8 @@ private: void encodeLightId(uint8_t idx, char* out) { - uint8_t mac[6]; - WiFi.macAddress(mac); - - sprintf_P(out, PSTR("%02X:%02X:%02X:%02X:%02X:%02X:00:11-%02X"), mac[0],mac[1],mac[2],mac[3],mac[4],mac[5], idx); + String mymac = WiFi.macAddress(); + sprintf_P(out, PSTR("%02X:%s:AB-%02X"), idx, mymac.c_str(), idx); } // construct 'globally unique' Json dict key fitting into signed int diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 13d43218a..d6a39a399 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -380,6 +380,12 @@ void WLED::setup() case FM_QOUT: DEBUG_PRINT(F("(QOUT)"));break; case FM_DIO: DEBUG_PRINT(F("(DIO)")); break; case FM_DOUT: DEBUG_PRINT(F("(DOUT)"));break; + #if defined(CONFIG_IDF_TARGET_ESP32S3) && CONFIG_ESPTOOLPY_FLASHMODE_OPI + case FM_FAST_READ: DEBUG_PRINT(F("(OPI)")); break; + #else + case FM_FAST_READ: DEBUG_PRINT(F("(fast_read)")); break; + #endif + case FM_SLOW_READ: DEBUG_PRINT(F("(slow_read)")); break; default: break; } #endif diff --git a/wled00/wled.h b/wled00/wled.h index bc525cd6f..2b3a77d24 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -3,12 +3,12 @@ /* Main sketch, global variable declarations @title WLED project sketch - @version 0.15.0-b6 + @version 0.15.0-b7 @author Christian Schwinne */ // version code in format yymmddb (b = daily build) -#define VERSION 2410140 +#define VERSION 2410270 //uncomment this if you have a "my_config.h" file you'd like to use //#define WLED_USE_MY_CONFIG @@ -36,12 +36,13 @@ #undef WLED_ENABLE_ADALIGHT // disable has priority over enable #endif //#define WLED_ENABLE_DMX // uses 3.5kb -//#define WLED_ENABLE_JSONLIVE // peek LED output via /json/live (WS binary peek is always enabled) #ifndef WLED_DISABLE_LOXONE #define WLED_ENABLE_LOXONE // uses 1.2kb #endif #ifndef WLED_DISABLE_WEBSOCKETS #define WLED_ENABLE_WEBSOCKETS +#else + #define WLED_ENABLE_JSONLIVE // peek LED output via /json/live (WS binary peek is always enabled) #endif //#define WLED_DISABLE_ESPNOW // Removes dependence on esp now diff --git a/wled00/wled_server.cpp b/wled00/wled_server.cpp index 958b51330..e8cbb41ae 100644 --- a/wled00/wled_server.cpp +++ b/wled00/wled_server.cpp @@ -193,12 +193,12 @@ void createEditHandler(bool enable) { editHandler = &server.addHandler(new SPIFFSEditor("","",WLED_FS));//http_username,http_password)); #endif #else - editHandler = &server.on(SET_F("/edit"), HTTP_GET, [](AsyncWebServerRequest *request){ + editHandler = &server.on(F("/edit"), HTTP_GET, [](AsyncWebServerRequest *request){ serveMessage(request, 501, FPSTR(s_notimplemented), F("The FS editor is disabled in this build."), 254); }); #endif } else { - editHandler = &server.on(SET_F("/edit"), HTTP_ANY, [](AsyncWebServerRequest *request){ + editHandler = &server.on(F("/edit"), HTTP_ANY, [](AsyncWebServerRequest *request){ serveMessage(request, 401, FPSTR(s_accessdenied), FPSTR(s_unlock_cfg), 254); }); } @@ -427,11 +427,11 @@ void initServer() #ifdef WLED_ENABLE_DMX - server.on(SET_F("/dmxmap"), HTTP_GET, [](AsyncWebServerRequest *request){ + server.on(F("/dmxmap"), HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, FPSTR(CONTENT_TYPE_HTML), PAGE_dmxmap , dmxProcessor); }); #else - server.on(SET_F("/dmxmap"), HTTP_GET, [](AsyncWebServerRequest *request){ + server.on(F("/dmxmap"), HTTP_GET, [](AsyncWebServerRequest *request){ serveMessage(request, 501, FPSTR(s_notimplemented), F("DMX support is not enabled in this build."), 254); }); #endif diff --git a/wled00/xml.cpp b/wled00/xml.cpp index 1ac22c9ce..dc2673271 100644 --- a/wled00/xml.cpp +++ b/wled00/xml.cpp @@ -227,7 +227,7 @@ void getSettingsJS(byte subPage, Print& settingsScript) sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]); #if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET) - if (Network.isEthernet()) strcat_P(s ,SET_F(" (Ethernet)")); + if (Network.isEthernet()) strcat_P(s ,PSTR(" (Ethernet)")); #endif printSetClassElementHTML(settingsScript,PSTR("sip"),0,s); } else @@ -501,7 +501,7 @@ void getSettingsJS(byte subPage, Print& settingsScript) #endif printSetFormValue(settingsScript,PSTR("BD"),serialBaud); #ifndef WLED_ENABLE_ADALIGHT - settingsScript.print(F("toggle('Serial);")); + settingsScript.print(F("toggle('Serial');")); #endif }