Skip to content

Conversation

@blazoncek
Copy link
Contributor

- helps with #4315
- add-on to #4762
- increases parallel I2S LED limit to 600 per bus
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 9, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@blazoncek
Copy link
Contributor Author

Large led count may need thorough testing with several usermods enabled.
AFAIK minimal free heap is about 50k for AWS to function properly. S2 may struggle with that.

@blazoncek
Copy link
Contributor Author

@coderabbitai please review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 9, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

I'll examine the PR changes to provide a comprehensive review.


🏁 Script executed:

#!/bin/bash
# Get PR information including title, description, and changed files
gh pr view 4763 --repo wled/WLED --json title,body,files,additions,deletions,changedFiles

# Get the actual diff to understand the changes
gh pr diff 4763 --repo wled/WLED

Length of output: 8934


@blazoncek Here's my review of PR #4763:

Summary

This PR implements two main changes:

  1. Mixed LED type detection: Prevents parallel I2S when different digital LED types are used on different buses
  2. LED limit increase: Raises the parallel I2S LED limit from 300 to 600 per bus

Technical Analysis

Good Changes

Mixed bus type detection (FX_fcn.cpp):

if (busType == 0) busType = bus.type; // remember first bus type
if (busType != bus.type) {
  DEBUG_PRINTF_P(PSTR("Mixed digital bus types detected! Forcing single I2S output.\n"));
  useParallelI2S = false; // mixed bus types, no parallel I2S
}

This is a solid safety measure that prevents potential issues with mixed LED types.

Scope fix: Moving digitalCount = 0; after the parallel I2S decision logic is correct.

JavaScript refactoring: The new helper functions (is8266(), is32(), isS2(), isS3()) improve code readability and maintainability.

⚠️ Memory Concerns

LED limit increase (300 → 600):
Your concerns about memory usage are very valid. With the limit doubled:

  • Worst case: 600 LEDs × 4 bytes (RGBW) × multiple buses = potentially 9.6kB+ per bus
  • ESP32-S2: Already memory-constrained, this could push it over the edge
  • With usermods: Additional memory pressure from AudioReactive, Matrix, etc.

Calculation example:

600 LEDs × 4 bytes × 8 buses = 19.2kB just for LED buffers
+ NeoPixelBus internal buffers
+ WLED core functionality 
+ Usermods (AudioReactive ~8kB, Matrix buffers, etc.)

This could easily exceed your 50kB free heap threshold for AWS functionality.

🔍 Recommendations

  1. Platform-specific limits: Consider different LED limits per platform:

    #ifdef CONFIG_IDF_TARGET_ESP32S2
    #define MAX_PARALLEL_I2S_LEDS 300  // Keep conservative for S2
    #else
    #define MAX_PARALLEL_I2S_LEDS 600  // Allow higher for ESP32
    #endif
  2. Memory estimation: Add runtime memory estimation before enabling parallel I2S:

    unsigned estimatedMemory = maxLedsOnBus * 4 * digitalCount + overhead;
    if (estimatedMemory > availableMemory * 0.7) useParallelI2S = false;
  3. Testing matrix: Given your concerns, thorough testing needed with:

    • Large LED counts (500+ per bus)
    • Multiple usermods enabled (AudioReactive + Matrix + others)
    • ESP32-S2 specifically
    • AWS connectivity under memory pressure
  4. Runtime monitoring: Consider adding heap monitoring that can dynamically disable parallel I2S if memory gets too low.

The core logic changes are sound, but the LED limit increase needs careful validation against the memory constraints you've identified, especially for S2 boards with usermods enabled.


🧠 Learnings used
Learnt from: blazoncek
PR: wled/WLED#4667
File: usermods/user_fx/user_fx.cpp:27-30
Timestamp: 2025-04-30T05:41:03.633Z
Learning: In WLED, the Segment::allocateData() method already includes optimization to check if data is allocated and sufficiently sized, handling buffer reuse to reduce memory fragmentation. Adding an external check like `if (SEGENV.data == nullptr && !SEGENV.allocateData(dataSize))` is unnecessary and could be problematic, as it bypasses proper size verification.

Learnt from: blazoncek
PR: wled/WLED#4658
File: wled00/const.h:140-141
Timestamp: 2025-04-26T19:19:07.600Z
Learning: In WLED, the WLED_MAX_PANELS macro is intentionally defined as a fixed constant value (18) with no redefinition mechanism, making it "unoverridable" - there's no need for a static assertion to check its maximum value.

Learnt from: blazoncek
PR: wled/WLED#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: willmmiles
PR: wled/WLED#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.

Learnt from: DedeHai
PR: wled/WLED#4682
File: wled00/FX.cpp:9016-9039
Timestamp: 2025-05-09T18:48:21.296Z
Learning: WLED does not support matrices large enough (≥1024 px) for 32-bit overflow in dx*dx + dy*dy to be a practical concern in particle system effects.

Learnt from: blazoncek
PR: wled/WLED#4482
File: wled00/udp.cpp:147-149
Timestamp: 2025-02-19T12:43:34.200Z
Learning: In WLED, maximum segment name length varies by platform:
- ESP8266: 32 characters (WLED_MAX_SEGNAME_LEN = 32)
- ESP32: 64 characters (WLED_MAX_SEGNAME_LEN = 64)
This platform difference can cause truncation when syncing longer names from ESP32 to ESP8266. Additionally, the WLED UI has limitations regarding modified maximum segment name lengths.

Learnt from: DedeHai
PR: wled/WLED#4750
File: usermods/audioreactive/audio_reactive.cpp:311-321
Timestamp: 2025-06-27T06:04:44.652Z
Learning: In WLED's AudioReactive usermod, FFT buffer memory (valFFT, windowFFT) is allocated once during initialization and never deallocated, following typical embedded system design where core functionality buffers persist for the application lifetime. Raw buffer pointers for aligned allocations don't need to be tracked in the current implementation since deallocation is never performed.

@netmindz
Copy link
Member

would we also want to merge this into main @blazoncek ?

@Arcitec
Copy link
Contributor

Arcitec commented Jul 10, 2025

@netmindz

  • Disabling parallel I2S when different LED chips are mixed looks like a correct change.
  • If there's any doubt, that change could be extracted into a separate PR and merged separately since it looks like a good and easily verifiable change.
  • The code that increases LED limit and changes the "memory usage algorithm" is confusing. The most confusing part is the new Javascript functions (such as is32() and isS2()) which analyzes some limits to try to detect the board model. Is there any better way to detect the board model from Javascript?
  • Increasing the LED limit might still cause memory overflows on some chips. Probably not though. Blaz thinks that memory overflow might only be a problem on ESP32-S2.

@blazoncek
Copy link
Contributor Author

@netmindz yes

@Arcitec
Copy link
Contributor

Arcitec commented Jul 11, 2025

I have now ran a local test with WLED 0_15_x branch with a custom backport of all of these latest fixes:

  • Blaz's fix for the I2S color conversion bug: 232dc04
  • Will's change which makes Parallel I2S the default instead of RMT: bus_wrapper: Use parallel I2S first when enabled #4762
  • Blaz's PR (this one) which disables Parallel I2S if the output channels use different LED ICs, and also raises the Parallel I2S LED IC limit from 300 to 600 and changes the LED Settings HTML page to calculate and detect chips differently.
image

Test Results:

  • The test was done on a ESP32-WROOM-32E(16MB).
  • LED outputs are on GPIO 16, 12, 4, 2.
  • I tested all outputs and they all display correct colors without any flickering.

I also had a second look at the LED Settings HTML changes of this PR. I see now that it receives the limit from an API call and then looks at the Max Analog, Max Digital and Max Virtual bus counts to identify the chip type.

That solution works, but if those limits ever change, there's a risk of subtle bugs in the future where someone may forget to also change the chip identification in settings_leds.htm. Then the chip can be subtly misidentified. One of the variables is even dynamic in the code: #define WLED_MAX_ANALOG_CHANNELS (LEDC_CHANNEL_MAX*LEDC_SPEED_MODE_MAX). Sure, it's not likely that they will change, but it's still a bit risky to look directly at changeable parameters from a different file to identify chips.

I think that part of the code should be changed to add a backend API change which returns the chip as a string, such as "ESP32", "ESP8266", "ESP32-C3" etc, by putting the chip "ID/name" in a #define string on the backend whose contents is based on the compile-flags such as CONFIG_IDF_TARGET_ESP32S2.

And then make the backend settings API return that string in the "get current settings" response.

And then change settings_leds.htm from this:

		function is8266() { return maxA ==  5 && maxD ==  3; } // NOTE: see const.h
		function is32()   { return maxA == 16 && maxD == 16; } // NOTE: see const.h
		function isC3()   { return maxA ==  6 && maxD ==  2; } // NOTE: see const.h
		function isS2()   { return maxA ==  8 && maxD == 12 && maxV == 4; } // NOTE: see const.h
		function isS3()   { return maxA ==  8 && maxD == 12 && maxV == 6; } // NOTE: see const.h

To this:

		function is8266() { return chipType === "ESP8266"; }
		function is32()   { return chipType === "ESP32"; }
		function isC3()   { return chipType === "ESP32-C3"; }
		function isS2()   { return chipType === "ESP32-S2"; }
		function isS3()   { return chipType === "ESP32-S3"; }

Other than that part, I think everything here looks very good. Thank you Blaz for being such an amazing dude and amazing developer. ❤️

However, I am not able to test the memory limits to check for overflows with huge amounts of LEDs and many usermods. Is that only likely to be a problem on ESP32-S2 with many usermods enabled at the same time, though?

@blazoncek blazoncek merged commit 39f3c99 into 0_15_x Jul 16, 2025
38 checks passed
blazoncek added a commit that referenced this pull request Jul 22, 2025
Prevent parallel I2S use if different LED types are used.
@blazoncek blazoncek deleted the fix-parallel-i2s-selection branch July 22, 2025 09:19
@willmmiles willmmiles added this to the 0.15.1 Bugfix release milestone Jul 26, 2025
Pluto1010 pushed a commit to Pluto1010/WLED that referenced this pull request Sep 1, 2025
Prevent parallel I2S use if different LED types are used.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants