Summary of differences between Ethernet and non-Ethernet builds - analysis, no code changes#5432
Summary of differences between Ethernet and non-Ethernet builds - analysis, no code changes#5432
Conversation
…e-selected via WLED_ETH_DEFAULT Co-authored-by: netmindz <442066+netmindz@users.noreply.github.com>
This assessment was wrong.
Ask a human ;-) The other differences between ethernet builds and normal (wifi-first) builds can be found by searching for
In summary: yes an ethernet build will run on non-ethernet esp32, but some features may behave unexpected. A non-ethernet build on ethernet boards may run, or may crash. |
|
@copilot please revise your proposal based on the new information provided. Do not change code in this PR. Just provide a summary of differences, based on your source code review and other information available to you. Also check the official espressif documentation for recommendations regarding custom firmware with Wi-Fi and ethernet on esp32. |
Co-authored-by: softhack007 <91616163+softhack007@users.noreply.github.com>
Reverted the code change in 37e4e48. The PR description now contains a comprehensive summary of all 15 categories of differences between ethernet-enabled and non-ethernet builds, based on reviewing every |
|
@coderabbitai can you also please review what the difference is between using a build with the ethernet support enabled in the build, but no ethernet device selected at runtime Vs a build with no support. Also what are your opinions of the review by copilot ? |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chainLet me search the codebase to understand the runtime behavior differences. 🏁 Script executed: Length of output: 10826 🏁 Script executed: Length of output: 1473 🏁 Script executed: Length of output: 4119 🏁 Script executed: Length of output: 5224 🏁 Script executed: Length of output: 3329
1.
|
| Feature | WLED_USE_ETHERNET + ETH_NONE |
No ethernet build |
|---|---|---|
DEFAULT_LED_PIN |
4 (const.h:661) |
16 |
E131_MAX_UNIVERSE_COUNT |
20 (const.h:556) |
12 (ESP32) / 9 (ESP8266) |
| SPI bus for APA102/WS2801 | HSPI (bus_wrapper.h:307,324) |
VSPI |
| aPLL for I2S MCLK audio | Disabled (audio_source.h:234) |
Enabled |
| Ethernet board type in Settings UI | Visible (shows "None") | Hidden |
eth.type written to cfg.json |
Yes (as 0) |
No |
| Debug DNS resolution | ETH.hostByName() |
WiFi.hostByName() |
| Flash usage | Larger (ETH driver compiled) | Smaller |
| ETH event handlers compiled in | Yes (never fire) | No |
Notable concern: In net_debug.cpp, the ethernet build always uses ETH.hostByName() for debug DNS resolution — but with WLED_ETH_NONE, ETH.begin() is never called, so this call will silently fail. A non-ethernet build correctly uses WiFi.hostByName().
Also notable: The aPLL being disabled for audio is a compile-time penalty. If someone runs a WLED_USE_ETHERNET firmware on a non-ethernet board with ETH_NONE, they lose I2S MCLK audio quality for no reason.
Differences that ARE correctly gated by ethernetType != WLED_ETH_NONE at runtime
These only activate if a real ethernet board type is selected:
- Pin reservation:
initEthernet()returns immediately atnetwork.cpp:168whenethernetType == WLED_ETH_NONE. No RMII pins or board-specific pins are allocated. ETH.begin(): Never called — no ethernet hardware initialization.- MAC/IP preference: ETH MAC/IP is only preferred after a successful
ETH_CONNECTEDevent, which never fires withETH_NONE. - WiFi disconnect on ETH connect: The
WiFi.disconnect(true)atnetwork.cpp:411only runs insideARDUINO_EVENT_ETH_CONNECTED, which never triggers. cfg.jsonpin array: Only written whenethernetType != WLED_ETH_NONE(cfg.cpp:916).- Reserved pins in settings UI: Guarded by the same
ethernetType != WLED_ETH_NONEcheck (xml.cpp:135).
Summary
A
WLED_USE_ETHERNETbuild withETH_NONEis NOT the same as a non-ethernet build. It carries compile-time overhead (flash, altered defaults, disabled aPLL, HSPI bus) even when no ethernet adapter is selected. The "no adapter" state correctly avoids the dangerous runtime side-effects (pin lockout, WiFi disconnect, MAC weirdness), but the compile-time costs and defaults remain.
2. Opinion on the Copilot Review
The Copilot review had a significant factual error on its main claim. It assessed that the DEFAULT_LED_PIN = 4 override for WLED_USE_ETHERNET builds was unnecessary because the official esp32_eth PlatformIO environment already sets DATA_PINS=4 explicitly.
softhack007 correctly explained why this was wrong:
- Custom build environments: Users creating custom ethernet build environments may not set
DATA_PINSexplicitly. TheDEFAULT_LED_PIN=4inconst.his a safety net for them. - First-boot
cfg.jsoninitialization: On a fresh install, WLED writes its defaults tocfg.json. IfDEFAULT_LED_PIN=16, that gets saved tocfg.jsonimmediately — and on many ethernet boards GPIO16 is hard-wired to the ethernet clock output, causing crashes. WLED_ETH_DEFAULT != WLED_ETH_NONEis not a safe guard: softhack007 explicitly flagged this as dangerous logic to rely on.
The Copilot review lacked awareness of the hardware deployment context — specifically, the first-boot cfg.json write behavior and the heterogeneity of custom ethernet build environments. This caused a valid and intentional safety measure to be incorrectly flagged and reverted, requiring a maintainer to manually explain the reasoning.
This is a good illustration of where static code analysis without hardware/deployment context can produce misleading results, particularly in firmware projects where "what gets written on first boot" matters as much as runtime logic.
✏️ Learnings added
Learnt from: netmindz
URL: https://github.com/wled/WLED/pull/5432
Timestamp: 2026-03-20T15:29:26.641Z
Learning: In WLED ethernet builds (WLED_USE_ETHERNET), the DEFAULT_LED_PIN=4 override in const.h:661 is an intentional safety measure that applies at compile-time regardless of the runtime ethernetType value. It protects against first-boot cfg.json writes saving GPIO16 as the LED pin on ethernet boards where GPIO16 is hard-wired to ethernet clock output (ETH_CLOCK_GPIO16_OUT), which causes crashes. It also protects custom build environments that forget to set DATA_PINS explicitly. This was confirmed by softhack007 in PR `#5432`.
Learnt from: netmindz
URL: https://github.com/wled/WLED/pull/5432
Timestamp: 2026-03-20T15:29:26.641Z
Learning: In WLED, a WLED_USE_ETHERNET build with ethernetType=WLED_ETH_NONE (no adapter selected at runtime) differs from a non-ethernet build in several compile-time ways that persist even with no adapter: DEFAULT_LED_PIN is 4 (not 16), E131_MAX_UNIVERSE_COUNT is 20 (not 12), APA102/WS2801 uses HSPI (not VSPI), I2S MCLK aPLL is disabled (audio quality cost), ethernet UI is visible in settings, eth.type=0 is written to cfg.json, and net_debug.cpp uses ETH.hostByName() (which will fail since ETH is never initialized). The runtime-gated behaviors (pin reservation, ETH.begin(), WiFi disconnect, MAC/IP preference) are correctly skipped when ethernetType==WLED_ETH_NONE.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
🧠 Learnings used
Learnt from: DedeHai
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2026-02-21T15:07:26.737Z
Learning: On ESP32 with ESP-IDF V4, there is an APLL (Audio PLL) resource conflict between Ethernet (when using internal RMII clock on GPIO 0/16/17) and I2S PDM microphones. In commit 98138a02e (Nov 2022, PR `#2907`), the audio reactive usermod was changed to set `use_apll = true` for PDM microphones in `usermods/audioreactive/audio_source.h` line 228. This causes Ethernet initialization to fail because both EMAC and I2S PDM cannot share the APLL simultaneously. This was not an issue in v0.15.3 because APLL was not enabled for PDM mode at that time. The fix is to disable APLL for PDM mode when Ethernet is enabled, either through runtime detection or a compile-time flag.
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2026-03-15T13:21:32.008Z
Learning: In WLED code reviews (and generally), when a PR discussion involves "is this worth doing?" uncertainty about a proposed reliability, safety, or data-integrity mechanism (e.g. CRC checks, backups, power-loss protection), suggest performing a software FMEA (Failure Mode and Effects Analysis). The FMEA should: enumerate failure modes for the feared event, assess each mitigation's effectiveness per failure mode, note common-cause/common-mode failures, and rate credibility for the typical WLED use case. This was successfully used in PR `#5421` to evaluate CRC-based config file protection and was well-received by the WLED maintainers (softhack007 explicitly requested this be remembered for future reviews).
Learnt from: softhack007
Repo: wled/WLED PR: 5048
File: wled00/bus_manager.cpp:549-556
Timestamp: 2026-02-11T16:20:02.872Z
Learning: ESP-IDF V5 requires a complete rewrite of the LEDC (PWM/analog LED) subsystem in WLED. The framework now manages LEDC channels internally (unlike V4 where WLED managed them directly), and dithering functionality may not work as it did before. Direct LEDC struct access (e.g., `LEDC.channel_group[gr].channel[ch].duty.duty`) used in the current implementation will need to be replaced with proper HAL API calls. This affects `wled00/bus_manager.cpp` BusPwm class and related pin manager LEDC allocation code.
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:11.994Z
Learning: In WLED code reviews, when code is modified or added, look for "magic numbers" (hardcoded numeric literals) and suggest replacing them with appropriate defined constants when those constants are meaningful in the context of the PR. For example, the hardcoded value 32 should be replaced with WLED_MAX_SEGNAME_LEN when it represents a segment name length limit. This improves code maintainability and reduces the risk of inconsistencies.
Learnt from: softhack007
Repo: wled/WLED PR: 5048
File: wled00/wled.cpp:385-387
Timestamp: 2026-02-08T19:33:02.648Z
Learning: In WLED ESP32 code, when checking whether USB CDC serial initialization delay is needed, rely on the ARDUINO_USB_CDC_ON_BOOT flag rather than explicit CONFIG_IDF_TARGET checks, because not all development boards for chips with native USB capability (ESP32-C3/C5/C6/S2/S3/H2/P4) actually use the native USB—many have external UART bridge chips instead. The ARDUINO_USB_CDC_ON_BOOT flag correctly indicates the board's actual USB configuration.
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-11-14T13:37:30.955Z
Learning: In WLED code reviews, when code is modified or added, look for "magic numbers" (hardcoded numeric literals) and suggest replacing them with defined constants when meaningful constants exist in the codebase. For example, suggest replacing hardcoded "32" with WLED_MAX_SEGNAME_LEN if the context relates to segment name length limits.
Learnt from: netmindz
Repo: wled/WLED PR: 5093
File: wled00/util.cpp:1159-1182
Timestamp: 2025-11-20T00:04:04.829Z
Learning: In WLED PR `#5093`, the deviceId feature is designed for opt-in usage reporting that tracks only version/upgrade information (non-behavioral data), not user activity patterns. The deterministic salt approach (MAC + "WLED" + chip model/revision) is acceptable for this limited use case, as correlating MAC addresses to version history represents minimal privacy risk compared to behavioral tracking.
Learnt from: DedeHai
Repo: wled/WLED PR: 4939
File: wled00/FX_fcn.cpp:1176-1187
Timestamp: 2025-09-16T18:08:42.848Z
Learning: In WLED finalizeInit() bus creation (wled00/FX_fcn.cpp), intentionally allowing memory overruns when bus configurations exceed MAX_LED_MEMORY is a deliberate design choice. The trade-off prioritizes creating buses with reduced LED counts over completely failing to create buses, which would cause no LED output and UI failures. This approach forces users to update configurations after migrating to version 0.16 while maintaining basic functionality.
Learnt from: blazoncek
Repo: wled/WLED PR: 4482
File: wled00/udp.cpp:147-149
Timestamp: 2025-02-19T12:43:34.199Z
Learning: ESP8266 and ESP32 platforms have different maximum segment name lengths in WLED, which can cause truncation when syncing segment names between devices. This platform difference affects the user experience when using the segment name sync feature.
Learnt from: mval-sg
Repo: wled/WLED PR: 4876
File: wled00/xml.cpp:0-0
Timestamp: 2025-08-28T08:09:20.630Z
Learning: The WLED codebase has opportunities for refactoring hardcoded array bounds (like the "15" used for DMX channels) to use sizeof(array)/sizeof(array[0]) for more maintainable code, but such changes should be done consistently across the entire codebase in a dedicated refactoring effort.
Learnt from: mval-sg
Repo: wled/WLED PR: 4876
File: wled00/wled_eeprom.cpp:0-0
Timestamp: 2025-09-01T10:26:17.959Z
Learning: In WLED PR `#4876`, the DMXStartLED EEPROM backward compatibility issue was partially addressed by keeping it at address 2550 and reading it as a 16-bit value, with DMXChannelsValue array moved to addresses 2552-2566. This maintains compatibility with pre-0.11 EEPROM layouts for DMXStartLED, though legacy "Set to 255" (code 6) configurations may still need migration logic.
|
Thank you, very informative! |
|
Besides the differences on flash size, possibly zero'd MAC for WiFi, and aPLL audioreactive handling (I2S MCLK -> aux-in degraded quality), I think that "SPI bus for APA102/WS2801 => HSPI vs. VSPI" is actually the most user-visible limitation with ethernet builds. If users have APA102 (or other SPI "dot*star" based LEDs) on an ethernet build, it means
|
Per reviewer feedback, the original code change has been reverted — the
DEFAULT_LED_PIN = 4override whenWLED_USE_ETHERNETis defined is an intentional safety measure. This PR now contains no code changes, only a summary of differences based on source code review.Summary of Differences: Ethernet vs Non-Ethernet Builds
1. Default LED Pin (
const.h:660)DEFAULT_LED_PIN = 4(GPIO4 — safe for all known ethernet boards)DEFAULT_LED_PIN = 16(GPIO16 — standard ESP32 default)ETH_CLOCK_GPIO16_OUT). A fresh install with pin 16 on these boards causes crashes.2. E1.31/Art-Net Universe Count (
const.h:555)E131_MAX_UNIVERSE_COUNT = 20E131_MAX_UNIVERSE_COUNT = 12E131_MAX_UNIVERSE_COUNT = 93. SPI Bus for APA102/WS2801 LEDs (
bus_wrapper.h:307,324)4. Network Identity & Routing (
Network.cpp)5. Ethernet Board Configuration & Pin Reservation (
network.cpp,wled.h)ethernetTypeglobal,initEthernet()allocates up to 10 pins (6 non-configurable RMII pins + MDC, MDIO, power, clock).6. WiFi Behavior on Ethernet Connect (
network.cpp:413)7. Settings UI (
xml.cpp:279,set.cpp:148)8. GPIO Reservation in Settings (
xml.cpp:134)9. Configuration Persistence (
cfg.cpp:133,913)eth.typeandeth.pin[]incfg.json.10. Debug Output Routing (
net_debug.cpp:12,33)ETH.hostByName()for DNS resolution of debug host.WiFi.hostByName().11. Audio Reactive aPLL Conflict (
usermods/audioreactive/audio_source.h:234)12. Usermod Behavior (quinled-an-penta)
13. Platform Restrictions
14. ESP-NOW Interactions (#5210, #4703)
ETH_CLOCK_GPIO0_OUT,ETH_CLOCK_GPIO16_OUT, orETH_CLOCK_GPIO17_OUTmay crash when ESP-NOW is enabled.15. Flash Space
Espressif ESP-IDF Recommendations
Per Espressif documentation, the ESP32 EMAC uses a dedicated RMII interface with fixed pins that cannot be remapped. WiFi and Ethernet can coexist but share some hardware resources (notably the aPLL clock). The recommendation is to configure the PHY and clock mode correctly for the specific board hardware.
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.