-
-
Notifications
You must be signed in to change notification settings - Fork 4k
DMX Output - Runtime Config & replace SparkFunDMX with esp_dmx #5287
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?
Conversation
WalkthroughAdds pin-configurable DMX output: introduces a DMXOutput API and pin-based initialization, updates DMX drivers to use a send pin, persists/exposes Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| -D DECODE_LG=true | ||
| -DWLED_USE_MY_CONFIG | ||
| -D WLED_PS_DONT_REPLACE_FX ; PS replacement FX are purely a flash memory saving feature, do not replace classic FX until we run out of flash | ||
| -D WLED_ENABLE_DMX |
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.
TODO: remove after testing, unless we can safely enable by default now it can be enabled at runtime?
|
I still need to test with actual hardware, but I think this should be pretty close to the required code |
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.
Actionable comments posted: 6
🤖 Fix all issues with AI agents
In @wled00/cfg.cpp:
- Around line 1124-1126: The JSON serialization writes the DMX pin under
"dmxOutputPin" but deserialization expects "outputPin", causing a mismatch;
change the key used when assigning into if_live_dmx (replace F("dmxOutputPin")
with F("outputPin")) in the WLED_ENABLE_DMX serialization block so the key
matches the deserializer that reads "outputPin" (or alternatively update the
deserializer to "dmxOutputPin" if you prefer that name) and verify the
if_live_dmx / dmxOutputPin mapping is consistent.
- Around line 600-602: There is a JSON key mismatch between the deserialization
and serialization of the DMX output pin: the deserializer reads
if_live_dmx[F("outputPin")] while the serializer writes
if_live_dmx[F("dmxOutputPin")]; pick one key and make both sides consistent
(either change the deserialization call that references F("outputPin") to use
F("dmxOutputPin") or change the serializer to write F("outputPin")), ensuring
the symbol dmxOutputPin and the if_live_dmx JSON object use the same key so
config persistence/deserialization works correctly.
In @wled00/dmx_output.cpp:
- Around line 73-75: The DEBUG_PRINTF call is using "%s" but
PinManager::getPinOwner(outputPin) returns a PinOwner enum; change the code to
print the enum correctly by either converting the enum to a string (add or call
a helper like PinOwnerToString/PinManager::getPinOwnerName that returns const
char* and pass that to DEBUG_PRINTF) or print its integer value by using the
correct format specifier (e.g., replace "%s" with "%d" and cast the enum to
int). Update the DEBUG_PRINTF invocation that references PinManager::getPinOwner
so the format specifier matches the provided value.
- Around line 96-97: The stub for the disabled-DMX branch has a mismatched
signature: change the no-arg initDMXOutput() to match the declaration
initDMXOutput(int outputPin) so compilation succeeds when WLED_ENABLE_DMX is not
defined; keep handleDMXOutput() as-is, and mark the unused parameter (outputPin)
appropriately (e.g., omit its name or use an attribute/void cast) to avoid
unused-parameter warnings while ensuring the function signature matches the
header.
- Around line 86-91: DMXOutput::write stores values into the local dmxdata[] but
update() never copies that buffer to the driver; call dmx_write(dmxPort,
dmxdata, DMX_PACKET_SIZE) before dmx_send(dmxPort, DMX_PACKET_SIZE) so the
driver's internal buffer gets the latest channel values. Locate
DMXOutput::update and insert the dmx_write(dmxPort, dmxdata, DMX_PACKET_SIZE)
call immediately prior to the existing dmx_send invocation, keeping
DMX_PACKET_SIZE and dmxPort as used in the diff.
In @wled00/set.cpp:
- Around line 441-443: The code stores a new dmxOutputPin from
request->arg(F("IDMO")).toInt() but doesn't reallocate or reinitialize DMX at
runtime; update the handler to mirror the IR logic: if a previous dmxOutputPin
was allocated, release it via PinManager, validate/allocate the new pin with
PinManager (handle invalid/unavailable pins), update the dmxOutputPin variable,
and call initDMXOutput() to reinitialize DMX with the new pin (or log/report
failure). Ensure you reference and update the same symbols: dmxOutputPin,
PinManager (allocate/deallocate), and initDMXOutput() so runtime pin changes
take effect.
🧹 Nitpick comments (2)
wled00/fcn_declare.h (1)
78-78: Address parameter type inconsistency between DMX initialization functions.The
initDMXOutput()function usesint outputPinhere and in its implementation, butDMXOutput::init()expectsuint8_t outputPin. Additionally, the globaldmxOutputPinvariable in wled.h is declared asintwith a default of-1(for disabled state), which cannot be properly represented asuint8_t. While the implementation guards against negative values withif (outputPin < 1) return;, standardize the parameter type across the declaration, implementation, and theDMXOutputclass API for clarity and to accurately represent the valid range of pin values.wled00/src/dependencies/dmx/ESPDMX.cpp (1)
21-28: Consider adding defensive validation for sendPin.The function relies on the caller to validate
sendPin, but ifinit()is called directly with an invalid pin (e.g., -1), it could cause undefined behavior withpinMode()and Serial operations.🛡️ Optional: Add defensive check
void DMXESPSerial::init(int sendPin) { + if (sendPin < 0) return; this->sendPin = sendPin; channelSize = defaultMax; Serial1.begin(DMXSPEED); pinMode(sendPin, OUTPUT); dmxStarted = true; }
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (15)
platformio.iniwled00/cfg.cppwled00/data/settings_sync.htmwled00/dmx_output.cppwled00/dmx_output.hwled00/fcn_declare.hwled00/pin_manager.hwled00/set.cppwled00/src/dependencies/dmx/ESPDMX.cppwled00/src/dependencies/dmx/ESPDMX.hwled00/src/dependencies/dmx/SparkFunDMX.cppwled00/src/dependencies/dmx/SparkFunDMX.hwled00/wled.cppwled00/wled.hwled00/xml.cpp
💤 Files with no reviewable changes (2)
- wled00/src/dependencies/dmx/SparkFunDMX.cpp
- wled00/src/dependencies/dmx/SparkFunDMX.h
🧰 Additional context used
📓 Path-based instructions (6)
wled00/**/*.cpp
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 2-space indentation for C++ source files (.cpp)
Files:
wled00/xml.cppwled00/cfg.cppwled00/dmx_output.cppwled00/wled.cppwled00/set.cppwled00/src/dependencies/dmx/ESPDMX.cpp
wled00/**/!(html_*)*.h
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 2-space indentation for non-generated C++ header files (.h)
Files:
wled00/pin_manager.hwled00/fcn_declare.hwled00/dmx_output.hwled00/src/dependencies/dmx/ESPDMX.hwled00/wled.h
wled00/data/**/*.{htm,html,css,js}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use tabs for indentation in web files (.htm/.html/.css/.js) under wled00/data
Files:
wled00/data/settings_sync.htm
wled00/data/**
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
wled00/data/**: When modifying web UI files, runnpm run buildto regenerate embedded headers before any firmware build
For web UI changes, edit files only under wled00/data (not firmware or generated files)
Files:
wled00/data/settings_sync.htm
wled00/data/settings*.htm
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Name settings pages as settings*.htm within the web UI
Files:
wled00/data/settings_sync.htm
platformio.ini
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use platformio.ini as the single source of truth for hardware build targets and settings
Files:
platformio.ini
🧠 Learnings (26)
📓 Common learnings
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.
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: 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: DedeHai
Repo: wled/WLED PR: 4798
File: wled00/FX.cpp:7531-7533
Timestamp: 2025-08-26T11:51:21.817Z
Learning: In WLED PR #4798, DedeHai confirmed that certain gamma-related calls in FX.cpp/FX_fcn.cpp/particle systems are intentional for effect-level shaping (e.g., brightness curves, TV sim, Pride 2015 pre-mix), distinct from final output gamma. Do not flag or remove these in future reviews; add comments when feasible to clarify intent.
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: DedeHai
Repo: wled/WLED PR: 4997
File: wled00/e131.cpp:33-44
Timestamp: 2025-10-10T18:34:06.550Z
Learning: In WLED's DDP packet handling (ws.cpp and e131.cpp), only prevent out-of-bounds memory access rather than enforcing DDP spec compliance. Don't check the 1440-byte spec limit—accept out-of-spec packets assuming correct encoding. The bounds check `maxDataIndex = c + numLeds * ddpChannelsPerLed; if (maxDataIndex > dataLen) reject` is sufficient and already covers the timecode flag case (when c=4) without needing separate validation.
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-12-28T14:06:48.772Z
Learning: In WLED post-commit ee9ac947, the rendering pipeline uses per-segment buffers and per-pixel bus updates. Unmapped (0xFFFF) mapping entries are now skipped in WS2812FX::show() (no “clear to black”), which can leave physical gap LEDs with stale/random colors unless they are explicitly cleared. This is a behavior change from pre-0.16 where a full physical buffer was effectively refreshed each frame.
📚 Learning: 2025-09-01T10:26:17.959Z
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.
Applied to files:
wled00/xml.cppwled00/pin_manager.hwled00/fcn_declare.hwled00/cfg.cppwled00/dmx_output.cppwled00/dmx_output.hwled00/wled.cppwled00/data/settings_sync.htmwled00/set.cppwled00/src/dependencies/dmx/ESPDMX.cppwled00/src/dependencies/dmx/ESPDMX.hplatformio.iniwled00/wled.h
📚 Learning: 2025-10-10T18:34:06.550Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4997
File: wled00/e131.cpp:33-44
Timestamp: 2025-10-10T18:34:06.550Z
Learning: In WLED's DDP packet handling (ws.cpp and e131.cpp), only prevent out-of-bounds memory access rather than enforcing DDP spec compliance. Don't check the 1440-byte spec limit—accept out-of-spec packets assuming correct encoding. The bounds check `maxDataIndex = c + numLeds * ddpChannelsPerLed; if (maxDataIndex > dataLen) reject` is sufficient and already covers the timecode flag case (when c=4) without needing separate validation.
Applied to files:
wled00/xml.cppwled00/cfg.cppwled00/dmx_output.cppwled00/wled.cppwled00/set.cppwled00/src/dependencies/dmx/ESPDMX.hplatformio.iniwled00/wled.h
📚 Learning: 2025-08-26T11:51:21.817Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4798
File: wled00/FX.cpp:7531-7533
Timestamp: 2025-08-26T11:51:21.817Z
Learning: In WLED PR #4798, DedeHai confirmed that certain gamma-related calls in FX.cpp/FX_fcn.cpp/particle systems are intentional for effect-level shaping (e.g., brightness curves, TV sim, Pride 2015 pre-mix), distinct from final output gamma. Do not flag or remove these in future reviews; add comments when feasible to clarify intent.
Applied to files:
wled00/xml.cppwled00/fcn_declare.hwled00/cfg.cppwled00/dmx_output.cppwled00/wled.cppwled00/set.cppplatformio.ini
📚 Learning: 2025-08-28T08:09:20.630Z
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.
Applied to files:
wled00/xml.cppwled00/fcn_declare.hwled00/cfg.cppwled00/dmx_output.cppwled00/dmx_output.hwled00/wled.cppwled00/set.cppwled00/src/dependencies/dmx/ESPDMX.cppwled00/src/dependencies/dmx/ESPDMX.hplatformio.iniwled00/wled.h
📚 Learning: 2025-09-16T18:08:42.848Z
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.
Applied to files:
wled00/xml.cppwled00/fcn_declare.hwled00/cfg.cppwled00/dmx_output.cppwled00/wled.cppwled00/src/dependencies/dmx/ESPDMX.hplatformio.iniwled00/wled.h
📚 Learning: 2025-10-05T15:24:05.545Z
Learnt from: CR
Repo: wled/WLED PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-05T15:24:05.545Z
Learning: Applies to wled00/html_*.h : DO NOT edit generated embedded web header files (wled00/html_*.h)
Applied to files:
wled00/xml.cppwled00/fcn_declare.hplatformio.iniwled00/wled.h
📚 Learning: 2025-12-28T14:06:48.772Z
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-12-28T14:06:48.772Z
Learning: In WLED post-commit ee9ac947, the rendering pipeline uses per-segment buffers and per-pixel bus updates. Unmapped (0xFFFF) mapping entries are now skipped in WS2812FX::show() (no “clear to black”), which can leave physical gap LEDs with stale/random colors unless they are explicitly cleared. This is a behavior change from pre-0.16 where a full physical buffer was effectively refreshed each frame.
Applied to files:
wled00/xml.cppwled00/cfg.cppwled00/dmx_output.cppwled00/wled.cppwled00/set.cppwled00/src/dependencies/dmx/ESPDMX.cppwled00/wled.h
📚 Learning: 2025-10-05T15:24:05.545Z
Learnt from: CR
Repo: wled/WLED PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-05T15:24:05.545Z
Learning: Applies to wled00/data/** : For web UI changes, edit files only under wled00/data (not firmware or generated files)
Applied to files:
wled00/xml.cpp
📚 Learning: 2025-09-12T17:29:43.826Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4923
File: wled00/FX.cpp:4883-4901
Timestamp: 2025-09-12T17:29:43.826Z
Learning: In WLED’s web UI, only one slider value (e.g., SEGMENT.intensity or SEGMENT.custom1) changes at a time; code relying on this may use simplified change guards, though presets/JSON can still update multiple fields atomically.
Applied to files:
wled00/xml.cpp
📚 Learning: 2025-11-14T13:37:30.955Z
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.
Applied to files:
wled00/xml.cppwled00/cfg.cppwled00/wled.cppwled00/set.cppplatformio.iniwled00/wled.h
📚 Learning: 2025-03-29T01:22:54.617Z
Learnt from: willmmiles
Repo: wled/WLED PR: 4623
File: usermods/word-clock-matrix/word-clock-matrix.cpp:332-332
Timestamp: 2025-03-29T01:22:54.617Z
Learning: In the WLED project, hardcoded usermod IDs (like 500 in the WordClockMatrix's getId() method) are intentionally used as part of a strategy to avoid modifying core code. There are plans to remove numeric usermod IDs entirely in the future.
Applied to files:
wled00/pin_manager.h
📚 Learning: 2025-06-15T09:59:52.720Z
Learnt from: netmindz
Repo: wled/WLED PR: 4728
File: wled00/FX.h:378-378
Timestamp: 2025-06-15T09:59:52.720Z
Learning: In WLED's FX.h, MODE_COUNT represents the highest FX_MODE_ ID + 1, not the total count of FX_MODE_ definitions. This is because some effects may have been removed but their IDs are not reused, creating gaps in the numbering sequence. MODE_COUNT is used for array bounds and range checking.
Applied to files:
wled00/pin_manager.hwled00/wled.h
📚 Learning: 2025-08-31T03:38:14.114Z
Learnt from: BobLoeffler68
Repo: wled/WLED PR: 4891
File: wled00/FX.cpp:3333-3349
Timestamp: 2025-08-31T03:38:14.114Z
Learning: WLED PacMan effect (wled00/FX.cpp): Keep pacmancharacters_t position fields as signed int (not int16_t). Maintainer preference (blazoncek) prioritizes avoiding potential overhead/regressions over minor RAM savings. Avoid type shrinking here unless memory pressure is demonstrated.
Applied to files:
wled00/fcn_declare.hwled00/cfg.cppwled00/wled.cppwled00/wled.h
📚 Learning: 2025-11-16T19:40:46.260Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4926
File: wled00/FX.cpp:4727-4730
Timestamp: 2025-11-16T19:40:46.260Z
Learning: WLED AuroraWave (wled00/FX.cpp): wave_start and wave_end intentionally use int16_t; segments longer than 32k LEDs are not supported (bounded by MAX_LEDS), so widening to 32-bit is unnecessary.
Applied to files:
wled00/fcn_declare.hwled00/cfg.cppwled00/dmx_output.cppwled00/wled.cppwled00/wled.h
📚 Learning: 2025-11-14T13:37:11.994Z
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.
Applied to files:
wled00/cfg.cppwled00/set.cppwled00/wled.h
📚 Learning: 2025-08-29T00:26:15.808Z
Learnt from: ksedgwic
Repo: wled/WLED PR: 4883
File: usermods/usermod_v2_skystrip/rest_json_client.h:6-14
Timestamp: 2025-08-29T00:26:15.808Z
Learning: WLED uses a vendored ArduinoJson library (version 6) located at "src/dependencies/json/ArduinoJson-v6.h" which is included through wled.h. Usermods should not directly include ArduinoJson headers but instead rely on wled.h for ArduinoJson symbols. The standard pattern is to include wled.h and use JsonObject, JsonArray, DynamicJsonDocument, etc. without additional includes.
Applied to files:
wled00/dmx_output.cppwled00/wled.h
📚 Learning: 2025-08-29T00:26:15.808Z
Learnt from: ksedgwic
Repo: wled/WLED PR: 4883
File: usermods/usermod_v2_skystrip/rest_json_client.h:6-14
Timestamp: 2025-08-29T00:26:15.808Z
Learning: In WLED projects, ArduinoJson.h is not directly included via #include <ArduinoJson.h> - the ArduinoJson symbols are made available through the WLED build system and wled.h transitive includes, so explicitly adding #include <ArduinoJson.h> is not necessary and may not work.
Applied to files:
wled00/dmx_output.cppwled00/wled.h
📚 Learning: 2026-01-03T16:42:26.035Z
Learnt from: DedeHai
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2026-01-03T16:42:26.035Z
Learning: In WLED, both parallel I2S and single I2S modes require additional DMA buffers (4× the pixel buffer size). The memory calculation must account for which specific buses use I2S hardware, not just check digitalCount <= 8, because single I2S mode places the I2S bus at the END (ESP32 bus 8 with digitalCount=9, S2 bus 4 with digitalCount=5).
Applied to files:
wled00/dmx_output.cppwled00/wled.h
📚 Learning: 2025-09-13T13:13:35.817Z
Learnt from: netmindz
Repo: wled/WLED PR: 3777
File: wled00/bus_manager.cpp:941-947
Timestamp: 2025-09-13T13:13:35.817Z
Learning: For HUB75 matrix panels in WLED, pins are physically dedicated to the matrix hardware and don't need to be deallocated on driver initialization failure since they cannot be reused for other purposes without hardware changes.
Applied to files:
wled00/wled.cpp
📚 Learning: 2025-09-18T03:17:30.107Z
Learnt from: willmmiles
Repo: wled/WLED PR: 4939
File: wled00/FX_fcn.cpp:1183-1194
Timestamp: 2025-09-18T03:17:30.107Z
Learning: In WLED finalizeInit() bus creation (wled00/FX_fcn.cpp), digitalCount is intentionally incremented even for placeholder buses to maintain consistent resource mapping across all bus configurations.
Applied to files:
wled00/wled.cpp
📚 Learning: 2025-12-01T07:01:16.949Z
Learnt from: blazoncek
Repo: wled/WLED PR: 5140
File: wled00/data/settings_time.htm:66-76
Timestamp: 2025-12-01T07:01:16.949Z
Learning: In WLED PR #5134, the fix for macros being initialized with the enable bit set only handles new configurations, not existing ones. If there is a bug in timer/macro handling code (e.g., in settings_time.htm), it must be fixed to work correctly for existing configurations as well.
Applied to files:
wled00/set.cpp
📚 Learning: 2025-11-22T20:33:14.840Z
Learnt from: softhack007
Repo: wled/WLED PR: 5107
File: boards/adafruit_matrixportal_esp32s3.json:1-66
Timestamp: 2025-11-22T20:33:14.840Z
Learning: In WLED, board JSON files in the boards/ directory may reference partition files that don't exist or have slightly different names than actual files in tools/. This is intentional because platformio.ini or platformio_override.sample.ini explicitly override the partition file using the board_build.partitions setting, which takes precedence over the board JSON partition reference. This pattern exists in multiple local board definitions and should not be flagged as an issue.
Applied to files:
platformio.ini
📚 Learning: 2025-07-06T16:11:05.896Z
Learnt from: Jason2866
Repo: wled/WLED PR: 4167
File: platformio.ini:427-430
Timestamp: 2025-07-06T16:11:05.896Z
Learning: In PlatformIO, using `-fno-lto` in `build_unflags` is a valid pattern to remove potentially existing `-fno-lto` flags from the build system before adding `-flto=auto` in `build_flags`. This ensures that LTO can be enabled without conflicts from default build system flags that might disable LTO.
Applied to files:
platformio.ini
📚 Learning: 2025-07-06T16:15:24.051Z
Learnt from: Jason2866
Repo: wled/WLED PR: 4167
File: platformio.ini:427-430
Timestamp: 2025-07-06T16:15:24.051Z
Learning: In espressif Arduino framework, `-fno-lto` is set as a standard default in the `platformio-build.py` script. Therefore, using `-fno-lto` in `build_unflags` is not only valid but necessary to remove this default setting before enabling LTO with `-flto=auto` or `-flto=4` in `build_flags`.
Applied to files:
platformio.ini
📚 Learning: 2025-10-20T09:38:51.997Z
Learnt from: blazoncek
Repo: wled/WLED PR: 4995
File: wled00/FX.cpp:5223-5226
Timestamp: 2025-10-20T09:38:51.997Z
Learning: WLED matrices: each dimension (SEG_W, SEG_H) is limited to ≤255; 256 or larger per side is not supported/feasible on ESP32, so effects should assume per-dimension max 255.
Applied to files:
wled00/wled.h
🧬 Code graph analysis (7)
wled00/xml.cpp (1)
wled00/util.cpp (4)
printSetFormValue(114-116)printSetFormValue(114-114)printSetFormValue(121-123)printSetFormValue(121-121)
wled00/fcn_declare.h (1)
wled00/dmx_output.cpp (4)
initDMXOutput(69-78)initDMXOutput(69-69)initDMXOutput(96-96)initDMXOutput(96-96)
wled00/dmx_output.h (1)
wled00/dmx_output.cpp (6)
init(81-85)init(81-81)write(86-88)write(86-86)update(89-91)update(89-89)
wled00/wled.cpp (1)
wled00/dmx_output.cpp (4)
initDMXOutput(69-78)initDMXOutput(69-69)initDMXOutput(96-96)initDMXOutput(96-96)
wled00/src/dependencies/dmx/ESPDMX.cpp (1)
wled00/dmx_output.cpp (2)
init(81-85)init(81-81)
wled00/src/dependencies/dmx/ESPDMX.h (1)
wled00/src/dependencies/dmx/ESPDMX.cpp (8)
init(21-28)init(21-21)write(31-36)write(31-31)update(44-60)update(44-44)end(38-42)end(38-38)
wled00/wled.h (2)
wled00/src/dependencies/dmx/ESPDMX.h (1)
DMXESPSerial(30-45)wled00/dmx_output.h (1)
DMXOutput(17-29)
🪛 Clang (14.0.6)
wled00/dmx_output.h
[error] 11-11: 'esp_dmx.h' file not found
(clang-diagnostic-error)
🔇 Additional comments (12)
platformio.ini (1)
124-124: LGTM: DMX feature enabled for ESP8266 builds.The compile-time flag enables DMX output functionality across ESP8266 builds. Platform-specific driver selection (ESPDMX for ESP8266, esp_dmx for ESP32) is handled via conditional compilation elsewhere in the codebase.
wled00/src/dependencies/dmx/ESPDMX.h (2)
32-32: Pin-based initialization API looks good.The refactored
init(int sendPin)signature replaces the previous parameterless and MaxChan-based initialization, supporting the new runtime pin configuration. The implementation correctly handles pin allocation as shown in the corresponding .cpp file.
37-44: Private state management is well-structured.The private members properly encapsulate DMX instance state (pin, initialization flag, data buffer, and channel count). The data store size of
dmxMaxChannel+1correctly accounts for the DMX start byte at index 0.wled00/pin_manager.h (1)
44-44: New PinOwner enum value correctly added.The
DMX_OUTPUT = 0x8Fenum value is unique, follows the established pattern for built-in pin owners (high bit set), and pairs well with the existingDMX_INPUT = 0x8Dentry. The comment clearly identifies its purpose.wled00/wled.cpp (1)
520-520: Initial DMX setup is correct.The pin-based initialization call
initDMXOutput(dmxOutputPin)properly configures DMX during startup. The implementation validates the pin value and handles allocation as shown in dmx_output.cpp.Note: As flagged in set.cpp review, runtime pin changes won't take effect until reboot since there's no reinitialization when settings are updated.
wled00/xml.cpp (1)
463-463: LGTM!The addition of the DMX output pin form value follows the established pattern and is correctly guarded by the WLED_ENABLE_DMX flag.
wled00/wled.h (2)
141-143: LGTM!Clean consolidation of DMX output includes into a single header under the WLED_ENABLE_DMX flag.
453-458: LGTM!Platform-specific DMX implementation selection is appropriate:
- ESP8266 continues to use DMXESPSerial
- Non-ESP8266 targets use the new DMXOutput class
- The dmxOutputPin is correctly initialized to -1 (disabled by default)
wled00/dmx_output.h (1)
1-33: LGTM!The new DMXOutput header provides a clean abstraction for ESP32/non-ESP8266 DMX output:
- Platform-specific includes are correctly guarded
- Public API (init, write, update) is straightforward
- Port selection comment (lines 25-27) helpfully explains the choice of port 1
The static analysis error about
esp_dmx.hnot found is a false positive—this is a platform-specific library that will be available when building for ESP32 targets with the esp_dmx library installed.wled00/data/settings_sync.htm (2)
53-56: LGTM!The
hideNoDMX()function follows the same pattern as the existinghideNoDMXInput()function, providing consistent UI behavior for the DMX output feature toggle.
174-177: LGTM!The new DMX Output section is properly structured with appropriate pin range validation (
min="-1" max="99"), uses tabs for indentation as per coding guidelines, and is conditionally displayed via thehideNoDMX()function.wled00/dmx_output.cpp (1)
69-78: Pin validation and allocation logic looks good.The validation
outputPin < 1correctly rejects invalid pins (including the default -1), and the PinManager integration ensures proper resource tracking. The early return pattern is clean.
| #ifdef WLED_ENABLE_DMX | ||
| if_live_dmx[F("dmxOutputPin")] = dmxOutputPin; | ||
| #endif |
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.
Ensure JSON key matches deserialization.
This serialization block writes dmxOutputPin to the key "dmxOutputPin", but line 601 reads from "outputPin". See the comment on lines 600-602 for details.
🤖 Prompt for AI Agents
In @wled00/cfg.cpp around lines 1124 - 1126, The JSON serialization writes the
DMX pin under "dmxOutputPin" but deserialization expects "outputPin", causing a
mismatch; change the key used when assigning into if_live_dmx (replace
F("dmxOutputPin") with F("outputPin")) in the WLED_ENABLE_DMX serialization
block so the key matches the deserializer that reads "outputPin" (or
alternatively update the deserializer to "dmxOutputPin" if you prefer that name)
and verify the if_live_dmx / dmxOutputPin mapping is consistent.
| DEBUG_PRINTF("DMXOutput: Error: Failed to allocate pin for DMX_OUTPUT. Pin already in use:\n"); | ||
| DEBUG_PRINTF("In use by: %s\n", PinManager::getPinOwner(outputPin)); | ||
| return; |
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.
Format specifier mismatch: getPinOwner() returns an enum, not a string.
PinManager::getPinOwner() returns a PinOwner enum value. Using %s format specifier will cause undefined behavior or garbage output.
🐛 Proposed fix
if (!pinAllocated) {
- DEBUG_PRINTF("DMXOutput: Error: Failed to allocate pin for DMX_OUTPUT. Pin already in use:\n");
- DEBUG_PRINTF("In use by: %s\n", PinManager::getPinOwner(outputPin));
+ DEBUG_PRINTF("DMXOutput: Error: Failed to allocate pin %d for DMX_OUTPUT. Pin already in use (owner: %d)\n", outputPin, (int)PinManager::getPinOwner(outputPin));
return;
}🤖 Prompt for AI Agents
In @wled00/dmx_output.cpp around lines 73 - 75, The DEBUG_PRINTF call is using
"%s" but PinManager::getPinOwner(outputPin) returns a PinOwner enum; change the
code to print the enum correctly by either converting the enum to a string (add
or call a helper like PinOwnerToString/PinManager::getPinOwnerName that returns
const char* and pass that to DEBUG_PRINTF) or print its integer value by using
the correct format specifier (e.g., replace "%s" with "%d" and cast the enum to
int). Update the DEBUG_PRINTF invocation that references PinManager::getPinOwner
so the format specifier matches the provided value.
| void initDMXOutput(){} | ||
| void handleDMXOutput() {} |
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.
Function signature mismatch in #else branch.
When WLED_ENABLE_DMX is not defined, initDMXOutput() has no parameter, but the declaration in fcn_declare.h was updated to initDMXOutput(int outputPin). This will cause compilation errors when DMX is disabled.
🐛 Proposed fix
#else
-void initDMXOutput(){}
+void initDMXOutput(int){}
void handleDMXOutput() {}
#endif🤖 Prompt for AI Agents
In @wled00/dmx_output.cpp around lines 96 - 97, The stub for the disabled-DMX
branch has a mismatched signature: change the no-arg initDMXOutput() to match
the declaration initDMXOutput(int outputPin) so compilation succeeds when
WLED_ENABLE_DMX is not defined; keep handleDMXOutput() as-is, and mark the
unused parameter (outputPin) appropriately (e.g., omit its name or use an
attribute/void cast) to avoid unused-parameter warnings while ensuring the
function signature matches the header.
| #ifdef WLED_ENABLE_DMX | ||
| dmxOutputPin = request->arg(F("IDMO")).toInt(); | ||
| #endif |
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.
Missing runtime handling for DMX output pin changes.
The code accepts the new dmxOutputPin value but doesn't handle runtime pin reallocation or DMX reinitialization. Compare with IR pin handling (lines 255-263) which deallocates the old pin, validates and allocates the new pin, and calls initIR().
For consistency and better UX, consider:
- Deallocating the previous DMX output pin if it was allocated
- Validating and allocating the new pin using PinManager
- Reinitializing DMX with the new pin (or clearly document that reboot is required)
Suggested implementation pattern
#ifdef WLED_ENABLE_DMX
- dmxOutputPin = request->arg(F("IDMO")).toInt();
+ // Deallocate old DMX output pin if allocated
+ if (dmxOutputPin >= 0 && PinManager::isPinAllocated(dmxOutputPin, PinOwner::DMX_OUTPUT)) {
+ PinManager::deallocatePin(dmxOutputPin, PinOwner::DMX_OUTPUT);
+ }
+ int newDmxPin = request->arg(F("IDMO")).toInt();
+ dmxOutputPin = newDmxPin;
+ // Reinitialize DMX output with new pin
+ initDMXOutput(dmxOutputPin);
#endifNote: This assumes initDMXOutput() handles the case where the pin is already allocated or is invalid.
🤖 Prompt for AI Agents
In @wled00/set.cpp around lines 441 - 443, The code stores a new dmxOutputPin
from request->arg(F("IDMO")).toInt() but doesn't reallocate or reinitialize DMX
at runtime; update the handler to mirror the IR logic: if a previous
dmxOutputPin was allocated, release it via PinManager, validate/allocate the new
pin with PinManager (handle invalid/unavailable pins), update the dmxOutputPin
variable, and call initDMXOutput() to reinitialize DMX with the new pin (or
log/report failure). Ensure you reference and update the same symbols:
dmxOutputPin, PinManager (allocate/deallocate), and initDMXOutput() so runtime
pin changes take effect.
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.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In @wled00/dmx_output.cpp:
- Around line 86-88: The write method (DMXOutput::write) writes directly to
dmxdata[channel] without validating channel; add bounds checking to clamp or
reject out-of-range indices (e.g., ensure channel is within the valid DMX
range/array bounds before writing) — use the DMXOutput::write entry point to
either clamp channel to the valid range (minimum 1, maximum the DMX buffer size)
or check against the dmxdata buffer length/channelSize and return early if out
of range so you never index dmxdata with an invalid channel.
- Around line 81-85: The DMXOutput::init function ignores the esp_err_t return
from dmx_driver_install leading to silent failures; mirror the pattern from
dmx_input.cpp by capturing the return value of dmx_driver_install(dmxPort,
&config, DMX_INTR_FLAGS_DEFAULT), check if it is not ESP_OK, log the error with
esp_err_to_name(err) (e.g., via DEBUG_PRINTF or existing logger) mentioning
"DMXOutput: Error installing DMX driver", and return early to avoid further
initialization (do not proceed to dmx_set_pin on error).
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
wled00/dmx_output.cpp
🧰 Additional context used
📓 Path-based instructions (1)
wled00/**/*.cpp
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 2-space indentation for C++ source files (.cpp)
Files:
wled00/dmx_output.cpp
🧠 Learnings (19)
📓 Common learnings
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.
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: 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: DedeHai
Repo: wled/WLED PR: 4798
File: wled00/FX.cpp:7531-7533
Timestamp: 2025-08-26T11:51:21.817Z
Learning: In WLED PR #4798, DedeHai confirmed that certain gamma-related calls in FX.cpp/FX_fcn.cpp/particle systems are intentional for effect-level shaping (e.g., brightness curves, TV sim, Pride 2015 pre-mix), distinct from final output gamma. Do not flag or remove these in future reviews; add comments when feasible to clarify intent.
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-12-28T14:06:48.772Z
Learning: In WLED post-commit ee9ac947, the rendering pipeline uses per-segment buffers and per-pixel bus updates. Unmapped (0xFFFF) mapping entries are now skipped in WS2812FX::show() (no “clear to black”), which can leave physical gap LEDs with stale/random colors unless they are explicitly cleared. This is a behavior change from pre-0.16 where a full physical buffer was effectively refreshed each frame.
📚 Learning: 2025-09-01T10:26:17.959Z
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.
Applied to files:
wled00/dmx_output.cpp
📚 Learning: 2025-08-28T08:09:20.630Z
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.
Applied to files:
wled00/dmx_output.cpp
📚 Learning: 2025-09-16T18:08:42.848Z
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.
Applied to files:
wled00/dmx_output.cpp
📚 Learning: 2025-12-28T14:06:48.772Z
Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-12-28T14:06:48.772Z
Learning: In WLED post-commit ee9ac947, the rendering pipeline uses per-segment buffers and per-pixel bus updates. Unmapped (0xFFFF) mapping entries are now skipped in WS2812FX::show() (no “clear to black”), which can leave physical gap LEDs with stale/random colors unless they are explicitly cleared. This is a behavior change from pre-0.16 where a full physical buffer was effectively refreshed each frame.
Applied to files:
wled00/dmx_output.cpp
📚 Learning: 2025-10-10T18:34:06.550Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4997
File: wled00/e131.cpp:33-44
Timestamp: 2025-10-10T18:34:06.550Z
Learning: In WLED's DDP packet handling (ws.cpp and e131.cpp), only prevent out-of-bounds memory access rather than enforcing DDP spec compliance. Don't check the 1440-byte spec limit—accept out-of-spec packets assuming correct encoding. The bounds check `maxDataIndex = c + numLeds * ddpChannelsPerLed; if (maxDataIndex > dataLen) reject` is sufficient and already covers the timecode flag case (when c=4) without needing separate validation.
Applied to files:
wled00/dmx_output.cpp
📚 Learning: 2025-09-18T03:17:30.107Z
Learnt from: willmmiles
Repo: wled/WLED PR: 4939
File: wled00/FX_fcn.cpp:1183-1194
Timestamp: 2025-09-18T03:17:30.107Z
Learning: In WLED BusManager (wled00/FX_fcn.cpp), direct access to BusManager::busses is part of the intended public API design, not an encapsulation violation. The wrapper accessor methods are considered unnecessary obfuscation that should be removed in future refactoring.
Applied to files:
wled00/dmx_output.cpp
📚 Learning: 2025-11-14T13:37:11.994Z
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.
Applied to files:
wled00/dmx_output.cpp
📚 Learning: 2025-08-26T11:51:21.817Z
Learnt from: DedeHai
Repo: wled/WLED PR: 4798
File: wled00/FX.cpp:7531-7533
Timestamp: 2025-08-26T11:51:21.817Z
Learning: In WLED PR #4798, DedeHai confirmed that certain gamma-related calls in FX.cpp/FX_fcn.cpp/particle systems are intentional for effect-level shaping (e.g., brightness curves, TV sim, Pride 2015 pre-mix), distinct from final output gamma. Do not flag or remove these in future reviews; add comments when feasible to clarify intent.
Applied to files:
wled00/dmx_output.cpp
📚 Learning: 2025-08-21T00:00:17.196Z
Learnt from: willmmiles
Repo: wled/WLED PR: 4859
File: usermods/udp_name_sync/udp_name_sync.cpp:62-70
Timestamp: 2025-08-21T00:00:17.196Z
Learning: In WLED codebase, UDP packet processing code must never rely on null termination being present on the wire and must always validate packet size first. The codebase already has some vulnerabilities where malformed data can crash the software, so avoiding introduction of new ones is a priority.
Applied to files:
wled00/dmx_output.cpp
📚 Learning: 2025-11-14T13:37:30.955Z
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.
Applied to files:
wled00/dmx_output.cpp
📚 Learning: 2025-11-27T06:33:11.436Z
Learnt from: BobLoeffler68
Repo: wled/WLED PR: 5109
File: wled00/FX.cpp:3174-3343
Timestamp: 2025-11-27T06:33:11.436Z
Learning: WLED Ants effect (wled00/FX.cpp): The author prefers the current velocity initialization using hw_random16(1000, 5000)/5000.0f, resulting in an effective range of ~3.6–10.0 (with VELOCITY_MIN=2.0, VELOCITY_MAX=10.0), and wants the code kept as-is with comments updated to document this behavior. Avoid suggesting changes to span the full 2.0–10.0 range in future reviews.
Applied to files:
wled00/dmx_output.cpp
📚 Learning: 2025-12-01T07:01:16.949Z
Learnt from: blazoncek
Repo: wled/WLED PR: 5140
File: wled00/data/settings_time.htm:66-76
Timestamp: 2025-12-01T07:01:16.949Z
Learning: In WLED PR #5134, the fix for macros being initialized with the enable bit set only handles new configurations, not existing ones. If there is a bug in timer/macro handling code (e.g., in settings_time.htm), it must be fixed to work correctly for existing configurations as well.
Applied to files:
wled00/dmx_output.cpp
📚 Learning: 2026-01-03T14:38:09.949Z
Learnt from: DedeHai
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2026-01-03T14:38:09.949Z
Learning: In WLED code reviews, check that FastLED noise function aliases (`inoise8`, `inoise16`, etc.) are not used. These should be replaced with the proper WLED functions (`perlin8`, `perlin16`, etc.) as the `inoise*` functions are only aliases kept for compatibility reasons.
Applied to files:
wled00/dmx_output.cpp
📚 Learning: 2025-09-18T03:17:30.107Z
Learnt from: willmmiles
Repo: wled/WLED PR: 4939
File: wled00/FX_fcn.cpp:1183-1194
Timestamp: 2025-09-18T03:17:30.107Z
Learning: In WLED bus management code, dead code branches in error handling (like unreachable else breaks) are intentionally preserved to accommodate potential future API changes, even when currently unreachable.
Applied to files:
wled00/dmx_output.cpp
📚 Learning: 2025-08-31T03:38:14.114Z
Learnt from: BobLoeffler68
Repo: wled/WLED PR: 4891
File: wled00/FX.cpp:3333-3349
Timestamp: 2025-08-31T03:38:14.114Z
Learning: WLED PacMan effect (wled00/FX.cpp): Keep pacmancharacters_t position fields as signed int (not int16_t). Maintainer preference (blazoncek) prioritizes avoiding potential overhead/regressions over minor RAM savings. Avoid type shrinking here unless memory pressure is demonstrated.
Applied to files:
wled00/dmx_output.cpp
📚 Learning: 2025-08-29T00:26:15.808Z
Learnt from: ksedgwic
Repo: wled/WLED PR: 4883
File: usermods/usermod_v2_skystrip/rest_json_client.h:6-14
Timestamp: 2025-08-29T00:26:15.808Z
Learning: WLED uses a vendored ArduinoJson library (version 6) located at "src/dependencies/json/ArduinoJson-v6.h" which is included through wled.h. Usermods should not directly include ArduinoJson headers but instead rely on wled.h for ArduinoJson symbols. The standard pattern is to include wled.h and use JsonObject, JsonArray, DynamicJsonDocument, etc. without additional includes.
Applied to files:
wled00/dmx_output.cpp
📚 Learning: 2025-08-29T00:26:15.808Z
Learnt from: ksedgwic
Repo: wled/WLED PR: 4883
File: usermods/usermod_v2_skystrip/rest_json_client.h:6-14
Timestamp: 2025-08-29T00:26:15.808Z
Learning: In WLED projects, ArduinoJson.h is not directly included via #include <ArduinoJson.h> - the ArduinoJson symbols are made available through the WLED build system and wled.h transitive includes, so explicitly adding #include <ArduinoJson.h> is not necessary and may not work.
Applied to files:
wled00/dmx_output.cpp
📚 Learning: 2026-01-03T16:42:26.035Z
Learnt from: DedeHai
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2026-01-03T16:42:26.035Z
Learning: In WLED, both parallel I2S and single I2S modes require additional DMA buffers (4× the pixel buffer size). The memory calculation must account for which specific buses use I2S hardware, not just check digitalCount <= 8, because single I2S mode places the I2S bus at the END (ESP32 bus 8 with digitalCount=9, S2 bus 4 with digitalCount=5).
Applied to files:
wled00/dmx_output.cpp
🧬 Code graph analysis (1)
wled00/dmx_output.cpp (1)
wled00/src/dependencies/dmx/ESPDMX.cpp (6)
init(21-28)init(21-21)write(31-36)write(31-31)update(44-60)update(44-44)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: wled_build / Build Environments (usermods)
- GitHub Check: wled_build / Build Environments (nodemcuv2_compat)
- GitHub Check: wled_build / Build Environments (esp32dev)
- GitHub Check: wled_build / Build Environments (esp01_1m_full_160)
🔇 Additional comments (2)
wled00/dmx_output.cpp (2)
2-2: LGTM!The header include is appropriate for the new DMXOutput class functionality.
89-92: LGTM!The
updatemethod correctly writes and sends the DMX packet using the esp_dmx library functions.
| void initDMXOutput(int outputPin) { | ||
| if (outputPin < 1) return; | ||
| const bool pinAllocated = PinManager::allocatePin(outputPin, true, PinOwner::DMX_OUTPUT); | ||
| if (!pinAllocated) { | ||
| DEBUG_PRINTF("DMXOutput: Error: Failed to allocate pin for DMX_OUTPUT. Pin already in use:\n"); | ||
| DEBUG_PRINTF("In use by: %s\n", PinManager::getPinOwner(outputPin)); | ||
| return; | ||
| } | ||
| dmx.init(outputPin); // set output pin and initialize DMX output | ||
| } |
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:
# First, let's look at the full dmx_output.cpp file to understand context
wc -l wled00/dmx_output.cppRepository: wled/WLED
Length of output: 77
🏁 Script executed:
# Read the entire dmx_output.cpp file
cat -n wled00/dmx_output.cppRepository: wled/WLED
Length of output: 3792
🏁 Script executed:
# Search for GPIO 0 usage in the codebase to see if it's considered valid
rg "GPIO 0|pin.*0|outputPin.*0" wled00/ -i -A 2 -B 2 | head -100Repository: wled/WLED
Length of output: 5727
🏁 Script executed:
# Search for similar pin validation patterns with < 1 or < 0
rg "allocatePin|outputPin\s*<|pin\s*<\s*[01]" wled00/ -i -A 3 -B 1Repository: wled/WLED
Length of output: 14357
🏁 Script executed:
# Check for other pin allocation error handling patterns
rg "allocatePin.*false|!pinAllocated" wled00/ -A 3 -B 1Repository: wled/WLED
Length of output: 2285
🏁 Script executed:
# Search for dmx module initialization and pin tracking
rg "dmx\." wled00/dmx_output.cpp -A 1 -B 1Repository: wled/WLED
Length of output: 1104
🏁 Script executed:
# Search for dmxOutputPin or similar variable
rg "dmx.*[Pp]in|dmxOutput" wled00/ -iRepository: wled/WLED
Length of output: 4123
🏁 Script executed:
# Check if there's a global dmx object and how it tracks output pin
rg "class DMXOutput|struct DMXOutput|DMXOutput\s+dmx" wled00/ -B 2 -A 5Repository: wled/WLED
Length of output: 921
🏁 Script executed:
# Look for the dmx object declaration and init function
grep -r "dmx\.init\|DMXOutput dmx" wled00/ --include="*.h" --include="*.cpp"Repository: wled/WLED
Length of output: 191
Change pin validation to allow GPIO 0, which is valid in WLED.
The validation outputPin < 1 on line 70 incorrectly rejects GPIO 0. GPIO 0 is a valid and usable pin in WLED (see BTNPIN definition in wled.h and button allocation patterns in set.cpp), and other pin allocation logic uses >= 0. Change this to if (outputPin < 0) return; to only exclude disabled (-1) and negative values.
Additionally, pin allocation failures only log via DEBUG_PRINTF without updating the dmxOutputPin state. For consistency with other modules (buttons, relay, IR), consider setting dmxOutputPin = -1; before returning on allocation failure.
The error message could also be simplified:
- DEBUG_PRINTF("DMXOutput: Error: Failed to allocate pin for DMX_OUTPUT. Pin already in use:\n");
- DEBUG_PRINTF("In use by: %s\n", PinManager::getPinOwner(outputPin));
+ DEBUG_PRINTF("DMXOutput: Error: Failed to allocate pin %d for DMX_OUTPUT. Already in use by: %s\n",
+ outputPin, PinManager::getPinOwner(outputPin));| void DMXOutput::init(uint8_t outputPin) { | ||
| dmx_config_t config = DMX_CONFIG_DEFAULT; | ||
| dmx_driver_install(dmxPort, &config, DMX_INTR_FLAGS_DEFAULT); | ||
| dmx_set_pin(dmxPort, outputPin, -1, -1); | ||
| } |
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:
# Find esp_dmx related files and configuration
find . -type f -name "*.h" -o -name "*.cpp" | xargs grep -l "esp_dmx\|dmx_driver_install" | head -20Repository: wled/WLED
Length of output: 142
🏁 Script executed:
# Look for library dependency declarations (platformio.ini, package.json, cmake files, etc.)
git ls-files | grep -E "(platformio|package|cmake|requirements)" | head -20Repository: wled/WLED
Length of output: 792
🏁 Script executed:
# Check the full DMXOutput file for context and error handling patterns
wc -l wled00/dmx_output.cppRepository: wled/WLED
Length of output: 77
🏁 Script executed:
# Search for error handling patterns in similar driver initialization
rg "dmx_driver_install|dmx_set_pin" -A 3 -B 3Repository: wled/WLED
Length of output: 1432
🏁 Script executed:
# Check platformio.ini for esp_dmx library version
cat platformio.ini | grep -A 100 "esp_dmx"Repository: wled/WLED
Length of output: 4152
🏁 Script executed:
# Read the full dmx_output.cpp file (99 lines)
cat -n wled00/dmx_output.cppRepository: wled/WLED
Length of output: 3792
🏁 Script executed:
# Read dmx_output.h to understand the class structure and init signature
cat -n wled00/dmx_output.hRepository: wled/WLED
Length of output: 1031
🌐 Web query:
esp_dmx library ESP32 dmx_driver_install return value error handling
💡 Result:
Short answer: dmx_driver_install returns an esp_err_t. Check it against ESP_OK and handle/ log failures (esp_err_to_name()). Common failure codes to expect: ESP_ERR_NO_MEM, ESP_ERR_INVALID_ARG, ESP_ERR_INVALID_STATE, ESP_FAIL (and other generic ESP-IDF codes). Also be aware of known platform issues (e.g. crashes reported when installing on UART2 in some setups). References: esp_dmx README (dmx_driver_install usage), ESP-IDF esp_err docs, and a related esp_dmx issue. [1][2][3]
Sources
- esp_dmx README / usage and install docs. [1]
- ESP-IDF error codes & esp_err_t helpers (ESP_OK, ESP_ERR_NO_MEM, esp_err_to_name(), etc.). [2]
- esp_dmx GitHub issue reporting crash when installing on UART2. [3]
Links:
[1] someweisguy/esp_dmx README (dmx_driver_install usage). (github.com)
[2] ESP-IDF esp_err / error-codes documentation (ESP_OK, esp_err_to_name, common ESP_ERR_*). (docs.espressif.com)
[3] Issue: "Problem with installing DMX on UART2" (esp_dmx). (github.com)
Citations:
- 1: https://github.com/someweisguy/esp_dmx
- 2: https://docs.espressif.com/projects/esp-idf/en/v4.4/esp32/api-reference/system/esp_err.html?utm_source=openai
- 3: Problem with installing DMX on UART2 someweisguy/esp_dmx#150
Add error handling for dmx_driver_install call.
The dmx_driver_install() call returns an esp_err_t and should be checked for errors, similar to the pattern used in dmx_input.cpp. Without error checking, silent driver initialization failures could occur. Add an error check and handle failure cases:
esp_err_t err = dmx_driver_install(dmxPort, &config, DMX_INTR_FLAGS_DEFAULT);
if (err != ESP_OK) {
DEBUG_PRINTF("DMXOutput: Error installing DMX driver: %s\n", esp_err_to_name(err));
return;
}The library version is already pinned to a specific commit in platformio.ini, and the API calls match the library documentation. However, error handling is necessary to handle initialization failures and known platform issues (e.g., UART2 crashes).
🤖 Prompt for AI Agents
In @wled00/dmx_output.cpp around lines 81 - 85, The DMXOutput::init function
ignores the esp_err_t return from dmx_driver_install leading to silent failures;
mirror the pattern from dmx_input.cpp by capturing the return value of
dmx_driver_install(dmxPort, &config, DMX_INTR_FLAGS_DEFAULT), check if it is not
ESP_OK, log the error with esp_err_to_name(err) (e.g., via DEBUG_PRINTF or
existing logger) mentioning "DMXOutput: Error installing DMX driver", and return
early to avoid further initialization (do not proceed to dmx_set_pin on error).
| void DMXOutput::write(uint8_t channel, uint8_t value) { | ||
| dmxdata[channel] = value; | ||
| } |
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.
Add bounds checking to prevent buffer overflow.
The write method directly accesses dmxdata[channel] without validating the channel parameter. This can cause a buffer overflow if an out-of-bounds channel value is passed.
Comparing with the ESPDMX implementation (from wled00/src/dependencies/dmx/ESPDMX.cpp lines 30-35), bounds checking is performed:
if (Channel < 1) Channel = 1;
if (Channel > channelSize) Channel = channelSize;The new implementation should include similar validation.
🔒 Proposed fix to add bounds checking
void DMXOutput::write(uint8_t channel, uint8_t value) {
+ if (channel < 1) channel = 1;
+ if (channel >= DMX_PACKET_SIZE) channel = DMX_PACKET_SIZE - 1;
dmxdata[channel] = value;
}Note: Adjust the bounds check according to the valid channel range for esp_dmx. DMX512 typically uses channels 1-512, with slot 0 reserved for the start code.
🤖 Prompt for AI Agents
In @wled00/dmx_output.cpp around lines 86 - 88, The write method
(DMXOutput::write) writes directly to dmxdata[channel] without validating
channel; add bounds checking to clamp or reject out-of-range indices (e.g.,
ensure channel is within the valid DMX range/array bounds before writing) — use
the DMXOutput::write entry point to either clamp channel to the valid range
(minimum 1, maximum the DMX buffer size) or check against the dmxdata buffer
length/channelSize and return early if out of range so you never index dmxdata
with an invalid channel.
|
Since you are almost fully implementing my PR lol (#5216), I would suggest you add rate limiting as well. Sending more then 44hz of data won't have any advantage, since the DMX standard has that as its max theoretical limit. Right now its called on each loop. I would also suggest to add something like number of fixtures to output, since by default it now assumes each led in a strip corresponds to a DMX fixture (thus most of the time consuming the full DMX universe). Ideally you would specify which strip(s) get outputted to DMX. |
Allow the DMX Output pin to be set at runtime, not need the user to hack around in the source code
Also swap the DMX Output to the same driver as DMX Input, leaving only 8266 to use ESPDMX
Summary by CodeRabbit
New Features
Refactor
✏️ Tip: You can customize this high-level summary in your review settings.