diff --git a/usermods/audioreactive/audio_reactive.h b/usermods/audioreactive/audio_reactive.h index 99d6d7bf..4ae5474c 100644 --- a/usermods/audioreactive/audio_reactive.h +++ b/usermods/audioreactive/audio_reactive.h @@ -191,7 +191,7 @@ static const float fftResultPink[MAX_PINK+1][NUM_GEQ_CHANNELS] = { { 12.0f, 6.60f, 2.60f, 1.15f, 1.35f, 2.05f, 2.85f, 2.50f, 2.85f, 3.30f, 2.25f, 4.35f, 3.80f, 3.75f, 6.50f, 9.00f}, // 4 IMNP441 - voice, or small speaker { 2.75f, 1.60f, 1.40f, 1.46f, 1.52f, 1.57f, 1.68f, 1.80f, 1.89f, 2.00f, 2.11f, 2.21f, 2.30f, 1.75f, 2.55f, 3.60f }, // 5 ICS-43434 datasheet response * pink noise - { 2.25f, 1.20f, 1.00f, 1.20f, 1.80f, 3.20f, 5.10f, 5.50f, 4.00f, 4.80f, 6.70f, 6.40f, 5.80f, 3.90f, 6.00f, 5.10f }, // 6 ICS-43434 - big speaker, strong bass + { 2.90f, 1.25f, 0.75f, 1.08f, 2.35f, 3.55f, 3.60f, 3.40f, 2.75f, 3.45f, 4.40f, 6.35f, 6.80f, 6.80f, 8.50f,10.64f }, // 6 ICS-43434 - big speaker, strong bass { 1.65f, 1.00f, 1.05f, 1.30f, 1.48f, 1.30f, 1.80f, 3.00f, 1.50f, 1.65f, 2.56f, 3.00f, 2.60f, 2.30f, 5.00f, 3.00f }, // 7 SPM1423 { 2.25f, 1.60f, 1.30f, 1.60f, 2.20f, 3.20f, 3.06f, 2.60f, 2.85f, 3.50f, 4.10f, 4.80f, 5.70f, 6.05f,10.50f,14.85f }, // 8 userdef #1 for ewowi (enhance median/high freqs) @@ -908,7 +908,9 @@ class AudioReactive : public Usermod { static const char _name[]; static const char _enabled[]; static const char _inputLvl[]; +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3) static const char _analogmic[]; +#endif static const char _digitalmic[]; static const char UDP_SYNC_HEADER[]; static const char UDP_SYNC_HEADER_v1[]; @@ -2132,10 +2134,12 @@ class AudioReactive : public Usermod { oappend(SET_F("addInfo('AudioReactive:help',0,'');")); //WLEDMM: add defaults + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3) // -S3/-S2/-C3 don't support analog audio #ifdef AUDIOPIN oappend(SET_F("xOpt('AudioReactive:analogmic:pin',1,' ⎌',")); oappendi(AUDIOPIN); oappend(");"); #endif oappend(SET_F("aOpt('AudioReactive:analogmic:pin',1);")); //only analog options + #endif oappend(SET_F("dd=addDropdown('AudioReactive','digitalmic:type');")); #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3) @@ -2353,7 +2357,9 @@ class AudioReactive : public Usermod { const char AudioReactive::_name[] PROGMEM = "AudioReactive"; const char AudioReactive::_enabled[] PROGMEM = "enabled"; const char AudioReactive::_inputLvl[] PROGMEM = "inputLevel"; +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3) const char AudioReactive::_analogmic[] PROGMEM = "analogmic"; +#endif const char AudioReactive::_digitalmic[] PROGMEM = "digitalmic"; const char AudioReactive::UDP_SYNC_HEADER[] PROGMEM = "00002"; // new sync header version, as format no longer compatible with previous structure const char AudioReactive::UDP_SYNC_HEADER_v1[] PROGMEM = "00001"; // old sync header version - need to add backwards-compatibility feature 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 44867c82..ff60a4d4 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 @@ -2,37 +2,37 @@ #include // WLEDMM: make sure that I2C drivers have the "right" Wire Object #include +#include #undef U8X8_NO_HW_I2C // WLEDMM: we do want I2C hardware drivers - if possible -//#define WIRE_INTERFACES_COUNT 2 // experimental - tell U8x8Lib that there is a second Wire unit +//#define WIRE_INTERFACES_COUNT 2 // experimental - tell U8x8Lib that there is a second Wire unit #include "wled.h" #include // from https://github.com/olikraus/u8g2/ #include "4LD_wled_fonts.c" #ifndef FLD_ESP32_NO_THREADS -#define FLD_ESP32_USE_THREADS // comment out to use 0.13.x behviour without parallel update task - slower, but more robust. May delay other tasks like LEDs or audioreactive!! +#define FLD_ESP32_USE_THREADS // comment out to use 0.13.x behaviour without parallel update task - slower, but more robust. May delay other tasks like LEDs or audioreactive!! #endif //#define OLD_4LD_FONTS // comment out if you prefer the "classic" look with blocky fonts (saves 1K flash) // -// Insired by the usermod_v2_four_line_display +// Inspired by the usermod_v2_four_line_display // // v2 usermod for using 128x32 or 128x64 i2c // OLED displays to provide a four line display // for WLED. // // Dependencies -// * This usermod REQURES the ModeSortUsermod -// * This Usermod works best, by far, when coupled -// with RotaryEncoderUIUsermod. +// * This usermod does not REQUIRE the ModeSortUsermod any more +// * This usermod works best, by far, when coupled +// with RotaryEncoderUI_ALT usermod. // // Make sure to enable NTP and set your time zone in WLED Config | Time. // // REQUIREMENT: You must add the following requirements to // REQUIREMENT: "lib_deps" within platformio.ini / platformio_override.ini -// REQUIREMENT: * U8g2 (the version already in platformio.ini is fine) -// REQUIREMENT: * Wire +// REQUIREMENT: olikraus/U8g2@ ^2.34.15 (the version already in platformio.ini is fine) // //The SCL and SDA pins are defined here. @@ -94,7 +94,9 @@ typedef enum { SSD1305, // U8X8_SSD1305_128X32_ADAFRUIT_HW_I2C SSD1305_64, // U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C SSD1306_SPI, // U8X8_SSD1306_128X32_NONAME_HW_SPI - SSD1306_SPI64 // U8X8_SSD1306_128X64_NONAME_HW_SPI + SSD1306_SPI64=7, // U8X8_SSD1306_128X64_NONAME_HW_SPI + SSD1309_SPI64=8, // U8X8_SSD1309_128X64_NONAME0_4W_HW_SPI + SSD1327_SPI128=9 // U8X8_SSD1327_WS_128X128_4W_SW_SPI } DisplayType; @@ -162,6 +164,8 @@ class FourLineDisplayUsermod : public Usermod { bool enabled = true; #endif bool contrastFix = false; + bool driverHW = false; + bool driverSPI = false; // Next variables hold the previous known values to determine if redraw is // required. @@ -239,8 +243,8 @@ class FourLineDisplayUsermod : public Usermod { if (u8x8 == nullptr) return; if (FLD_SemaphoreTake(drawMux, maxWait) != pdTRUE) return; // WLEDMM acquire draw mutex -#if defined(ARDUINO_ARCH_ESP32) && !defined(OLD_4LD_FONTS) // WLEDMM use nicer 2x2 font on ESP32 - if (!ignoreLH && lineHeight==2) { +#if defined(ARDUINO_ARCH_ESP32) && !defined(OLD_4LD_FONTS) // WLEDMM use nicer 2x2 font on ESP32 + if (!ignoreLH && lineHeight>1) { if(strlen(string) > 3) // WLEDMM little hack - less than 3 chars -> show in bold u8x8->setFont(u8x8_font_7x14_1x2_r); // normal else @@ -253,8 +257,8 @@ class FourLineDisplayUsermod : public Usermod { } #else u8x8->setFont(u8x8_font_chroma48medium8_r); - if (!ignoreLH && lineHeight==2) u8x8->draw1x2String(col, row, string); - else u8x8->drawString(col, row, string); + if (!ignoreLH && lineHeight>1) u8x8->draw1x2String(col, row, string); + else u8x8->drawString(col, row, string); #endif FLD_SemaphoreGive(drawMux); // WLEDMM release draw mutex } @@ -262,8 +266,8 @@ class FourLineDisplayUsermod : public Usermod { if (!typeOK || !enabled) return; if (u8x8 == nullptr) return; if (FLD_SemaphoreTake(drawMux, maxWait) != pdTRUE) return; // WLEDMM acquire draw mutex -#if defined(ARDUINO_ARCH_ESP32) && !defined(OLD_4LD_FONTS) // WLEDMM use nicer 2x2 font on ESP32 - if (lineHeight==2) { // WLEDMM use 2x3 on 128x64 displays +#if defined(ARDUINO_ARCH_ESP32) && !defined(OLD_4LD_FONTS) // WLEDMM use nicer 2x2 font on ESP32 + if (lineHeight>1) { // WLEDMM use 2x3 on 128x64 displays //u8x8->setFont(u8x8_font_profont29_2x3_r); // sans serif 2x3 u8x8->setFont(u8x8_font_courB18_2x3_r); // courier bold 2x3 u8x8->drawString(col, row + (row >3? 1:0), string); @@ -275,7 +279,7 @@ class FourLineDisplayUsermod : public Usermod { } #else u8x8->setFont(u8x8_font_chroma48medium8_r); - if (lineHeight==2) { // WLEDMM use 2x3 on 128x64 displays + if (lineHeight>1) { // WLEDMM use 2x3 on 128x64 displays u8x8->draw2x2String(col, row + (row >3? 1:0), string); } else { u8x8->draw2x2String(col, row, string); @@ -287,7 +291,7 @@ class FourLineDisplayUsermod : public Usermod { if (!typeOK || !enabled) return; if (FLD_SemaphoreTake(drawMux, maxWait) != pdTRUE) return; // WLEDMM acquire draw mutex u8x8->setFont(font); - if (!ignoreLH && lineHeight==2) u8x8->draw1x2Glyph(col, row, glyph); + if (!ignoreLH && lineHeight>1) u8x8->draw1x2Glyph(col, row, glyph); else u8x8->drawGlyph(col, row, glyph); FLD_SemaphoreGive(drawMux); // WLEDMM release draw mutex } @@ -324,7 +328,7 @@ class FourLineDisplayUsermod : public Usermod { void draw2x2GlyphIcons() { if (!typeOK || !enabled) return; // WLEDMM make sure the display is initialized before we try to draw on it if (FLD_SemaphoreTake(drawMuxBig, maxWaitLong) != pdTRUE) return; // WLEDMM acquire BIG draw mutex - if (lineHeight == 2) { + if (lineHeight > 1) { drawGlyph( 1, 0, 1, u8x8_4LineDisplay_WLED_icons_2x2, true); //brightness icon drawGlyph( 5, 0, 2, u8x8_4LineDisplay_WLED_icons_2x2, true); //speed icon drawGlyph( 9, 0, 3, u8x8_4LineDisplay_WLED_icons_2x2, true); //intensity icon @@ -378,7 +382,11 @@ class FourLineDisplayUsermod : public Usermod { drawStatusIcons(); //icons power, wifi, timer, etc if (lineHeight > 1) { // WLEDMM use extra space for useful information - strncpy_P(lineBuffer, PSTR(" "), LINE_BUFFER_SIZE); + #if defined(WLED_DEBUG) || defined(SR_DEBUG) || defined(SR_STATS) + snprintf_P(lineBuffer, LINE_BUFFER_SIZE, PSTR(" %-3.3s %-2.2s "), driverSPI? "SPI" : "I2C", driverHW? "hw" : "sw"); // WLEDMM driver info + #else + strncpy_P(lineBuffer, PSTR(" "), LINE_BUFFER_SIZE); + #endif if (apActive) strncpy_P(lineBuffer, PSTR(" AP mode "), LINE_BUFFER_SIZE); else if (!WLED_CONNECTED) strncpy_P(lineBuffer, PSTR(" NO NET "), LINE_BUFFER_SIZE); if (WLED_MQTT_CONNECTED) lineBuffer[9] = 'M'; // "MQTT" @@ -410,7 +418,7 @@ class FourLineDisplayUsermod : public Usermod { void setup() { if (!enabled) return; // typeOK = true will be set after successful setup - bool isHW, isSPI = (type == SSD1306_SPI || type == SSD1306_SPI64); + bool isHW, isSPI = (type == SSD1306_SPI || type == SSD1306_SPI64 || type > 7); PinOwner po = PinOwner::UM_FourLineDisplay; if (isSPI) { if (ioPin[0] < 0 || ioPin[1] < 0) { @@ -427,6 +435,7 @@ class FourLineDisplayUsermod : public Usermod { isHW = (ioPin[0]==spi_sclk && ioPin[1]==spi_mosi); if ((ioPin[0] == -1) || (ioPin[1] == -1)) isHW = true; // WLEDMM "use global" = hardware + if ((spi_sclk <0) || (spi_mosi < 0)) isHW = false; // no global pins - use software emulation PinManagerPinType cspins[3] = { { ioPin[2], true }, { ioPin[3], true }, { ioPin[4], true } }; if (!pinManager.allocateMultiplePins(cspins, 3, PinOwner::UM_FourLineDisplay)) { typeOK=false; strcpy(errorMessage, PSTR("SPI3 alloc pins failed")); return; } if (isHW) po = PinOwner::HW_SPI; // allow multiple allocations of HW I2C bus pins @@ -437,6 +446,13 @@ class FourLineDisplayUsermod : public Usermod { strcpy(errorMessage, PSTR("SPI2 alloc pins failed")); return; } + // start SPI now! +#ifdef ARDUINO_ARCH_ESP32 + if (isHW) SPI.begin(spi_sclk, spi_miso, spi_mosi); // ESP32 - will silently fail if SPI alread active. +#else + if (isHW) SPI.begin(); // ESP8266 - SPI pins are fixed +#endif + } else { //if (ioPin[0] < 0 || ioPin[1] < 0) { //WLEDMM do _not_ copy global pins !! // ioPin[0] = i2c_scl; @@ -458,6 +474,8 @@ class FourLineDisplayUsermod : public Usermod { } } + driverHW = isHW; + driverSPI= isSPI; DEBUG_PRINTLN(F("Allocating display.")); /* // At some point it may be good to not new/delete U8X8 object but use this instead @@ -529,6 +547,16 @@ class FourLineDisplayUsermod : public Usermod { if (!isHW) u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_4W_SW_SPI(ioPin[0], ioPin[1], ioPin[2], ioPin[3], ioPin[4]); else u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_4W_HW_SPI(ioPin[2], ioPin[3], ioPin[4]); // Pins are cs, dc, reset break; + case SSD1309_SPI64: + // u8x8 uses global SPI variable that is attached to VSPI bus on ESP32 + if (!isHW) u8x8 = (U8X8 *) new U8X8_SSD1309_128X64_NONAME0_4W_SW_SPI(ioPin[0], ioPin[1], ioPin[2], ioPin[3], ioPin[4]); + else u8x8 = (U8X8 *) new U8X8_SSD1309_128X64_NONAME0_4W_HW_SPI(ioPin[2], ioPin[3], ioPin[4]); // Pins are cs, dc, reset + break; + case SSD1327_SPI128: + // u8x8 uses global SPI variable that is attached to VSPI bus on ESP32 + if (!isHW) u8x8 = (U8X8 *) new U8X8_SSD1327_WS_128X128_4W_SW_SPI(ioPin[0], ioPin[1], ioPin[2], ioPin[3], ioPin[4]); + else u8x8 = (U8X8 *) new U8X8_SSD1327_WS_128X128_4W_HW_SPI(ioPin[2], ioPin[3], ioPin[4]); // Pins are cs, dc, reset + break; default: u8x8 = nullptr; } @@ -542,6 +570,8 @@ class FourLineDisplayUsermod : public Usermod { } lineHeight = u8x8->getRows() > 4 ? 2 : 1; + if (u8x8->getRows() > 8) lineHeight =3; + //if (u8x8->getRows() > 12) lineHeight =4; if (isSPI) { USER_PRINTLN(isHW ? F("Starting display (SPI HW).") : F("Starting display (SPI Soft).")); } else { @@ -559,7 +589,7 @@ class FourLineDisplayUsermod : public Usermod { setPowerSave(0); drawing = false; - // init semaphores to enable drawing + // init semaphores to allow drawing FLD_SemaphoreGive(drawMux); FLD_SemaphoreGive(drawMuxBig); @@ -789,9 +819,9 @@ class FourLineDisplayUsermod : public Usermod { uint8_t col = 15; uint8_t row = 0; drawGlyph(col, row, (wificonnected ? 20 : 0), u8x8_4LineDisplay_WLED_icons_1x1, true); // wifi icon - if (lineHeight==2) { col--; } else { row++; } + if (lineHeight>1) { col--; } else { row++; } drawGlyph(col, row, (bri > 0 ? 9 : 0), u8x8_4LineDisplay_WLED_icons_1x1, true); // power icon - if (lineHeight==2) { col--; } else { col = row = 0; } + if (lineHeight>1) { col--; } else { col = row = 0; } drawGlyph(col, row, (nightlightActive ? 6 : 0), u8x8_4LineDisplay_WLED_icons_1x1, true); // moon icon for nightlight mode } @@ -830,7 +860,7 @@ class FourLineDisplayUsermod : public Usermod { for (byte i=5; i<=printedChars; i++) lineBuffer[i-5] = lineBuffer[i]; //include '\0' printedChars -= 5; } - if (lineHeight == 2) { // use this code for 8 line display + if (lineHeight > 1) { // use this code for 8 line display char smallBuffer1[MAX_MODE_LINE_SPACE+1] = { '\0' }; char smallBuffer2[MAX_MODE_LINE_SPACE+1] = { '\0' }; uint8_t smallChars1 = 0; @@ -859,11 +889,11 @@ class FourLineDisplayUsermod : public Usermod { } while (smallChars1 < (MAX_MODE_LINE_SPACE-1)) smallBuffer1[smallChars1++]=' '; smallBuffer1[smallChars1] = 0; - smallBuffer1[MAX_MODE_LINE_SPACE -1] = '\0'; // ensure the string ends where it should (while loop avove can overshoot by 1) + smallBuffer1[MAX_MODE_LINE_SPACE -1] = '\0'; // ensure the string ends where it should (while loop above can overshoot by 1) drawString(1, row*lineHeight, smallBuffer1, true); while (smallChars2 < (MAX_MODE_LINE_SPACE-1)) smallBuffer2[smallChars2++]=' '; smallBuffer2[smallChars2] = 0; - smallBuffer2[MAX_MODE_LINE_SPACE -1] = '\0'; // ensure the string ends where it should (while loop avove can overshoot by 1) + smallBuffer2[MAX_MODE_LINE_SPACE -1] = '\0'; // ensure the string ends where it should (while loop above can overshoot by 1) drawString(1, row*lineHeight+1, smallBuffer2, true); } } else { // use this code for 4 ling displays @@ -917,7 +947,7 @@ class FourLineDisplayUsermod : public Usermod { if (!wakeDisplay()) clear(); // Print the overlay if (glyphType>0 && glyphType<255) { - if (lineHeight == 2) drawGlyph(5, 0, glyphType, u8x8_4LineDisplay_WLED_icons_6x6, true); // use 3x3 font with draw2x2Glyph() if flash runs short and comment out 6x6 font + if (lineHeight > 1) drawGlyph(5, 0, glyphType, u8x8_4LineDisplay_WLED_icons_6x6, true); // use 3x3 font with draw2x2Glyph() if flash runs short and comment out 6x6 font else drawGlyph(6, 0, glyphType, u8x8_4LineDisplay_WLED_icons_3x3, true); } if (line1) { @@ -941,7 +971,7 @@ class FourLineDisplayUsermod : public Usermod { // Turn the display back on if (!wakeDisplay()) clear(); // Print the overlay - if (lineHeight == 2) { + if (lineHeight > 1) { //add a bit of randomness switch (millis()%3) { case 0: @@ -1172,7 +1202,7 @@ class FourLineDisplayUsermod : public Usermod { xTaskCreateUniversal( // this is guaranteed to work on any ESP32 (single or dual core) [](void * par) { // Function to implement the task // see https://www.freertos.org/vtaskdelayuntil.html - const TickType_t xFrequency = REFRESH_RATE_MS * portTICK_PERIOD_MS / 2; + const TickType_t xFrequency = REFRESH_RATE_MS * portTICK_PERIOD_MS / 2; TickType_t xLastWakeTime = xTaskGetTickCount(); for(;;) { delay(1); // DO NOT DELETE THIS LINE! It is needed to give the IDLE(0) task enough time and to keep the watchdog happy. @@ -1233,7 +1263,9 @@ class FourLineDisplayUsermod : public Usermod { oappend(SET_F("addOption(dd,'SSD1305 128x64',5);")); oappend(SET_F("addOption(dd,'SSD1306 SPI',6);")); oappend(SET_F("addOption(dd,'SSD1306 SPI 128x64',7);")); - bool isSPI = (type == SSD1306_SPI || type == SSD1306_SPI64); + oappend(SET_F("addOption(dd,'SSD1309 SPI 128x64',8);")); + oappend(SET_F("addOption(dd,'SSD1327 SPI 128x128',9);")); + bool isSPI = (type == SSD1306_SPI || type == SSD1306_SPI64 || type > 7); // WLEDMM add defaults oappend(SET_F("addInfo('4LineDisplay:pin[]',0,'','I2C/SPI CLK');")); oappend(SET_F("dRO('4LineDisplay:pin[]',0);")); // disable read only pins @@ -1296,7 +1328,7 @@ class FourLineDisplayUsermod : public Usermod { void addToConfig(JsonObject& root) { // determine if we are using global HW pins (data & clock) int8_t hw_dta, hw_clk; - if ((type == SSD1306_SPI || type == SSD1306_SPI64)) { + if ((type == SSD1306_SPI || type == SSD1306_SPI64) || (type > 7)) { hw_clk = spi_sclk; hw_dta = spi_mosi; } else { @@ -1362,7 +1394,7 @@ class FourLineDisplayUsermod : public Usermod { clockMode = top[FPSTR(_clockMode)] | clockMode; showSeconds = top[FPSTR(_showSeconds)] | showSeconds; contrastFix = top[FPSTR(_contrastFix)] | contrastFix; - if (newType == SSD1306_SPI || newType == SSD1306_SPI64) + if (newType == SSD1306_SPI || newType == SSD1306_SPI64 || newType > 7) ioFrequency = min(20000, max(500, (int)(top[FPSTR(_busClkFrequency)] | ioFrequency/1000))) * 1000; // limit frequency else ioFrequency = min(3400, max(100, (int)(top[FPSTR(_busClkFrequency)] | ioFrequency/1000))) * 1000; // limit frequency @@ -1392,10 +1424,12 @@ class FourLineDisplayUsermod : public Usermod { USER_PRINTLN(F("Display terminated.")); } PinOwner po = PinOwner::UM_FourLineDisplay; - bool isSPI = (type == SSD1306_SPI || type == SSD1306_SPI64); + bool isSPI = (type == SSD1306_SPI || type == SSD1306_SPI64 || type > 7); if (isSPI) { pinManager.deallocateMultiplePins((const uint8_t *)(&oldPin[2]), 3, po); bool isHW = (oldPin[0]==spi_sclk && oldPin[1]==spi_mosi); + if (oldPin[0]==-1 && oldPin[1]==-1) isHW = true; // WLEDMM "use global" means hardware driver + if (spi_sclk==-1 && spi_mosi==-1) isHW = false; // WLEDMM global pins not set -> software driver if (isHW) po = PinOwner::HW_SPI; } else { //bool isHW = (oldPin[0]==i2c_scl && oldPin[1]==i2c_sda); diff --git a/usermods/usermod_v2_games/usermod_v2_games.h b/usermods/usermod_v2_games/usermod_v2_games.h index 0c23ce59..59cb0552 100644 --- a/usermods/usermod_v2_games/usermod_v2_games.h +++ b/usermods/usermod_v2_games/usermod_v2_games.h @@ -319,7 +319,7 @@ uint16_t mode_3DIMUCube(void) { return FRAMETIME; } -static const char _data_FX_MODE_3DIMUCube[] PROGMEM = "🎮 3DIMUCube ☾@,Perspective;!;!;2;pal=1"; //random cycle +static const char _data_FX_MODE_3DIMUCube[] PROGMEM = "🎮 3DIMUCube ☾@,Perspective;!;!;2;pal=1"; //WLEDMM random smooth class GamesUsermod : public Usermod { private: diff --git a/wled00/FX.cpp b/wled00/FX.cpp index f2e3801d..9a66b74b 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -6740,8 +6740,23 @@ uint16_t mode_DJLight(void) { // Written by ??? Adapted by Wil if (SEGENV.aux0 != secondHand) { // Triggered millis timing. SEGENV.aux0 = secondHand; - CRGB color = CRGB(fftResult[15]/2, fftResult[5]/2, fftResult[0]/2); // 16-> 15 as 16 is out of bounds - SEGMENT.setPixelColor(mid, color.fadeToBlackBy(map(fftResult[4], 0, 255, 255, 4))); // TODO - Update + //CRGB color = CRGB(fftResult[15]/2, fftResult[5]/2, fftResult[0]/2); // formula from 0.13.x (10Khz): R = 3880-5120, G=240-340, B=60-100 + //CRGB color = CRGB(fftResult[12]/2, fftResult[3]/2, fftResult[1]/2); // formula for 0.14.x (22Khz): R = 3015-3704, G=216-301, B=86-129 + // an attempt to get colors more balanced + CRGB color = CRGB(fftResult[11]/2 + fftResult[12]/4 + fftResult[14]/4, // red : 2412-3704 + 4479-7106 + fftResult[4]/2 + fftResult[3]/4, // green: 216-430 + fftResult[1]/4 + fftResult[2]/4); // blue: 86-216 + // make colors less "pastel", by turning up color saturation in HSV space + if (color.getLuma() > 32) { // don't change "dark" pixels + CHSV hsvColor = rgb2hsv_approximate(color); + hsvColor.v = min(max(hsvColor.v, (uint8_t)48), (uint8_t)212); // 48 < brightness < 212 + hsvColor.s = max(hsvColor.s, (uint8_t)192); // turn up color saturation (> 192) + color = hsvColor; + } + //if (color.getLuma() > 12) color.maximizeBrightness(); // for testing + + //SEGMENT.setPixelColor(mid, color.fadeToBlackBy(map(fftResult[4], 0, 255, 255, 4))); // 0.13.x fade -> 180hz-260hz + SEGMENT.setPixelColor(mid, color.fadeToBlackBy(map(fftResult[3], 0, 255, 255, 4))); // 0.14.x fade -> 216hz-301hz for (int i = SEGLEN - 1; i > mid; i--) SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i-1)); // move to the left for (int i = 0; i < mid; i++) SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i+1)); // move to the right diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 3227b158..58dd2624 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -238,7 +238,7 @@ CRGBPalette16 &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) { targetPalette = PartyColors_p; break; case 1: {//periodically replace palette with a random one. Transition palette change in 500ms uint32_t timeSinceLastChange = millis() - _lastPaletteChange; - if (timeSinceLastChange > 5000 /*+ ((uint32_t)(255-intensity))*100*/) { + if (timeSinceLastChange > randomPaletteChangeTime * 1000U) { prevRandomPalette = randomPalette; randomPalette = CRGBPalette16( CHSV(random8(), random8(160, 255), random8(128, 255)), @@ -258,7 +258,7 @@ CRGBPalette16 &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) { break;} case 73: {//periodically replace palette with a random one. Transition palette change in 500ms uint32_t timeSinceLastChange = millis() - _lastPaletteChange; - if (timeSinceLastChange > 5000 /*+ ((uint32_t)(255-intensity))*100*/) { + if (timeSinceLastChange > randomPaletteChangeTime * 1000U) { prevRandomPalette = randomPalette; randomPalette = CRGBPalette16( CHSV(random8(), random8(160, 255), random8(128, 255)), @@ -2125,12 +2125,12 @@ WS2812FX* WS2812FX::instance = nullptr; const char JSON_mode_names[] PROGMEM = R"=====(["FX names moved"])====="; //WLEDMM netmindz ar palette add Audio responsive const char JSON_palette_names[] PROGMEM = R"=====([ -"Default","* Random Cycle ☾","* Color 1","* Colors 1&2","* Color Gradient","* Colors Only","Party","Cloud","Lava","Ocean", +"Default","* Random Smooth ☾","* Color 1","* Colors 1&2","* Color Gradient","* Colors Only","Party","Cloud","Lava","Ocean", "Forest","Rainbow","Rainbow Bands","Sunset","Rivendell","Breeze","Red & Blue","Yellowout","Analogous","Splash", "Pastel","Sunset 2","Beach","Vintage","Departure","Landscape","Beech","Sherbet","Hult","Hult 64", "Drywet","Jul","Grintage","Rewhi","Tertiary","Fire","Icefire","Cyane","Light Pink","Autumn", "Magenta","Magred","Yelmag","Yelblu","Orange & Teal","Tiamat","April Night","Orangery","C9","Sakura", "Aurora","Atlantica","C9 2","C9 New","Temperature","Aurora 2","Retro Clown","Candy","Toxy Reaf","Fairy Reaf", "Semi Blue","Pink Candy","Red Reaf","Aqua Flash","Yelblu Hot","Lite Light","Red Flash","Blink Red","Red Shift","Red Tide", -"Candy2","Audio Responsive Ratio ☾","Audio Responsive Hue ☾","* Random Cycle 💡" +"Candy2","Audio Responsive Ratio ☾","Audio Responsive Hue ☾","* Random Cycle" ])====="; diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 6721a5bc..c537f37d 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -367,6 +367,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { int tdd = light_tr["dur"] | -1; if (tdd >= 0) transitionDelay = transitionDelayDefault = tdd * 100; CJSON(strip.paletteFade, light_tr["pal"]); + CJSON(randomPaletteChangeTime, light_tr[F("rpc")]); JsonObject light_nl = light["nl"]; CJSON(nightlightMode, light_nl["mode"]); @@ -491,6 +492,8 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { CJSON(netDebugPrintIP[i], if_ndb_ip[i]); CJSON(netDebugPrintPort, if_ndb["port"]); CJSON(netDebugEnabled, if_ndb["enabled"]); + // USER_PRINTF("deserializeConfig %d\n", netDebugEnabled); + pinManager.manageDebugTXPin(); #endif JsonObject if_ntp = interfaces[F("ntp")]; @@ -853,6 +856,7 @@ void serializeConfig() { light_tr["mode"] = fadeTransition; light_tr["dur"] = transitionDelayDefault / 100; light_tr["pal"] = strip.paletteFade; + light_tr[F("rpc")] = randomPaletteChangeTime; JsonObject light_nl = light.createNestedObject("nl"); light_nl["mode"] = nightlightMode; @@ -965,6 +969,7 @@ void serializeConfig() { } if_ndb["port"] = netDebugPrintPort; if_ndb["enabled"] = netDebugEnabled; + // USER_PRINTF("serializeConfig %d\n", netDebugEnabled); #endif JsonObject if_ntp = interfaces.createNestedObject("ntp"); diff --git a/wled00/const.h b/wled00/const.h index 368dbab2..61552775 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -5,7 +5,7 @@ * Readability defines and their associated numerical values + compile-time constants */ -#define GRADIENT_PALETTE_COUNT 61 //WLEDMM netmindz ar palette +2, ewowi second Random Cycle palette +1 +#define GRADIENT_PALETTE_COUNT 61 //WLEDMM netmindz ar palette +2, ewowi Random Smooth palette +1 //Defaults #define DEFAULT_CLIENT_SSID "Your_Network" diff --git a/wled00/data/index.css b/wled00/data/index.css index b676a7de..d12942b6 100644 --- a/wled00/data/index.css +++ b/wled00/data/index.css @@ -738,10 +738,10 @@ input[type=range]::-moz-range-thumb { margin: 4px 0 0; } -#Colors { +/* #Colors { padding-top: 18px; } - + */ /* Dynamically hide brightness slider label */ .hd { display: var(--bhd); @@ -1517,7 +1517,7 @@ TD .checkmark, TD .radiomark { } } -@media all and (max-width: 1249px) { +@media all and (max-width: 1024px) { #buttonPcm { display: none; } diff --git a/wled00/data/index.htm b/wled00/data/index.htm index 47751fda..624c2875 100644 --- a/wled00/data/index.htm +++ b/wled00/data/index.htm @@ -66,7 +66,7 @@ - + @@ -89,99 +89,102 @@
-
-
-
- -
-
- Hue -
-
-
- -
-
- Saturation -
-
-
- -
-
- Value/Brightness -
-
-
- -
-
- Kelvin/Temperature -
-
- -
+
+
+
+
- + +
+
+ Hue +
+
+
+ +
+
+ Saturation +
+
+
+
- Red channel + Value/Brightness
-
+
- +
- Green channel + Kelvin/Temperature
-
-
- +
+ +
+
+ +
+
+ Red channel +
+
+
+ +
+
+ Green channel +
+
+
+ +
+
+ Blue channel +
+
+
+ +
+
- Blue channel + White channel
-
-
- -
- -
+
+ +
+ +
+
+ White balance
- White channel -
-
- -
- -
+
+
+
+
+
+
+

+
+
+
+
+
R
- White balance -
-
-
-
-
-
-
-

-
-
-
-
-
R
-
-
- - - -
-

-
- - - -
+
+ + + +
+

+
+ + + +
+

Color palette

@@ -204,6 +207,12 @@
+
+ +
+
+
+

Effect mode

@@ -309,19 +318,16 @@
- -
-

Peek ☾

-
-

Segment view ☾

-
-
-
-
+
+
+
+
+

Segments

Loading...
+
diff --git a/wled00/data/index.js b/wled00/data/index.js index 6f2aa646..caab2916 100644 --- a/wled00/data/index.js +++ b/wled00/data/index.js @@ -26,7 +26,7 @@ var ws, cpick, ranges; var cfg = { theme:{base:"dark", bg:{url:""}, alpha:{bg:0.6,tab:0.8}, color:{bg:""}}, comp :{colors:{picker: true, rgb: false, quick: true, hex: false}, - labels:true, pcmbot:false, pid:true, seglen:false, segpwr:false, segexp:true, peekexp:true, segvexp: true, css:true, hdays:false} //WLEDMM segexp true as default, add peekexp and segvexp + labels:true, pcmbot:false, pid:true, seglen:false, segpwr:false, segexp:true, css:true, hdays:false} //WLEDMM segexp true as default }; var hol = [ [0,11,24,4,"https://aircoookie.github.io/xmas.png"], // christmas @@ -557,7 +557,6 @@ function populatePresets(fromls) delete pJson["0"]; var cn = ""; var arr = Object.entries(pJson); - console.log(arr); arr.sort(cmpP); pQL = []; var is = []; @@ -612,7 +611,9 @@ function parseInfo(i) { mw = i.leds.matrix ? i.leds.matrix.w : 0; mh = i.leds.matrix ? i.leds.matrix.h : 0; isM = mw>0 && mh>0; - if (!isM) { + if (isM) { + gId('buttonSr').className = "active"; isLv = true; //WLEDMM: on after load + } else { gId("filter1D").classList.add('hide'); //gId("filter2D").classList.add('hide'); hideModes("2D"); @@ -667,12 +668,16 @@ function populateInfo(i) if (i.cn) vcn = i.cn; //WLEDMM: add total heap and total PSRAM, and build number, add bin name - if (i.ver.includes("0.14.1.")) vcn = "Sitting Ducks"; // easter egg - if (i.ver.includes("0.14.0.")) vcn = "Lupo"; // check for MM versioning scheme + if (i.ver.includes("0.14.1")) vcn = "Sitting Ducks"; // easter egg + if (i.ver.includes("0.14.0")) vcn = "Lupo"; // check for MM versioning scheme + if (i.ver.includes("0.14.0-b2.2")) vcn = "Sitting Ducks"; // early easter egg + if (i.ver.includes("0.14.0-b2.20")) vcn = "Lupo"; cn += `v${i.ver}  "${vcn}"

(WLEDMM_${i.ver} ${i.rel}.bin)

build ${i.vid}

${urows} ${urows===""?'':''} -${i.opt&0x100?inforow("Net Serial ☾",""):''} +${i.opt&0x100?inforow("Net Print ☾",""):''} +${i.serialOnline?inforow(i.serialOnline,"TX="+i.sTX,"; RX="+i.sRX):""} +${i.opt&0x100?'':''} ${inforow("Build",i.vid)} ${inforow("Estimated current",pwru)} ${inforow("Average FPS",i.leds.fps)} @@ -1161,21 +1166,8 @@ function updateLen(s, draw=true) //WLEDMM conditonally draw segment view gId(`seg${s}len`).innerHTML = out; if (draw && isM) drawSegmentView(); //WLEDMM draw new segmentview if something changes in a segment - gId("segviews").style.display = isM? "inline":"none"; -} - -//WLEDMM -function eandp(o,i) -{ - expandV(o,i); - peek(i, i.style.display =="none"); -} - -//WLEDMM -function expandV(o,i) -{ - i.style.display = i.style.display!=="none" ? "none" : ""; - o.style.rotate = i.style.display==="none" ? "-90deg" : "none"; + gId("effectGFX").style.display = isM? "inline":"none"; + gId("segGFX").style.display = isM? "inline":"none"; } //WLEDMM @@ -1214,9 +1206,10 @@ function drawSegmentView() { peek(canvasPeek); } + let segments = gId("Segments"); let windowWidth = Math.min(window.innerWidth*0.98, maxWidth*30); let windowWidthFactor = maxWidth > maxHeight?1:maxWidth/maxHeight; - ctx.canvas.width = (ctx.canvas.parentElement.offsetWidth > 800?windowWidth:300) * windowWidthFactor; //Mobile and non pc mode gets 300, pc 800 + ctx.canvas.width = (segments.offsetWidth > 800?windowWidth:300) * windowWidthFactor; //Mobile and non pc mode gets 300, pc 800 ctx.canvas.height = ctx.canvas.width / maxWidth * maxHeight; canvasPeek.width = ctx.canvas.width; canvasPeek.height = ctx.canvas.height; @@ -1225,10 +1218,6 @@ function drawSegmentView() { var ppL = ctx.canvas.width / maxWidth; //pixels per led // console.log("dim", ctx.canvas.width , maxWidth, ctx.canvas.height , maxHeight, ppL); - ctx.lineWidth = 1; - ctx.strokeStyle="yellow"; - ctx.strokeRect(0, 0, ctx.canvas.width, ctx.canvas.height); - var colorArray = [[255,0,0], [0,255,0], [0,0,255], [255,0,255], [255,165,0], [255,255,0]]; // ["red", "green", "blue", "magenta", "orange", "yellow"]; @@ -1237,9 +1226,11 @@ function drawSegmentView() { if (!initSegmentVars(p)) break; - ctx.lineWidth = 3; - ctx.strokeStyle="white"; - ctx.strokeRect(topLeftX, topLeftY, pw*ppL, ph*ppL); + if (gId("segcont").children.length > 1) { //Estetic: Don't draw surrounding box if only one segment + ctx.lineWidth = 3; + ctx.strokeStyle="white"; + ctx.strokeRect(topLeftX, topLeftY, pw*ppL, ph*ppL); + } var fx = parseInt(gId("seg"+p+"fx").value); @@ -1315,23 +1306,26 @@ function drawSegmentView() { } // for each segment - gId("MD").innerHTML = "W*H=LC: " + maxWidth + " x " + maxHeight + " = " + maxWidth * maxHeight; + if (gId("segcont").children.length > 1) { //Only show this if more then one segment + gId("MD").innerHTML = "total W*H=LC: " + maxWidth + " x " + maxHeight + " = " + maxWidth * maxHeight; + } + gId("MD").style.display = gId("segcont").children.length > 1?"inline":"none" function post() { for (let p=0; p1) { //only show number if more than one segment + if (gId("segcont").children.length>1) { //only show number and name if more than one segment ctx.font = '40px Arial'; ctx.fillStyle = "orange"; ctx.fillText(p, topLeftX + pw/2*ppL - 10, topLeftY + ph/2*ppL + 10); + + //show name of fx + ctx.font = '20px Arial'; + ctx.fillStyle = "white"; + var name = eJson.find((o)=>{return o.id==fx}).name; + ctx.fillText(name, topLeftX+10, topLeftY + ph*ppL - 10); } - - //show name of fx - ctx.font = '20px Arial'; - ctx.fillStyle = "white"; - var name = eJson.find((o)=>{return o.id==fx}).name; - ctx.fillText(name, topLeftX + ppL, topLeftY + ph*ppL - 10); } } @@ -1942,34 +1936,37 @@ function toggleSync() function toggleLiveview() { - //WLEDMM adding liveview2D support - if (isInfo && isM) toggleInfo(); - if (isNodes && isM) toggleNodes(); - isLv = !isLv; + if (isM) { + //WLEDMM adding liveview2D support on main ui + isLv = !isLv; + gId("colorGFX").style.display = isLv? "inline":"none"; + gId("effectGFX").style.display = isLv? "inline":"none"; + gId("segGFX").style.display = isLv? "inline":"none"; - var lvID = "liveview"; - if (isM) { - lvID = "liveview2D" - if (isLv) { - var cn = ''; - d.getElementById('kliveview2D').innerHTML = cn; - } + canvasPeek = gId("canvasPeek"); + if (isLv) peek(canvasPeek); //W + } else { + //WLEDMM remove liveview2D support here + if (isInfo && isM) toggleInfo(); + if (isNodes && isM) toggleNodes(); + isLv = !isLv; - gId('mliveview2D').style.transform = (isLv) ? "translateY(0px)":"translateY(100%)"; + var lvID = "liveview"; + + gId(lvID).style.display = (isLv) ? "block":"none"; + var url = (loc?`http://${locip}`:'') + "/" + lvID; + gId(lvID).src = (isLv) ? url:"about:blank"; + size(); } - gId(lvID).style.display = (isLv) ? "block":"none"; - var url = (loc?`http://${locip}`:'') + "/" + lvID; - gId(lvID).src = (isLv) ? url:"about:blank"; gId('buttonSr').className = (isLv) ? "active":""; - if (!isLv && ws && ws.readyState === WebSocket.OPEN) ws.send('{"lv":false}'); - size(); + if (ws && ws.readyState === WebSocket.OPEN) ws.send(`{"lv":${isLv}}`); } function toggleInfo() { if (isNodes) toggleNodes(); - if (isLv && isM) toggleLiveview(); + // if (isLv && isM) toggleLiveview(); //WLEDMM: not for GFX isInfo = !isInfo; if (isInfo) requestJson(); gId('info').style.transform = (isInfo) ? "translateY(0px)":"translateY(100%)"; @@ -1979,7 +1976,7 @@ function toggleInfo() function toggleNodes() { if (isInfo) toggleInfo(); - if (isLv && isM) toggleLiveview(); + // if (isLv && isM) toggleLiveview(); //WLEDMM: not for GFX isNodes = !isNodes; if (isNodes) loadNodes(); gId('nodes').style.transform = (isNodes) ? "translateY(0px)":"translateY(100%)"; @@ -3228,7 +3225,7 @@ function size() var h = gId('top').clientHeight; sCol('--th', h + "px"); sCol('--bh', gId('bot').clientHeight + "px"); - if (isLv) h -= 4; + if (isLv && !isM) h -= 4; //WLEDMM: no for matrices sCol('--tp', h + "px"); togglePcMode(); } @@ -3240,10 +3237,10 @@ function togglePcMode(fromB = false) localStorage.setItem('pcm', pcModeA); pcMode = pcModeA; } - if (wW < 1250 && !pcMode) return; - if (!fromB && ((wW < 1250 && lastw < 1250) || (wW >= 1250 && lastw >= 1250))) return; + if (wW <= 1024 && !pcMode) return; + if (!fromB && ((wW <= 1024 && lastw <= 1024) || (wW > 1024 && lastw > 1024))) return; openTab(0, true); - if (wW < 1250) {pcMode = false;} + if (wW <= 1024) {pcMode = false;} else if (pcModeA && !fromB) pcMode = pcModeA; updateTablinks(0); gId('buttonPcm').className = (pcMode) ? "active":""; diff --git a/wled00/data/peek.js b/wled00/data/peek.js index 371a9d97..5192cfec 100644 --- a/wled00/data/peek.js +++ b/wled00/data/peek.js @@ -1,4 +1,4 @@ -function peek(c, setOff=false) { +function peek(c) { // Check for canvas support var ctx = c.getContext('2d'); if (ctx) { // Access the rendering context @@ -16,42 +16,35 @@ function peek(c, setOff=false) { } } ws.binaryType = "arraybuffer"; - - function processWSData(e) { + ws.addEventListener('message',(e)=>{ + // function processWSData(e) { try { if (toString.call(e.data) === '[object ArrayBuffer]') { let leds = new Uint8Array(e.data); if (leds[0] != 76 || leds[1] != 2 || !ctx) return; //'L', set in ws.cpp let mW = leds[2]; // matrix width let mH = leds[3]; // matrix height - let pPL = Math.min(c.width / mW, (c.height-10) / mH); // pixels per LED (width of circle) WLEDMM -10 for prompts + let pPL = Math.min(c.width / mW, c.height / mH); // pixels per LED (width of circle) let lOf = Math.floor((c.width - pPL*mW)/2); //left offeset (to center matrix) - var i = 6; + var i = 4; //same offset as in ws.cpp ctx.clearRect(0, 0, c.width, c.height); //WLEDMM function colorAmp(color) { if (color == 0) return 0; return 25+225*color/255; } //WLEDMM in range 55 - 205 for (y=0.5;y
Transition Time: ms
- Enable Palette transitions: + Enable Palette transitions:
+ Random Cycle Palette Time: s

Timed light

Default Duration: min
Default Target brightness:
diff --git a/wled00/data/settings_sync.htm b/wled00/data/settings_sync.htm index 4a73de11..f255a2e2 100644 --- a/wled00/data/settings_sync.htm +++ b/wled00/data/settings_sync.htm @@ -257,9 +257,9 @@ Hue status: Disabled in this build
Keep at 115200 to use Improv. Some boards may not support high rates. -

Net Serial ☾

+

Net Print ☾

- This firmware build does not include Net Serial support.
+ This firmware build does not include Net Print support.
Netcat host IP:
diff --git a/wled00/data/settings_ui.htm b/wled00/data/settings_ui.htm index 42e3f5ea..46509162 100644 --- a/wled00/data/settings_ui.htm +++ b/wled00/data/settings_ui.htm @@ -25,8 +25,6 @@ "seglen": "Set segment length instead of stop LED", "segpwr": "Hide segment power & brightness", "segexp" : "Always expand first segment", - "peekexp" : "Expand peek ☾", - "segvexp" : "Expand segment visualization ☾", "css": "Enable custom CSS", "hdays": "Enable custom Holidays list" }, @@ -267,8 +265,6 @@ :
:
:
- :
- :
I hate dark mode:
:
diff --git a/wled00/data/settings_um.htm b/wled00/data/settings_um.htm index 06e97f22..6f71cea6 100644 --- a/wled00/data/settings_um.htm +++ b/wled00/data/settings_um.htm @@ -120,7 +120,7 @@ // WLEDMM make a dropdown for pin variables if (f.includes("pin")) { var n = this.name.replace("[]","").substr(-3); - urows += ``; //WLEDMM width capped. to be moved to css one day for (var j=-1; j<=50; j++) { // all possible pins WLEDMM: hardcoded to 50 as d.max_gpio is not calculated yet here (done in appendGPIOinfo) let foundPin = -1; for (var i=0; iarg(F("TD")).toInt(); if (t >= 0) transitionDelayDefault = t; strip.paletteFade = request->hasArg(F("PF")); + t = request->arg(F("TP")).toInt(); + randomPaletteChangeTime = MIN(255,MAX(1,t)); nightlightTargetBri = request->arg(F("TB")).toInt(); t = request->arg(F("TL")).toInt(); diff --git a/wled00/util.cpp b/wled00/util.cpp index 66930316..5b93780d 100644 --- a/wled00/util.cpp +++ b/wled00/util.cpp @@ -139,8 +139,8 @@ void sappends(char stype, const char* key, char* val) bool oappendi(int i) { - char s[11]; - sprintf(s, "%d", i); + char s[16]; // WLEDMM max 32bit integer needs 11 chars (sign + 10) not 10 + snprintf(s, 15, "%d", i); // WLEDMM return oappend(s); } diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 7451bdd3..317fecfd 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -201,6 +201,9 @@ void WLED::loop() DEBUG_PRINT(F("Runtime: ")); DEBUG_PRINTLN(millis()); DEBUG_PRINT(F("Unix time: ")); toki.printTime(toki.getTime()); DEBUG_PRINT(F("Free heap: ")); DEBUG_PRINTLN(ESP.getFreeHeap()); + #ifdef ARDUINO_ARCH_ESP32 + DEBUG_PRINTF("%s min free stack %d\n", pcTaskGetTaskName(NULL), uxTaskGetStackHighWaterMark(NULL)); //WLEDMM + #endif #if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_PSRAM) if (psramFound()) { //DEBUG_PRINT(F("Total PSRAM: ")); DEBUG_PRINT(ESP.getPsramSize()/1024); DEBUG_PRINTLN("kB"); @@ -295,17 +298,17 @@ void WLED::setup() #else #endif #if defined(WLED_DEBUG) && defined(ARDUINO_ARCH_ESP32) && (defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || ARDUINO_USB_CDC_ON_BOOT) - delay(2500); // allow CDC USB serial to initialise + if (!Serial) delay(2500); // WLEDMM allow CDC USB serial to initialise #endif #if ARDUINO_USB_CDC_ON_BOOT - delay(2500); // WLEDMM: always allow CDC USB serial to initialise + if (!Serial) delay(2500); // WLEDMM: always allow CDC USB serial to initialise Serial.println("wait 1"); // waiting a bit longer ensures that a debug messages are shown in serial monitor - delay(2500); + if (!Serial) delay(2500); Serial.println("wait 2"); - delay(2500); + if (!Serial) delay(2500); - Serial.flush(); + if (Serial) Serial.flush(); // WLEDMM Serial.setTimeout(350); // WLEDMM: don't change timeout, as it causes crashes later // WLEDMM: redirect debug output to HWCDC Serial0.setDebugOutput(false); @@ -406,6 +409,12 @@ void WLED::setup() DEBUG_PRINTLN(ESP.getCoreVersion()); #endif DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap()); +#ifdef ARDUINO_ARCH_ESP32 + #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0) // unfortunately not availeable in older framework versions + USER_PRINT(F("\nArduino max stack ")); USER_PRINTLN(getArduinoLoopTaskStackSize()); + #endif + DEBUG_PRINTF("%s min free stack %d\n", pcTaskGetTaskName(NULL), uxTaskGetStackHighWaterMark(NULL)); //WLEDMM +#endif #if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_PSRAM) if (psramFound()) { @@ -464,6 +473,9 @@ void WLED::setup() registerUsermods(); DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap()); + #ifdef ARDUINO_ARCH_ESP32 + DEBUG_PRINTF("%s min free stack %d\n", pcTaskGetTaskName(NULL), uxTaskGetStackHighWaterMark(NULL)); //WLEDMM + #endif for (uint8_t i=1; iurl().c_str()); //WLEDMM: want to see if client connects to wled, for netdebug also wants to know server + USER_PRINTLN("Client request"); //WLEDMM: want to see if client connects to wled + #ifdef ARDUINO_ARCH_ESP32 + DEBUG_PRINTF("%s min free stack %d\n", pcTaskGetTaskName(NULL), uxTaskGetStackHighWaterMark(NULL)); //WLEDMM + #endif if (captivePortal(request)) return; serveIndexOrWelcome(request); }); @@ -551,6 +554,13 @@ void serveSettingsJS(AsyncWebServerRequest* request) strcat_P(buf,PSTR("function GetV(){var d=document;")); getSettingsJS(request, subPage, buf+strlen(buf)); // this may overflow by 35bytes!!! WLEDMM add request strcat_P(buf,PSTR("}")); + + #ifdef ARDUINO_ARCH_ESP32 + DEBUG_PRINT(F("ServeSettingsJS: ")); + DEBUG_PRINTF("%s min free stack %d\n", pcTaskGetTaskName(NULL), uxTaskGetStackHighWaterMark(NULL)); //WLEDMM + DEBUG_PRINTF(PSTR(" bytes.\tString buffer usage: %4d of %d bytes\n"), strlen(buf)+1, SETTINGS_STACK_BUF_SIZE+37); + #endif + request->send(200, "application/javascript", buf); } diff --git a/wled00/ws.cpp b/wled00/ws.cpp index 6db459ac..934cd775 100644 --- a/wled00/ws.cpp +++ b/wled00/ws.cpp @@ -117,6 +117,8 @@ void sendDataWs(AsyncWebSocketClient * client) DEBUG_PRINTLN(F("Out of memory (WS)!")); return; } + #else + // DEBUG_PRINTF("%s min free stack %d\n", pcTaskGetTaskName(NULL), uxTaskGetStackHighWaterMark(NULL)); //WLEDMM #endif buffer = ws.makeBuffer(len); // will not allocate correct memory sometimes on ESP8266 #ifdef ESP8266 @@ -163,7 +165,7 @@ bool sendLiveLedsWs(uint32_t wsClient) const size_t MAX_LIVE_LEDS_WS = 1024U; //WLEDMM use 4096 as max matrix size #endif size_t n = ((used -1)/MAX_LIVE_LEDS_WS) +1; //only serve every n'th LED if count over MAX_LIVE_LEDS_WS - size_t pos = (strip.isMatrix ? 6 : 2); // start of data WLEDMM 6 instead of 4 + size_t pos = (strip.isMatrix ? 4 : 2); size_t bufSize = pos + (used/n)*3; size_t skipLines = 0; @@ -177,8 +179,6 @@ bool sendLiveLedsWs(uint32_t wsClient) buffer[1] = 2; //version buffer[2] = Segment::maxWidth; buffer[3] = Segment::maxHeight; - buffer[4] = currentPreset; //WLEDMM - buffer[5] = currentPlaylist; //WLEDMM if (Segment::maxWidth * Segment::maxHeight > MAX_LIVE_LEDS_WS*4) { buffer[2] = Segment::maxWidth/4; buffer[3] = Segment::maxHeight/4; diff --git a/wled00/xml.cpp b/wled00/xml.cpp index 94318dd4..5fe7842a 100644 --- a/wled00/xml.cpp +++ b/wled00/xml.cpp @@ -466,6 +466,7 @@ void getSettingsJS(AsyncWebServerRequest* request, byte subPage, char* dest) //W sappend('c',SET_F("TF"),fadeTransition); sappend('v',SET_F("TD"),transitionDelayDefault); sappend('c',SET_F("PF"),strip.paletteFade); + sappend('v',SET_F("TP"),randomPaletteChangeTime); sappend('v',SET_F("BF"),briMultiplier); sappend('v',SET_F("TB"),nightlightTargetBri); sappend('v',SET_F("TL"),nightlightDelayMinsDefault);