-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Net debug - Runtime Config #5559
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
6e283ee
93b74aa
30d1617
d316625
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -659,6 +659,14 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { | |
| CJSON(hueIP[i], if_hue_ip[i]); | ||
| #endif | ||
|
|
||
| #ifdef WLED_ENABLE_NET_DEBUG | ||
| JsonObject if_ndb = interfaces["ndb"]; | ||
| JsonArray if_ndb_ip = if_ndb["ip"]; | ||
| for (byte i = 0; i < 4; i++) | ||
| CJSON(netDebugPrintIP[i], if_ndb_ip[i]); | ||
| CJSON(netDebugPrintPort, if_ndb["port"]); | ||
| #endif | ||
|
Comment on lines
+662
to
+668
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Validate
💡 Suggested patch `#ifdef` WLED_ENABLE_NET_DEBUG
JsonObject if_ndb = interfaces["ndb"];
JsonArray if_ndb_ip = if_ndb["ip"];
for (byte i = 0; i < 4; i++)
CJSON(netDebugPrintIP[i], if_ndb_ip[i]);
CJSON(netDebugPrintPort, if_ndb["port"]);
+ if (netDebugPrintPort < 0 || netDebugPrintPort > 65535) netDebugPrintPort = 0; // fallback handled during interface init
`#endif`🤖 Prompt for AI Agents |
||
|
|
||
| JsonObject if_ntp = interfaces[F("ntp")]; | ||
| CJSON(ntpEnabled, if_ntp["en"]); | ||
| getStringFromJson(ntpServerName, if_ntp[F("host")], 33); // "1.wled.pool.ntp.org" | ||
|
|
@@ -1191,6 +1199,15 @@ void serializeConfig(JsonObject root) { | |
| } | ||
| #endif | ||
|
|
||
| #ifdef WLED_ENABLE_NET_DEBUG | ||
| JsonObject if_ndb = interfaces.createNestedObject("ndb"); | ||
| JsonArray if_ndb_ip = if_ndb.createNestedArray("ip"); | ||
| for (byte i = 0; i < 4; i++) { | ||
| if_ndb_ip.add(netDebugPrintIP[i]); | ||
| } | ||
| if_ndb["port"] = netDebugPrintPort; | ||
| #endif | ||
|
|
||
| JsonObject if_ntp = interfaces.createNestedObject("ntp"); | ||
| if_ntp["en"] = ntpEnabled; | ||
| if_ntp[F("host")] = ntpServerName; | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -284,6 +284,19 @@ <h3>Serial</h3> | |||||
| </select><br> | ||||||
| <i>Keep at 115200 to use Improv. Some boards may not support high rates.</i> | ||||||
| </div> | ||||||
| <div class="sec"> | ||||||
| <h3>Net Debug ☾</h3> | ||||||
| <div id="NoNetDebug" class="hide"> | ||||||
| <em style="color:#fa0;">This firmware build does not include Net Debug support.<br></em> | ||||||
| </div> | ||||||
| <div id="NetDebug"> | ||||||
| Netcat host IP:<br> | ||||||
| <input name="N0" type="number" class="s" min="0" max="255" > . | ||||||
| <input name="N1" type="number" class="s" min="0" max="255" > . | ||||||
| <input name="N2" type="number" class="s" min="0" max="255" > . | ||||||
| <input name="N3" type="number" class="s" min="0" max="255" ><br> | ||||||
| Netcat host Port:<br> | ||||||
| <input name="NP" type="number" min="0" max="99999" ><br> | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Constrain Net Debug port to valid UDP range in the form. Line 299 allows 🐛 Suggested fix-<input name="NP" type="number" min="0" max="99999" ><br>
+<input name="NP" type="number" min="1" max="65535" ><br>📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
| </div> | ||||||
| <hr> | ||||||
| <button type="button" onclick="B()">Back</button><button type="submit">Save</button> | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -368,7 +368,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId) | |
| { | ||
| bool stateResponse = root[F("v")] | false; | ||
|
|
||
| #if defined(WLED_DEBUG) && defined(WLED_DEBUG_HOST) | ||
| #if defined(WLED_DEBUG) && defined(WLED_ENABLE_NET_DEBUG) | ||
| netDebugEnabled = root[F("debug")] | netDebugEnabled; | ||
| #endif | ||
|
Comment on lines
+371
to
373
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The runtime flag is still guarded by Suggested fix- `#if` defined(WLED_DEBUG) && defined(WLED_ENABLE_NET_DEBUG)
+ `#ifdef` WLED_ENABLE_NET_DEBUG
netDebugEnabled = root[F("debug")] | netDebugEnabled;
`#endif`🤖 Prompt for AI Agents |
||
|
|
||
|
|
@@ -866,7 +866,7 @@ void serializeInfo(JsonObject root) | |
| uint16_t os = 0; | ||
| #ifdef WLED_DEBUG | ||
| os = 0x80; | ||
| #ifdef WLED_DEBUG_HOST | ||
| #ifdef WLED_ENABLE_NET_DEBUG | ||
| os |= 0x0100; | ||
| if (!netDebugEnabled) os &= ~0x0080; | ||
| #endif | ||
|
Comment on lines
867
to
872
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Net-debug status bits are still hidden behind the outer Because this block only runs inside Suggested fix uint16_t os = 0;
`#ifdef` WLED_DEBUG
- os = 0x80;
- `#ifdef` WLED_ENABLE_NET_DEBUG
- os |= 0x0100;
- if (!netDebugEnabled) os &= ~0x0080;
- `#endif`
+ os |= 0x0080;
`#endif`
+ `#ifdef` WLED_ENABLE_NET_DEBUG
+ os |= 0x0100;
+ if (netDebugEnabled) os |= 0x0080;
+ `#endif`🤖 Prompt for AI Agents |
||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @coderabbitai please analyze the net debug core code for possible stability issues, buffer overruns and potential for heap fragmentation. Suggest improvements / re-design options that would improve stability.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: Length of output: 6723
Net Debug Stability Analysis🔴 Issue 1 — Per-character UDP packets (Critical heap fragmentation)This is the most severe problem. debugUdp.beginPacket(netDebugPrintIP, netDebugPrintPort); // heap alloc
debugUdp.write(c); // 1 byte payload
debugUdp.endPacket(); // heap free + syscall
Fix — add a line-oriented ring buffer: // net_debug.h — add to private section:
static constexpr size_t TX_BUF_SIZE = 512;
uint8_t _txBuf[TX_BUF_SIZE];
size_t _txLen = 0;
// net_debug.cpp — replace both write() overrides:
size_t NetworkDebugPrinter::write(uint8_t c) {
if (!WLED_CONNECTED || !netDebugEnabled) return 0;
if (_txLen < TX_BUF_SIZE) _txBuf[_txLen++] = c;
if (c == '\n' || _txLen == TX_BUF_SIZE) flush();
return 1;
}
size_t NetworkDebugPrinter::write(const uint8_t *buf, size_t size) {
if (!WLED_CONNECTED || buf == nullptr || size == 0 || !netDebugEnabled) return 0;
size_t written = 0;
while (written < size) {
size_t chunk = min(size - written, TX_BUF_SIZE - _txLen);
memcpy(_txBuf + _txLen, buf + written, chunk);
_txLen += chunk;
written += chunk;
if (_txLen == TX_BUF_SIZE || _txBuf[_txLen - 1] == '\n') flush();
}
return written;
}
void NetworkDebugPrinter::flush() {
if (_txLen == 0 || !WLED_CONNECTED || !netDebugEnabled) return;
if (debugUdp.beginPacket(netDebugPrintIP, netDebugPrintPort)) {
debugUdp.write(_txBuf, _txLen);
debugUdp.endPacket();
}
_txLen = 0;
}This reduces packet count from N-per-string to 1-per-line while keeping 🔴 Issue 2 — No IP / Port validation before
|
| Issue | Severity | Impact |
|---|---|---|
| Per-character UDP packets | 🔴 Critical | Heavy heap fragmentation, network spam |
| No IP/port validation | 🔴 Critical | Potential lwIP assert / socket corruption |
| No thread-safety (mutex) | 🟠 Moderate | Data corruption under concurrent tasks |
| Bare ternary DEBUGOUT macros | 🟠 Moderate | Parse hazard in edge call sites |
| USER_FLUSH() no-op | 🟡 Low | Partial lines silently dropped |
| No UDP size cap | 🟡 Low | Silent truncation for large buffers |
int instead of uint16_t for port |
🟡 Low | Semantic / type safety |
The single highest-impact change is Issue 1 (ring buffer with newline-triggered flush) — it addresses heap fragmentation, packet count, and indirectly the size-cap issue in one pass.
🧠 Learnings used
Learnt from: softhack007
Repo: wled/WLED PR: 5355
File: wled00/util.cpp:635-638
Timestamp: 2026-02-07T16:06:08.677Z
Learning: PSRAM-related compilation guards should enable PSRAM code only for ESP32 variants that actually include PSRAM: ESP32-C61, ESP32-C5, and ESP32-P4. Exclude ESP32-C3, ESP32-C6, and ESP8266 from these guards. Apply this rule across the codebase (not just wled00/util.cpp) by reviewing and updating PSRAM guards/macros in all relevant files (C/C++ headers and sources).
Learnt from: softhack007
Repo: wled/WLED PR: 4893
File: wled00/set.cpp:95-95
Timestamp: 2026-03-14T20:56:46.543Z
Learning: Guideline: Ensure WiFi hostname is set after WiFi.mode() but before WiFi.begin() to avoid default esp-XXXXXX hostname being used in DHCP. This ordering only takes effect after the STA interface exists (so avoid placing hostname setting before initConnection). In WLED, place the hostname configuration inside initConnection() (after WiFi.disconnect(true) and before WiFi.begin()) rather than in earlier boot code like deserializeConfig(). This rule should be applied in code reviews for WLED’s network initialization paths in wled00/*.cpp, and note that on ESP8266 the ordering is less strict but still desirable for consistency.
Learnt from: softhack007
Repo: wled/WLED PR: 4838
File: lib/NeoESP32RmtHI/src/NeoEsp32RmtHIMethod.cpp:30-35
Timestamp: 2026-03-27T12:33:48.499Z
Learning: In C/C++ preprocessor conditionals (`#if`, `#elif`) GCC/Clang treat `&&` as short-circuit evaluated during preprocessing. This means guards like `#if defined(ARDUINO_ARCH_ESP32) && ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)` are safe even if the macro/function-like macro on the RHS (e.g., `ESP_IDF_VERSION_VAL`) is not defined on some targets, because the RHS will not be expanded when the LHS is false (e.g., `defined(...)` evaluates to 0). During code review, avoid flagging such cases as “undefined function-like macro invocation” if they are protected by short-circuiting `defined(...) && ...`/`||` logic; some tools like cppcheck may not model this and can produce false positives. Also, don’t suggest refactoring that moves ESP32-specific includes/headers (e.g., `esp_idf_version.h`) outside of these guarded preprocessor blocks, since that will break targets (e.g., ESP8266) where the headers don’t exist.
Learnt from: softhack007
Repo: wled/WLED PR: 5048
File: wled00/cfg.cpp:673-673
Timestamp: 2026-03-27T21:17:45.980Z
Learning: When calling raw lwIP APIs (e.g., around `ntpUdp.begin()` or any `lwIP`/`tcpip`-layer call) in this codebase on ESP32 Arduino-ESP32 platforms where core locking/checking is enabled, wrap the lwIP call with `LOCK_TCPIP_CORE()` / `UNLOCK_TCPIP_CORE()` from `lwip/tcpip.h`. This prevents thread-safety/core-violation crashes without requiring `sdkconfig` changes.
Learnt from: softhack007
Repo: wled/WLED PR: 5048
File: wled00/cfg.cpp:673-673
Timestamp: 2026-03-27T21:17:45.980Z
Learning: When using lwIP “raw” APIs in WLED on ESP32 (Arduino-ESP32 / IDF 5.5+), don’t rely on LOCK_TCPIP_CORE()/UNLOCK_TCPIP_CORE() unless CONFIG_LWIP_TCPIP_CORE_LOCKING=y is guaranteed. CONFIG_LWIP_CHECK_THREAD_SAFETY=y can trigger the assertion “Required to lock TCPIP core functionality!” when raw lwIP calls occur off the TCPIP thread. If the locking mode isn’t enabled (or can’t be changed via sdkconfig), schedule lwIP work (e.g., ntpUdp.begin() and similar raw lwIP calls) via tcpip_callback() so it runs on the TCPIP thread; this should work regardless of the locking-mode setting. Review any similar raw lwIP usage for correct thread/context handling.
Learnt from: softhack007
Repo: wled/WLED PR: 5048
File: wled00/wled.cpp:698-700
Timestamp: 2026-03-28T01:37:15.541Z
Learning: In this WLED codebase, when using `DEBUG_PRINTLN(F("..."))`, an explicit trailing `\n` inside the `F("...")` string (e.g., `DEBUG_PRINTLN(F("Warning!\n"))`) may be intentional to create a blank line in debug output as a visual separator. During code review, do not automatically flag these as “double newline” or recommend removing the `\n`—first verify with the author/context that the extra newline is deliberate.
Learnt from: willmmiles
Repo: wled/WLED PR: 5462
File: wled00/json.cpp:1189-1198
Timestamp: 2026-03-30T15:32:02.808Z
Learning: When working with WLED strings stored in PROGMEM on ESP8266/ESP32, assume you can’t use `strchr_P` for character scanning. If you need to scan a PROGMEM string for a character (e.g., searching for '@' within effect data), review changes to ensure they perform an explicit RAM copy first (e.g., via `strncpy_P` into a buffer) and then scan in RAM. Avoid proposing incremental/streaming PROGMEM character-by-character scans without a RAM buffer on these targets, since it’s impractical with the available APIs.
Learnt from: DedeHai
Repo: wled/WLED PR: 5464
File: wled00/FX_fcn.cpp:1699-1701
Timestamp: 2026-04-09T07:26:09.816Z
Learning: In WLED’s WLED code, if a pixel/buffer allocation uses `BFRALLOC_NOBYTEACCESS` (and especially on classic ESP32 where byte-level access to IRAM-resident buffers is unsafe), avoid using byte-wise operations like `memset`/`memcpy` on that buffer. Specifically, do not combine `BFRALLOC_CLEAR | BFRALLOC_NOBYTEACCESS` and do not perform `memcpy`/`memset` over `Segment::pixels` (e.g., in `setGeometry()`/`finalizeInit()` or copy ctor/assignment). Instead, use element-wise 32-bit access (loop over `uint32_t*` and assign/copy per element) to ensure 32-bit access only.
Learnt from: DedeHai
Repo: wled/WLED PR: 5464
File: wled00/FX_fcn.cpp:1699-1701
Timestamp: 2026-04-09T09:14:29.218Z
Learning: In WLED, when reviewing ESP32 code that uses pixel buffers allocated with `BFRALLOC_NOBYTEACCESS` (e.g., `WS2812FX::_pixels` and `Segment::pixels`), treat `memset`/`memcpy` on those buffers as an intentionally low-risk, accepted pattern. These buffers are designed to be IRAM-safe for 32-bit-only access, and the Xtensa newlib assembly implementations perform 32-bit word stores for word-aligned, word-multiple-sized buffers (so the IRAM constraint is satisfied in practice). Do not flag `memset`/`memcpy` on `BFRALLOC_NOBYTEACCESS` pixel buffers as a critical bug; if any concern arises, downgrade severity to low and focus on potential future regressions rather than an immediate correctness violation.
Learnt from: softhack007
Repo: wled/WLED PR: 5508
File: wled00/FX.cpp:4137-4142
Timestamp: 2026-04-16T09:49:58.587Z
Learning: In WLED effect/overlay implementations (C++ under wled00), ensure effects operate through the SEGMENT.* read/write APIs for their own pixels/overlay state. Reserve global frame reads/writes like strip.getPixelColor* for copy_* style post-processing only. Do not manually composite/blend across lower layers inside the effect; segment-to-segment blending is handled later by WS2812FX::blendSegment(), so effects should produce their per-segment contributions without trying to composite with underlying layers themselves.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,23 +1,11 @@ | ||
| #include "wled.h" | ||
|
|
||
| #ifdef WLED_DEBUG_HOST | ||
| #ifdef WLED_ENABLE_NET_DEBUG | ||
|
|
||
| size_t NetworkDebugPrinter::write(uint8_t c) { | ||
| if (!WLED_CONNECTED || !netDebugEnabled) return 0; | ||
|
|
||
| if (!debugPrintHostIP && !debugPrintHostIP.fromString(netDebugPrintHost)) { | ||
| #ifdef ESP8266 | ||
| WiFi.hostByName(netDebugPrintHost, debugPrintHostIP, 750); | ||
| #else | ||
| #ifdef WLED_USE_ETHERNET | ||
| ETH.hostByName(netDebugPrintHost, debugPrintHostIP); | ||
| #else | ||
| WiFi.hostByName(netDebugPrintHost, debugPrintHostIP); | ||
| #endif | ||
| #endif | ||
| } | ||
|
|
||
| debugUdp.beginPacket(debugPrintHostIP, netDebugPrintPort); | ||
| debugUdp.beginPacket(netDebugPrintIP, netDebugPrintPort); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe it's also a good time to scrutinise the net debug UDP core code - I found it quite unreliable in the past, even when only dumping packets via netcat. Maybe we should directly move to a standard logging protocol? Afaik the main difference is in establishing the connection, after that its basicially a printf with some meta data added. Netdebug was an overnight hack by a contributor, it was never tested under "real load". |
||
| debugUdp.write(c); | ||
| debugUdp.endPacket(); | ||
| return 1; | ||
|
|
@@ -26,19 +14,7 @@ size_t NetworkDebugPrinter::write(uint8_t c) { | |
| size_t NetworkDebugPrinter::write(const uint8_t *buf, size_t size) { | ||
| if (!WLED_CONNECTED || buf == nullptr || !netDebugEnabled) return 0; | ||
|
|
||
| if (!debugPrintHostIP && !debugPrintHostIP.fromString(netDebugPrintHost)) { | ||
| #ifdef ESP8266 | ||
| WiFi.hostByName(netDebugPrintHost, debugPrintHostIP, 750); | ||
| #else | ||
| #ifdef WLED_USE_ETHERNET | ||
| ETH.hostByName(netDebugPrintHost, debugPrintHostIP); | ||
| #else | ||
| WiFi.hostByName(netDebugPrintHost, debugPrintHostIP); | ||
| #endif | ||
| #endif | ||
| } | ||
|
|
||
| debugUdp.beginPacket(debugPrintHostIP, netDebugPrintPort); | ||
| debugUdp.beginPacket(netDebugPrintIP, netDebugPrintPort); | ||
| size = debugUdp.write(buf, size); | ||
| debugUdp.endPacket(); | ||
| return size; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -523,6 +523,14 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) | |
| reconnectHue(); | ||
| #endif | ||
|
|
||
| #ifdef WLED_ENABLE_NET_DEBUG | ||
| for (int i=0;i<4;i++){ | ||
| String a = "N"+String(i); | ||
| netDebugPrintIP[i] = request->arg(a).toInt(); | ||
| } | ||
| netDebugPrintPort = request->arg("NP").toInt(); | ||
| #endif | ||
|
Comment on lines
+526
to
+532
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Guard and validate Net Debug fields before applying them. Line 529 and Line 531 currently overwrite values even when args are absent/invalid, which can silently reset settings to 🐛 Suggested hardening `#ifdef` WLED_ENABLE_NET_DEBUG
- for (int i=0;i<4;i++){
- String a = "N"+String(i);
- netDebugPrintIP[i] = request->arg(a).toInt();
- }
- netDebugPrintPort = request->arg("NP").toInt();
+ for (int i = 0; i < 4; i++) {
+ String a = "N" + String(i);
+ if (request->hasArg(a)) {
+ netDebugPrintIP[i] = (uint8_t)constrain(request->arg(a).toInt(), 0, 255);
+ }
+ }
+ if (request->hasArg(F("NP"))) {
+ int np = request->arg(F("NP")).toInt();
+ if (np > 0 && np <= 65535) netDebugPrintPort = np;
+ }
`#endif`🤖 Prompt for AI Agents |
||
|
|
||
| t = request->arg(F("BD")).toInt(); | ||
| if (t >= 96 && t <= 15000) serialBaud = t; | ||
| updateBaudRate(serialBaud *100); | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -384,7 +384,7 @@ void WLED::setup() | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #if !defined(WLED_DEBUG) && defined(ARDUINO_ARCH_ESP32) && !defined(WLED_DEBUG_HOST) && ARDUINO_USB_CDC_ON_BOOT | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #if !defined(WLED_DEBUG) && defined(ARDUINO_ARCH_ESP32) && !defined(WLED_ENABLE_NET_DEBUG) && ARDUINO_USB_CDC_ON_BOOT | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Serial.setDebugOutput(false); // switch off kernel messages when using USBCDC | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DEBUG_PRINTLN(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -442,7 +442,7 @@ void WLED::setup() | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| usePWMFixedNMI(); // link the NMI fix | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #if defined(WLED_DEBUG) && !defined(WLED_DEBUG_HOST) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #if defined(WLED_DEBUG) && !defined(WLED_ENABLE_NET_DEBUG) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| PinManager::allocatePin(hardwareTX, true, PinOwner::DebugOut); // TX (GPIO1 on ESP32) reserved for debug output | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #ifdef WLED_ENABLE_DMX //reserve GPIO2 as hardcoded DMX pin | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -827,6 +827,33 @@ void WLED::initInterfaces() | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #ifdef WLED_ENABLE_NET_DEBUG | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (netDebugPrintIP[0] == 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!netDebugPrintIP && !netDebugPrintIP.fromString(WLED_DEBUG_HOST)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #ifdef ESP8266 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| WiFi.hostByName(WLED_DEBUG_HOST, netDebugPrintIP, 750); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #ifdef WLED_USE_ETHERNET | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ETH.hostByName(WLED_DEBUG_HOST, netDebugPrintIP); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| WiFi.hostByName(WLED_DEBUG_HOST, netDebugPrintIP); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| IPAddress ipAddress = Network.localIP(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| netDebugPrintIP[0] = ipAddress[0]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| netDebugPrintIP[1] = ipAddress[1]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| netDebugPrintIP[2] = ipAddress[2]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (netDebugPrintPort == 0) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #ifdef WLED_DEBUG_PORT | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| netDebugPrintPort = WLED_DEBUG_PORT; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| netDebugPrintPort = 7868; //Default value | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+830
to
+855
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== WLED_DEBUG_HOST define presence =="
rg -n --type=cpp --type=h '^\s*#\s*define\s+WLED_DEBUG_HOST\b|^\s*#\s*ifndef\s+WLED_DEBUG_HOST\b'
echo
echo "== netDebug init block =="
rg -n -C4 'netDebugPrintIP|WLED_DEBUG_HOST|netDebugPrintPort' wled00/wled.cpp
echo
echo "== netDebugPrintIP octet assignments in wled.cpp =="
rg -n 'netDebugPrintIP\[[0-3]\]\s*=' wled00/wled.cppRepository: wled/WLED Length of output: 91 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "=== Lines 830-855 in wled00/wled.cpp ==="
sed -n '830,855p' wled00/wled.cpp
echo
echo "=== Context around netDebugPrintIP declaration ==="
rg -n 'netDebugPrintIP' wled00/wled.cpp | head -20
echo
echo "=== IPAddress class definition ==="
fd -t f '\.h$' -x grep -l 'class IPAddress' {} \;
echo
echo "=== Check if WLED_DEBUG_HOST is defined anywhere in project ==="
rg -r '\.{1,2}' --type=cpp --type=h 'define.*WLED_DEBUG_HOST|WLED_DEBUG_HOST\s*=' . 2>/dev/null || trueRepository: wled/WLED Length of output: 1432 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "=== Search for WLED_DEBUG or DEBUG_HOST in config files ==="
find . -type f \( -name "*.h" -o -name "*.cpp" -o -name "*.json" -o -name "*.md" \) -exec grep -l "DEBUG_HOST\|DEBUG_PORT" {} \; 2>/dev/null || true
echo
echo "=== Check wled.h for netDebugPrintIP declaration ==="
grep -n 'netDebugPrintIP\|IPAddress' wled00/wled.h | head -20
echo
echo "=== Look for IPAddress usage with bracket notation ==="
rg -n 'IPAddress.*\[[0-3]\]' wled00/ | head -10
echo
echo "=== Check default values or config setup ==="
rg -n 'WLED_DEBUG_HOST|netDebugPrintIP' wled00/set.cpp | head -20Repository: wled/WLED Length of output: 825 Net-debug init has compile-time dependency, inverted logic, and incomplete IP assignment bugs. Line 832 references Suggested fix `#ifdef` WLED_ENABLE_NET_DEBUG
- if (netDebugPrintIP[0] == 0) {
- if (!netDebugPrintIP && !netDebugPrintIP.fromString(WLED_DEBUG_HOST)) {
+ bool netDebugIpUnset = (netDebugPrintIP[0] == 0 && netDebugPrintIP[1] == 0 && netDebugPrintIP[2] == 0 && netDebugPrintIP[3] == 0);
+ if (netDebugIpUnset) {
+ `#ifdef` WLED_DEBUG_HOST
+ if (!netDebugPrintIP.fromString(WLED_DEBUG_HOST)) {
`#ifdef` ESP8266
WiFi.hostByName(WLED_DEBUG_HOST, netDebugPrintIP, 750);
`#else`
`#ifdef` WLED_USE_ETHERNET
ETH.hostByName(WLED_DEBUG_HOST, netDebugPrintIP);
`#else`
WiFi.hostByName(WLED_DEBUG_HOST, netDebugPrintIP);
`#endif`
`#endif`
- } else {
- IPAddress ipAddress = Network.localIP();
- netDebugPrintIP[0] = ipAddress[0];
- netDebugPrintIP[1] = ipAddress[1];
- netDebugPrintIP[2] = ipAddress[2];
}
+ `#else`
+ IPAddress ipAddress = Network.localIP();
+ netDebugPrintIP[0] = ipAddress[0];
+ netDebugPrintIP[1] = ipAddress[1];
+ netDebugPrintIP[2] = ipAddress[2];
+ netDebugPrintIP[3] = ipAddress[3];
+ `#endif`
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #ifndef WLED_DISABLE_ALEXA | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // init Alexa hue emulation | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (alexaEnabled) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -974,41 +974,71 @@ WLED_GLOBAL JsonDocument *pDoc _INIT(&gDoc); | |
| #endif | ||
| WLED_GLOBAL volatile uint8_t jsonBufferLock _INIT(0); | ||
|
|
||
| // enable net debug output over UDP; use -D WLED_ENABLE_NET_DEBUG to activate. | ||
| // Legacy: defining WLED_DEBUG_HOST='"ip_or_host"' also enables net debug and | ||
| // pre-seeds the target IP at compile time. | ||
| #if defined(WLED_DEBUG_HOST) && !defined(WLED_ENABLE_NET_DEBUG) | ||
| #define WLED_ENABLE_NET_DEBUG | ||
| #endif | ||
|
|
||
| // enable additional debug output | ||
| #if defined(WLED_DEBUG_HOST) | ||
| #if defined(WLED_ENABLE_NET_DEBUG) | ||
| #include "net_debug.h" | ||
| // On the host side, use netcat to receive the log statements: nc -l 7868 -u | ||
| // use -D WLED_DEBUG_HOST='"192.168.xxx.xxx"' or FQDN within quotes | ||
| #define DEBUGOUT NetDebug | ||
| WLED_GLOBAL bool netDebugEnabled _INIT(true); | ||
| WLED_GLOBAL char netDebugPrintHost[33] _INIT(WLED_DEBUG_HOST); | ||
| #ifndef WLED_DEBUG_PORT | ||
| #define WLED_DEBUG_PORT 7868 | ||
| #endif | ||
| WLED_GLOBAL int netDebugPrintPort _INIT(WLED_DEBUG_PORT); | ||
| WLED_GLOBAL bool netDebugEnabled _INIT(false); | ||
| WLED_GLOBAL int netDebugPrintPort _INIT(0); | ||
| WLED_GLOBAL IPAddress netDebugPrintIP _INIT_N(((0, 0, 0, 0))); // IP address of the bridge | ||
| #define DEBUGOUT(x) netDebugEnabled?NetDebug.print(x):Serial.print(x) | ||
| #define DEBUGOUTLN(x) netDebugEnabled?NetDebug.println(x):Serial.println(x) | ||
| #define DEBUGOUTF(x...) netDebugEnabled?NetDebug.printf(x):Serial.printf(x) | ||
| #define DEBUGOUTFlush() netDebugEnabled?NetDebug.flush():Serial.flush() | ||
| #else | ||
| #define DEBUGOUT Serial | ||
| #define DEBUGOUT(x) Serial.print(x) | ||
| #define DEBUGOUTLN(x) Serial.println(x) | ||
| #define DEBUGOUTF(x...) Serial.printf(x) | ||
| #define DEBUGOUTFlush() Serial.flush() | ||
|
Comment on lines
+991
to
+999
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== Object-style DEBUGOUT member calls (incompatible with function-like DEBUGOUT) =="
rg -nP --type=cpp --type=h '\bDEBUGOUT\s*\.\s*(print|println|printf|flush)\s*\('
echo
echo "== Bare DEBUGOUT identifier usages in affected areas =="
rg -nP '\bDEBUGOUT\b(?!\s*\()' wled00/wled.cpp usermods/audioreactive/audio_reactive.cppRepository: wled/WLED Length of output: 1346 🏁 Script executed: #!/bin/bash
set -euo pipefail
# Check the exact content of wled.h around lines 990-998
echo "=== wled.h lines 980-1010 ==="
sed -n '980,1010p' wled00/wled.h | cat -n
echo
echo "=== Check if there are any wrapper functions for stream compatibility ==="
rg -nA5 'debugOutStream|DEBUGOUT_STREAM|Print.*DEBUGOUT' wled00/wled.h
echo
echo "=== Verify the exact definitions of DEBUGOUT-related macros ==="
rg -nP '^\s*#define\s+(DEBUGOUT|DEBUGSR_|PLOT_)' wled00/wled.h usermods/audioreactive/audio_reactive.cpp | head -20Repository: wled/WLED Length of output: 1519
Making Consider using a wrapper function that returns a reference to the appropriate stream, allowing both function-call and stream-object usage patterns: `#if` defined(WLED_ENABLE_NET_DEBUG)
inline Print& debugOutStream() { return netDebugEnabled ? static_cast<Print&>(NetDebug) : static_cast<Print&>(Serial); }
`#else`
inline Print& debugOutStream() { return static_cast<Print&>(Serial); }
`#endif`
`#define` DEBUGOUT_STREAM() debugOutStream()
`#define` DEBUGOUT(x) DEBUGOUT_STREAM().print(x)
`#define` DEBUGOUTLN(x) DEBUGOUT_STREAM().println(x)
`#define` DEBUGOUTF(x...) DEBUGOUT_STREAM().printf(x)
`#define` DEBUGOUTFlush() DEBUGOUT_STREAM().flush()Then migrate stream-argument call sites (e.g., 🤖 Prompt for AI Agents
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. DEBUGSR_ macros in audioreactive UM should be adjusted. It's not necessary to have a legacy support helper only for this usermod.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: Length of output: 363
// usermods/audioreactive/audio_reactive.cpp, lines 55-57
`#define` DEBUGSR_PRINT(x) DEBUGOUT(x)
`#define` DEBUGSR_PRINTLN(x) DEBUGOUTLN(x)
`#define` DEBUGSR_PRINTF(x...) DEBUGOUTF(x)One separate issue remains in server.printStatus(DEBUGOUT); // DEBUGOUT is no longer a stream object
✏️ Learnings added
🧠 Learnings used |
||
| #endif | ||
|
|
||
| #ifdef WLED_DEBUG | ||
| #ifndef ESP8266 | ||
| #include <rom/rtc.h> | ||
| #endif | ||
| #define DEBUG_PRINT(x) DEBUGOUT.print(x) | ||
| #define DEBUG_PRINTLN(x) DEBUGOUT.println(x) | ||
| #define DEBUG_PRINTF(x...) DEBUGOUT.printf(x) | ||
| #define DEBUG_PRINTF_P(x...) DEBUGOUT.printf_P(x) | ||
| #define DEBUG_PRINT(x) DEBUGOUT(x) | ||
| #define DEBUG_PRINTLN(x) DEBUGOUTLN(x) | ||
| #define DEBUG_PRINTF(x...) DEBUGOUTF(x) | ||
| #define DEBUG_PRINTF_P(x...) DEBUGOUTF(x) | ||
| #else | ||
| #define DEBUG_PRINT(x) | ||
| #define DEBUG_PRINTLN(x) | ||
| #define DEBUG_PRINTF(x...) | ||
| #define DEBUG_PRINTF_P(x...) | ||
| #endif | ||
|
|
||
| // macros to print "user messages" to Serial | ||
| // cannot do this on -S2, due to buggy USBCDC serial driver | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @netmindz ah, you already have a provision for USER_PRINT 👍 did not see this when writing my first comment. The all you'd need is to also import
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @coderabbitai please verify if the restriction for -S2 (buggy USBCDC) is still needed. For comparison, there is a workaround in WLED-MM but it has the side-effect that sometimes serial output could get lost
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainLet me look at the referenced WLED-MM code and check the current state of the S2 USBCDC bug. 🏁 Script executed: Length of output: 86561 🏁 Script executed: Length of output: 37006 🏁 Script executed: Length of output: 37075 🌐 Web query: 💡 Result: As of 2025, the main “Arduino
If what you’re seeing in 2025 is “no serial output / can’t open COM port”, that’s often configuration/host-side, not the old core bug—e.g. needing Tools → “USB CDC On Boot” enabled and the right USB mode/flash settings. (docs.espressif.com) Citations:
Let me look at the 🏁 Script executed: Length of output: 4309 🏁 Script executed: Length of output: 2178 🏁 Script executed: Length of output: 1237 🏁 Script executed: Length of output: 359
1. The S2 USBCDC restriction is still relevantThe S2 CDC-over-USB crash is still being actively worked around in the current codebase — in `#if` defined(CONFIG_IDF_TARGET_ESP32S2)
delay(1); // on S2 the CDC output can crash without a delay
`#endif`The WLED-MM workaround applies // WLED-MM: only for S3/C3/C6/P4, NOT S2:
`#if` ARDUINO_USB_CDC_ON_BOOT && (defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3) || ...)
Serial.setTxTimeoutMs(0); // potential side-effect: incomplete debug outputSome specific arduino-esp32 bugs have been fixed — the RX buffer bug was resolved in PR 2. Critical issue:
|
||
| #if defined(WLED_DEBUG) || defined(WLED_ENABLE_NET_DEBUG) | ||
| // use DEBUG_PRINT | ||
| #define USER_PRINT(x) DEBUG_PRINT(x) | ||
| #define USER_PRINTLN(x) DEBUG_PRINTLN(x) | ||
| #define USER_PRINTF(x...) DEBUG_PRINTF(x) | ||
| #ifdef WLED_ENABLE_NET_DEBUG | ||
| #define USER_FLUSH() {} | ||
| #else | ||
| #define USER_FLUSH() {DEBUGOUTFlush();} | ||
| #endif | ||
|
Comment on lines
+1019
to
+1028
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This branch is selected when Suggested fix-#if defined(WLED_DEBUG) || defined(WLED_ENABLE_NET_DEBUG)
- // use DEBUG_PRINT
+#if defined(WLED_DEBUG)
+ // use DEBUG_PRINT
`#define` USER_PRINT(x) DEBUG_PRINT(x)
`#define` USER_PRINTLN(x) DEBUG_PRINTLN(x)
`#define` USER_PRINTF(x...) DEBUG_PRINTF(x)
+ `#ifdef` WLED_ENABLE_NET_DEBUG
+ `#define` USER_FLUSH() {}
+ `#else`
+ `#define` USER_FLUSH() {DEBUGOUTFlush();}
+ `#endif`
+#elif defined(WLED_ENABLE_NET_DEBUG)
+ // use net debug routing directly even when WLED_DEBUG is off
+ `#define` USER_PRINT(x) DEBUGOUT(x)
+ `#define` USER_PRINTLN(x) DEBUGOUTLN(x)
+ `#define` USER_PRINTF(x...) DEBUGOUTF(x)
`#ifdef` WLED_ENABLE_NET_DEBUG
`#define` USER_FLUSH() {}
`#else`
`#define` USER_FLUSH() {DEBUGOUTFlush();}
`#endif`🤖 Prompt for AI Agents |
||
| #else | ||
| // if serial is available, we use Serial.print directly | ||
| #define USER_PRINT(x) { if (canUseSerial()) DEBUGOUT(x); } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @coderabbitai where is the implementation of ``canUseSerial()`?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: Length of output: 501 🏁 Script executed: Length of output: 501 🏁 Script executed: Length of output: 509 🏁 Script executed: Length of output: 0 🏁 Script executed: Length of output: 12284
This would cause a compilation error for a standard build. The existing WLED idiom for guarding serial output is the global boolean The macros should likely read: `#define` USER_PRINT(x) { if (serialCanTX) Serial.print(x); }
`#define` USER_PRINTLN(x) { if (serialCanTX) Serial.println(x); }
`#define` USER_PRINTF(x...) { if (serialCanTX) Serial.printf(x); }(or route through 🧠 Learnings used
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I this the function was forgotten when porting over from WLED-MM
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: Length of output: 1794
bool canUseSerial(void) {
// On S3/C3/C6/P4, USB CDC blocks if disconnected
`#if` ARDUINO_USB_CDC_ON_BOOT && (defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32P4)) && !defined(WLED_ENABLE_NET_DEBUG)
if (!Serial) return false;
`#endif`
// TX pin allocated to LEDs or other non-debug function
if (pinManager.isPinAllocated(hardwareTX) && (pinManager.getPinOwner(hardwareTX) != PinOwner::DebugOut))
return false;
// Serial in use for Adalight / TPM2NET / generic realtime streaming
if ((realtimeMode == REALTIME_MODE_GENERIC) || (realtimeMode == REALTIME_MODE_ADALIGHT) || (realtimeMode == REALTIME_MODE_TPM2NET))
return false;
// Don't interfere with IMPROV
if (improvActive > 0) return false;
// Continuous Serial Streaming active
if (continuousSendLED == true) return false;
return true;
}Two things to note for the port:
Without both the definition and the declaration, any build that doesn't define ✏️ Learnings added
🧠 Learnings used
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree that the minimal replacement could be checking
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
// if serial is available, we use Serial.print directly
`#define` USER_PRINT(x) { if (serialCanTX) Serial.print(x); }
`#define` USER_PRINTLN(x) { if (serialCanTX) Serial.println(x); }
`#define` USER_PRINTF(x...) { if (serialCanTX) Serial.printf(x); }
`#define` USER_FLUSH() { Serial.flush(); }This avoids the missing-function compile error and stays consistent with how ✏️ Learnings added
🧠 Learnings used |
||
| #define USER_PRINTLN(x) { if (canUseSerial()) DEBUGOUTLN(x); } | ||
| #define USER_PRINTF(x...) { if (canUseSerial()) DEBUGOUTF(x); } | ||
| #define USER_FLUSH() {DEBUGOUTFlush();} | ||
| #endif | ||
|
|
||
|
|
||
| #ifdef WLED_DEBUG_FS | ||
| #define DEBUGFS_PRINT(x) DEBUGOUT.print(x) | ||
| #define DEBUGFS_PRINTLN(x) DEBUGOUT.println(x) | ||
| #define DEBUGFS_PRINTF(x...) DEBUGOUT.printf(x) | ||
| #define DEBUGFS_PRINT(x) DEBUGOUT(x) | ||
| #define DEBUGFS_PRINTLN(x) DEBUGOUTLN(x) | ||
| #define DEBUGFS_PRINTF(x...) DEBUGOUTF(x) | ||
| #else | ||
| #define DEBUGFS_PRINT(x) | ||
| #define DEBUGFS_PRINTLN(x) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: wled/WLED
Length of output: 1720
🏁 Script executed:
Repository: wled/WLED
Length of output: 2811
DEBUGBUS_PRINTF_Pmapping violates PROGMEM string handling.Line 43 maps
DEBUGBUS_PRINTF_PtoDEBUGOUTF, which fromwled.h(lines 993, 998) callsSerial.printf(x)orNetDebug.printf(x)— notprintf_P().The actual callsite at line 482 uses:
On ESP8266,
PSTR()strings reside in PROGMEM and must be read viaprintf_P(). Calling plainprintf()on a PROGMEM pointer produces garbled output or faults.The project guideline states: "Use
PSTR()withDEBUG_PRINTF_P()for format strings." This change violates that by silently dropping the_Pdistinction.Either:
DEBUGOUTF_Pmacro that callsprintf_P(), orDEBUGOUTFitself PROGMEM-aware (route_Pcalls throughprintf_P()on ESP8266).Then wire
DEBUGBUS_PRINTF_Pto the correct macro.🤖 Prompt for AI Agents