Skip to content

Update user_fx usermod README.md #4754

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

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open

Conversation

danewhero
Copy link

@danewhero danewhero commented Jun 30, 2025

Updating README for upcoming user_fx usermod.
(I had another PR open but in trying to resolve merge conflicts, I accidently closed it. That previous PR can be found here for reference.)

From my perspective, the last thing(s) to add here are:

  • my contact information (still debating whether I'm good enough with this to be able to deeply help another person, as I'm relatively new to C++), and
  • filling out the table of helpful functions and variables etc.

Summary by CodeRabbit

  • Documentation
    • Expanded the README for the user_fx usermod into a comprehensive tutorial and reference guide, including detailed explanations, code examples, and step-by-step walkthroughs for creating and registering custom WLED effects.

Copy link
Contributor

coderabbitai bot commented Jun 30, 2025

Walkthrough

The README documentation for the user_fx usermod was extensively rewritten and expanded. The update transforms the file from a brief description into a comprehensive tutorial and reference, detailing the structure, usage, and implementation of custom WLED effects within the usermod, including code examples, metadata explanations, and instructions for combining multiple effects.

Changes

File(s) Change Summary
usermods/user_fx/README.md Replaced brief description with a detailed tutorial and reference guide on creating WLED effects, including effect structure, example walkthroughs, metadata format, and multi-effect registration instructions

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Possibly related PRs

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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 generate unit tests to generate unit tests for 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.

@danewhero
Copy link
Author

@coderabbitai review

Copy link
Contributor

coderabbitai bot commented Jun 30, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
usermods/user_fx/README.md (2)

3-6: Correct intro typos & tighten wording

Grammar and spelling mistakes diminish the authority of the doc (e.g. “depracated”, informal “mess with”).
Proposed fix:

-This Usermod is a common place to put various user's WLED Effects.  It gives you a way to load in your own custom WLED effects, or to load in depracated WLED effects that you want to bring back--all without having to mess with the core WLED source code.
+This usermod is a common place to host custom WLED effects. It lets you load your own effects—or revive deprecated ones—without modifying the WLED core.

Also consider lower-casing “Effects” here and on line 5 for consistency with the rest of the doc.


470-478: Minor grammar corrections in “Combining Multiple Effects” section

-So now let's say that you wanted add the effects  "Diffusion Fire" and "Sinelon" through this same Usermod file:
+Suppose you want to add both “Diffusion Fire” and “Sinelon” through the same usermod file:

Also replace “different than” (l 474) → “different from”.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7b0075d and b656567.

📒 Files selected for processing (1)
  • usermods/user_fx/README.md (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: netmindz
PR: wled/WLED#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.
Learnt from: netmindz
PR: wled/WLED#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.
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.
usermods/user_fx/README.md (4)
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: netmindz
PR: wled/WLED#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.
Learnt from: netmindz
PR: wled/WLED#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.
Learnt from: KrX3D
PR: wled/WLED#4237
File: usermods/INA219_v2/INA219_v2.cpp:265-276
Timestamp: 2025-04-18T22:27:58.634Z
Learning: When implementing MQTT message handling in WLED usermods, use `strstr(topic, "/specific/path")` instead of `strcmp_P(topic, PSTR("/specific/path"))` to properly match topics that include the device prefix. The full MQTT topic typically follows the pattern `<mqttDeviceTopic>/specific/path`.
🪛 LanguageTool
usermods/user_fx/README.md

[style] ~20-~20: Consider removing “of” to be more concise
Context: ...area is where you place the FX code for all of the custom effects you want to use. This m...

(ALL_OF_THE)


[style] ~22-~22: As a shorter alternative for ‘able to’, consider using “can”.
Context: ...mods have to be registered so that they are able to be compiled into your binary. We will ...

(BE_ABLE_TO)


[style] ~22-~22: Avoid the passive voice after ‘to be able to’.
Context: ... be registered so that they are able to be compiled into your binary. We will go into grea...

(ABLE_TO_PASSIVE)


[uncategorized] ~33-~33: You might be missing the article “the” here.
Context: ...elColor()` 4. The function is called at current frame rate. Below are some helpful var...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[uncategorized] ~43-~43: You might be missing the article “a” here.
Context: ...be changed at any time if the user sets new segment size(s). | | SEGCOLOR(x) ...

(AI_EN_LECTOR_MISSING_DETERMINER_A)


[uncategorized] ~44-~44: You might be missing the article “the” here.
Context: ...??? | Gets user-selected colors from UI, where x is an integer 1, 2, or 3 fr pr...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[uncategorized] ~47-~47: Possible missing comma found.
Context: ... | Easy way to specify a Palette. This function which should be favoured over `ColorFro...

(AI_HYDRA_LEO_MISSING_COMMA)


[typographical] ~57-~57: It appears that a comma is missing.
Context: ... Understanding 2D WLED Effects In this section we give some advice to those who are ne...

(DURING_THAT_TIME_COMMA)


[uncategorized] ~61-~61: Use a comma before ‘and’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...le. This file handles all other imports and it has all the global variable declarat...

(COMMA_COMPOUND_SENTENCE)


[uncategorized] ~77-~77: Possible missing comma found.
Context: ...lock contains several constant variable definitions which essentially serve to extract the ...

(AI_HYDRA_LEO_MISSING_COMMA)


[misspelling] ~98-~98: Nonstandard phrase. Did you mean: “from 0 to 255”?
Context: ...MENT.speed (user-controllable parameter from 0–255) to a value between 20 and 80 Hz. * T...

(FROM_X_Y)


[uncategorized] ~100-~100: Possible missing comma found.
Context: ...gher speed = more frames per second). * Next we convert refresh rate from Hz to mill...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~100-~100: You might be missing the article “the” here.
Context: ...e frames per second). * Next we convert refresh rate from Hz to milliseconds. (It’s eas...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[uncategorized] ~104-~104: Possible missing comma found.
Context: ...re diffusion = smoother flame spread. * Next we assign SEGMENT.intensity (user inp...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~126-~126: You might be missing the article “the” here.
Context: ...nd the effect can’t proceed. * It calls previously defined mode_static() fallback effect...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[uncategorized] ~155-~155: The preposition “of” seems more likely in this position.
Context: ...conditional statement in the first line fo code ensures the effect updates on a fi...

(AI_EN_LECTOR_REPLACEMENT_PREPOSITION)


[uncategorized] ~173-~173: Possible missing preposition found.
Context: ...whether we even attempt to spawn sparks this frame. * hw_random8() gives a rando...

(AI_HYDRA_LEO_MISSING_IN)


[uncategorized] ~204-~204: Possible missing article found.
Context: ...Starting with the current heat value of pixel (x, y) assigned v: * if there’s a p...

(AI_HYDRA_LEO_MISSING_A)


[uncategorized] ~229-~229: Possible missing comma found.
Context: ... color-rendering for each pixel row.) * Next we update the main segment data with th...

(AI_HYDRA_LEO_MISSING_COMMA)


[grammar] ~231-~231: Use the plural noun “” with the number ‘255’.
Context: ...olor` from the current palette with 255 brightness, and no wrapping in palette lookup. *...

(IN_CD_PUNCTUATION)


[typographical] ~233-~233: Consider adding a comma after ‘Finally’ for more clarity.
Context: ... flames (e.g., yellow → red → black). * Finally we set the rendered color for the pixel...

(RB_LY_COMMA)


[grammar] ~235-~235: The word “fallback” is a noun. The verb is spelled with a space.
Context: ...h row. * If palette use is disabled, we fallback to fading a base color. * SEGCOLOR(0)...

(NOUN_VERB_CONFUSION)


[grammar] ~256-~256: Did you mean the adverb/preposition “within”?
Context: ...ines how the effect is to be interacted with in the UI: ```cpp static const char data...

(WITH_IN)


[typographical] ~283-~283: The word “otherwise” is an adverb that can’t be used like a conjunction, and therefore needs to be separated from the sentence.
Context: ...s is enabled, the effect uses a palette ColorFromPalette(), otherwise it fades from SEGCOLOR(0). The first...

(THUS_SENTENCE)


[style] ~285-~285: ‘in conjunction with’ might be wordy. Consider a shorter alternative.
Context: ...s to be selected by the user. But used in conjunction with the checkbox argument, palette use can ...

(EN_WORDINESS_PREMIUM_IN_CONJUNCTION_WITH)


[uncategorized] ~301-~301: You might be missing the article “a” here.
Context: ... line of code defines sinelon base as static helper function. This is how all effec...

(AI_EN_LECTOR_MISSING_DETERMINER_A)


[uncategorized] ~333-~333: Loose punctuation mark.
Context: ...2_t color2 = SEGCOLOR(2); ``` * color1: main moving dot color, chosen from pale...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~333-~333: You might be missing the article “a” here.
Context: ...r1`: main moving dot color, chosen from palette using the current position as index. * ...

(AI_EN_LECTOR_MISSING_DETERMINER_A)


[uncategorized] ~334-~334: Loose punctuation mark.
Context: ...he current position as index. * color2: secondary color from user-configured co...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~336-~336: This word is normally spelled with a hyphen.
Context: ... account the optional argument for if a Rainbow colored palette is in use: ```cpp if (rainbow...

(RAINBOW_COLORED)


[style] ~350-~350: ‘takes into account’ might be wordy. Consider a shorter alternative.
Context: ...with the selected color. The next line takes into account another one of the optional arguments f...

(EN_WORDINESS_PREMIUM_TAKES_INTO_ACCOUNT)


[uncategorized] ~350-~350: Possible missing comma found.
Context: ...ect to potentially handle dual mirrored dots which create the animation: ```cpp if...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~360-~360: You might be missing the article “the” here.
Context: ...If color2 is not set (0), fallback to same palette color as color1. * In `rain...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[uncategorized] ~380-~380: You might be missing the article “the” here.
Context: ...pos; } ``` * The first line checks if current position has changed since last frame. ...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[grammar] ~380-~380: The verb form ‘has’ does not seem to match the subject ‘checks’.
Context: ...e first line checks if current position has changed since last frame. (Prevents ho...

(SUBJECT_VERB_AGREEMENT_PLURAL)


[uncategorized] ~380-~380: You might be missing the article “the” here.
Context: ...s if current position has changed since last frame. (Prevents holes if the dot move...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[uncategorized] ~381-~381: You might be missing the article “a” here.
Context: ....aux0) and new position (pos) to ensure smooth continuous trail. * Works in both dir...

(AI_EN_LECTOR_MISSING_DETERMINER_A)


[uncategorized] ~449-~449: Possible missing comma found.
Context: ...important one that registers the custom effect so WLED knows about it. * 255: Tempor...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~452-~452: Loose punctuation mark.
Context: ...ction. * _data_FX_MODE_DIFFUSIONFIRE: Metadata string stored in PROGMEM, desc...

(UNLIKELY_OPENING_PUNCTUATION)


[grammar] ~472-~472: The verb “add” needs to be in the to-infinitive form.
Context: ...this Usermod So now let's say that you wanted add the effects "Diffusion Fire" and "Sine...

(MISSING_TO_BEFORE_A_VERB)


[style] ~474-~474: Did you mean ‘different from’? ‘Different than’ is often considered colloquial style.
Context: ...ell--and to name it something different than what's already inside the core WLED cod...

(DIFFERENT_THAN)


[duplication] ~478-~478: Possible typo: you repeated a word.
Context: ... Usermod class. * Compile the code! ## Compiling Compiling WLED yourself is beyond the scope of th...

(ENGLISH_WORD_REPEAT_RULE)

🪛 markdownlint-cli2 (0.17.2)
usermods/user_fx/README.md

39-39: Table pipe style
Expected: leading_and_trailing; Actual: leading_only; Missing trailing pipe

(MD055, table-pipe-style)


264-264: Hard tabs
Column: 12

(MD010, no-hard-tabs)


266-266: Hard tabs
Column: 5

(MD010, no-hard-tabs)


267-267: Hard tabs
Column: 5

(MD010, no-hard-tabs)


268-268: Hard tabs
Column: 5

(MD010, no-hard-tabs)


269-269: Hard tabs
Column: 5

(MD010, no-hard-tabs)


270-270: Hard tabs
Column: 5

(MD010, no-hard-tabs)


271-271: Hard tabs
Column: 12

(MD010, no-hard-tabs)


272-272: Hard tabs
Column: 5

(MD010, no-hard-tabs)


273-273: Hard tabs
Column: 5

(MD010, no-hard-tabs)

🔇 Additional comments (1)
usermods/user_fx/README.md (1)

258-288: Fix hard-tabs & pipe style to satisfy markdownlint

MD010 (no-hard-tabs) and MD055 (table-pipe-style) are triggered here. Use spaces instead of \t and close the table with a trailing pipe:

-| "Diffusion Fire@!      | Name.  (The @ symbol marks the end of the Effect Name, and the begining of the Parameter String elements.) |
-| !, | Use default UI entry; for the first space, this will automatically create a slider for Speed |
+| "Diffusion Fire@!"      | Name.  (The `@` marks the end of the effect name and the start of the parameter list.) |
+| `!,`                    | Use default UI entry; for the first slot this automatically creates a speed slider. |

Apply the same spacing & trailing-pipe fix to every row.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
usermods/user_fx/README.md (1)

37-48: “???” placeholders still present in Size column

The earlier review asked to replace these placeholders with actual units (e.g., uint8_t, bytes, milliseconds) or drop the column. They remain unchanged.

Please resolve to avoid shipping unfinished docs.
(Original feedback already given; still applies.)

🧹 Nitpick comments (6)
usermods/user_fx/README.md (6)

3-6: Fix spelling + remove stray link line

  • “depracated” → deprecated
  • Line 6 is an orphan URL that renders as plain text – it should be deleted (the bullets below already provide working TOC links).
-This Usermod is a common place to put various user's WLED Effects.  It gives you a way to load in your own custom WLED effects, or to load in depracated WLED effects that you want to bring back--all without having to mess with the core WLED source code.
+This usermod is a common place to put various users’ WLED effects. It lets you load your own custom effects, or bring back deprecated ones, without touching the core WLED source code.
-
-./README.md#how-the-usermod-works

24-25: Typo: “abour” → “about”

-We will go into greater detail on how custom effects work in the usermod and how to go abour creating your own in the section below.
+We will go into greater detail on how custom effects work in the usermod and how to go about creating your own in the section below.

37-48: Table formatting fails markdown-lint (MD055)

Each row needs a trailing pipe (|) for consistent pipe style:

-| Syntax Element                                  | Size   | Description |
+| Syntax Element                                  | Size   | Description |

…and so on for every row in this table.

Also consider aligning the header/rows for readability once the “???” values are fixed.


264-274: Hard tabs inside table – breaks rendering

Tabs are used between the columns, triggering markdownlint MD010. Replace with single spaces:

-| Parameter	| Default tooltip label |
-| sx	       | Effect speed |
+| Parameter | Default tooltip label |
+| sx        | Effect speed |

Repeat for all rows in this block.


295-296: Typo: “tep by step”

-we will break this effect down tep by step.
+We will break this effect down step by step.

459-463: Spelling: “instatiation” → “instantiation”

-The final part of this file handles instatiation and initialization:
+The final part of this file handles instantiation and initialization:
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b656567 and 1e6a992.

📒 Files selected for processing (1)
  • usermods/user_fx/README.md (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: netmindz
PR: wled/WLED#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.
Learnt from: netmindz
PR: wled/WLED#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.
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.
usermods/user_fx/README.md (4)
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: netmindz
PR: wled/WLED#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.
Learnt from: netmindz
PR: wled/WLED#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.
Learnt from: KrX3D
PR: wled/WLED#4237
File: usermods/INA219_v2/INA219_v2.cpp:265-276
Timestamp: 2025-04-18T22:27:58.634Z
Learning: When implementing MQTT message handling in WLED usermods, use `strstr(topic, "/specific/path")` instead of `strcmp_P(topic, PSTR("/specific/path"))` to properly match topics that include the device prefix. The full MQTT topic typically follows the pattern `<mqttDeviceTopic>/specific/path`.
🪛 LanguageTool
usermods/user_fx/README.md

[style] ~20-~20: Consider removing “of” to be more concise
Context: ...area is where you place the FX code for all of the custom effects you want to use. This m...

(ALL_OF_THE)


[style] ~22-~22: As a shorter alternative for ‘able to’, consider using “can”.
Context: ...mods have to be registered so that they are able to be compiled into your binary. We will ...

(BE_ABLE_TO)


[style] ~22-~22: Avoid the passive voice after ‘to be able to’.
Context: ... be registered so that they are able to be compiled into your binary. We will go into grea...

(ABLE_TO_PASSIVE)


[uncategorized] ~33-~33: You might be missing the article “the” here.
Context: ...elColor()` 4. The function is called at current frame rate. Below are some helpful var...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[uncategorized] ~43-~43: You might be missing the article “a” here.
Context: ...be changed at any time if the user sets new segment size(s). | | SEGCOLOR(x) ...

(AI_EN_LECTOR_MISSING_DETERMINER_A)


[uncategorized] ~44-~44: You might be missing the article “the” here.
Context: ...??? | Gets user-selected colors from UI, where x is an integer 1, 2, or 3 fr pr...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[uncategorized] ~47-~47: Possible missing comma found.
Context: ... | Easy way to specify a Palette. This function which should be favoured over `ColorFro...

(AI_HYDRA_LEO_MISSING_COMMA)


[typographical] ~57-~57: It appears that a comma is missing.
Context: ... Understanding 2D WLED Effects In this section we give some advice to those who are ne...

(DURING_THAT_TIME_COMMA)


[uncategorized] ~61-~61: Use a comma before ‘and’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...le. This file handles all other imports and it has all the global variable declarat...

(COMMA_COMPOUND_SENTENCE)


[uncategorized] ~77-~77: Possible missing comma found.
Context: ...lock contains several constant variable definitions which essentially serve to extract the ...

(AI_HYDRA_LEO_MISSING_COMMA)


[misspelling] ~98-~98: Nonstandard phrase. Did you mean: “from 0 to 255”?
Context: ...MENT.speed (user-controllable parameter from 0–255) to a value between 20 and 80 Hz. * T...

(FROM_X_Y)


[uncategorized] ~100-~100: Possible missing comma found.
Context: ...gher speed = more frames per second). * Next we convert refresh rate from Hz to mill...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~100-~100: You might be missing the article “the” here.
Context: ...e frames per second). * Next we convert refresh rate from Hz to milliseconds. (It’s eas...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[uncategorized] ~104-~104: Possible missing comma found.
Context: ...re diffusion = smoother flame spread. * Next we assign SEGMENT.intensity (user inp...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~126-~126: You might be missing the article “the” here.
Context: ...nd the effect can’t proceed. * It calls previously defined mode_static() fallback effect...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[uncategorized] ~155-~155: The preposition “of” seems more likely in this position.
Context: ...conditional statement in the first line fo code ensures the effect updates on a fi...

(AI_EN_LECTOR_REPLACEMENT_PREPOSITION)


[uncategorized] ~173-~173: Possible missing preposition found.
Context: ...whether we even attempt to spawn sparks this frame. * hw_random8() gives a rando...

(AI_HYDRA_LEO_MISSING_IN)


[uncategorized] ~204-~204: Possible missing article found.
Context: ...Starting with the current heat value of pixel (x, y) assigned v: * if there’s a p...

(AI_HYDRA_LEO_MISSING_A)


[uncategorized] ~229-~229: Possible missing comma found.
Context: ... color-rendering for each pixel row.) * Next we update the main segment data with th...

(AI_HYDRA_LEO_MISSING_COMMA)


[grammar] ~231-~231: Use the plural noun “” with the number ‘255’.
Context: ...olor` from the current palette with 255 brightness, and no wrapping in palette lookup. *...

(IN_CD_PUNCTUATION)


[typographical] ~233-~233: Consider adding a comma after ‘Finally’ for more clarity.
Context: ... flames (e.g., yellow → red → black). * Finally we set the rendered color for the pixel...

(RB_LY_COMMA)


[grammar] ~235-~235: The word “fallback” is a noun. The verb is spelled with a space.
Context: ...h row. * If palette use is disabled, we fallback to fading a base color. * SEGCOLOR(0)...

(NOUN_VERB_CONFUSION)


[grammar] ~256-~256: Did you mean the adverb/preposition “within”?
Context: ...ines how the effect is to be interacted with in the UI: ```cpp static const char data...

(WITH_IN)


[typographical] ~283-~283: The word “otherwise” is an adverb that can’t be used like a conjunction, and therefore needs to be separated from the sentence.
Context: ...s is enabled, the effect uses a palette ColorFromPalette(), otherwise it fades from SEGCOLOR(0). The first...

(THUS_SENTENCE)


[style] ~285-~285: ‘in conjunction with’ might be wordy. Consider a shorter alternative.
Context: ...s to be selected by the user. But used in conjunction with the checkbox argument, palette use can ...

(EN_WORDINESS_PREMIUM_IN_CONJUNCTION_WITH)


[uncategorized] ~301-~301: You might be missing the article “a” here.
Context: ... line of code defines sinelon base as static helper function. This is how all effec...

(AI_EN_LECTOR_MISSING_DETERMINER_A)


[uncategorized] ~333-~333: Loose punctuation mark.
Context: ...2_t color2 = SEGCOLOR(2); ``` * color1: main moving dot color, chosen from pale...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~333-~333: You might be missing the article “a” here.
Context: ...r1`: main moving dot color, chosen from palette using the current position as index. * ...

(AI_EN_LECTOR_MISSING_DETERMINER_A)


[uncategorized] ~334-~334: Loose punctuation mark.
Context: ...he current position as index. * color2: secondary color from user-configured co...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~336-~336: This word is normally spelled with a hyphen.
Context: ... account the optional argument for if a Rainbow colored palette is in use: ```cpp if (rainbow...

(RAINBOW_COLORED)


[style] ~350-~350: ‘takes into account’ might be wordy. Consider a shorter alternative.
Context: ...with the selected color. The next line takes into account another one of the optional arguments f...

(EN_WORDINESS_PREMIUM_TAKES_INTO_ACCOUNT)


[uncategorized] ~350-~350: Possible missing comma found.
Context: ...ect to potentially handle dual mirrored dots which create the animation: ```cpp if...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~360-~360: You might be missing the article “the” here.
Context: ...If color2 is not set (0), fallback to same palette color as color1. * In `rain...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[uncategorized] ~380-~380: You might be missing the article “the” here.
Context: ...pos; } ``` * The first line checks if current position has changed since last frame. ...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[grammar] ~380-~380: The verb form ‘has’ does not seem to match the subject ‘checks’.
Context: ...e first line checks if current position has changed since last frame. (Prevents ho...

(SUBJECT_VERB_AGREEMENT_PLURAL)


[uncategorized] ~380-~380: You might be missing the article “the” here.
Context: ...s if current position has changed since last frame. (Prevents holes if the dot move...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[uncategorized] ~381-~381: You might be missing the article “a” here.
Context: ....aux0) and new position (pos) to ensure smooth continuous trail. * Works in both dir...

(AI_EN_LECTOR_MISSING_DETERMINER_A)


[uncategorized] ~449-~449: Possible missing comma found.
Context: ...important one that registers the custom effect so WLED knows about it. * 255: Tempor...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~452-~452: Loose punctuation mark.
Context: ...ction. * _data_FX_MODE_DIFFUSIONFIRE: Metadata string stored in PROGMEM, desc...

(UNLIKELY_OPENING_PUNCTUATION)


[grammar] ~472-~472: The verb “add” needs to be in the to-infinitive form.
Context: ...this Usermod So now let's say that you wanted add the effects "Diffusion Fire" and "Sine...

(MISSING_TO_BEFORE_A_VERB)


[style] ~474-~474: Did you mean ‘different from’? ‘Different than’ is often considered colloquial style.
Context: ...ell--and to name it something different than what's already inside the core WLED cod...

(DIFFERENT_THAN)


[duplication] ~478-~478: Possible typo: you repeated a word.
Context: ... Usermod class. * Compile the code! ## Compiling Compiling WLED yourself is beyond the scope of th...

(ENGLISH_WORD_REPEAT_RULE)

🪛 markdownlint-cli2 (0.17.2)
usermods/user_fx/README.md

39-39: Table pipe style
Expected: leading_and_trailing; Actual: leading_only; Missing trailing pipe

(MD055, table-pipe-style)


264-264: Hard tabs
Column: 12

(MD010, no-hard-tabs)


266-266: Hard tabs
Column: 5

(MD010, no-hard-tabs)


267-267: Hard tabs
Column: 5

(MD010, no-hard-tabs)


268-268: Hard tabs
Column: 5

(MD010, no-hard-tabs)


269-269: Hard tabs
Column: 5

(MD010, no-hard-tabs)


270-270: Hard tabs
Column: 5

(MD010, no-hard-tabs)


271-271: Hard tabs
Column: 12

(MD010, no-hard-tabs)


272-272: Hard tabs
Column: 5

(MD010, no-hard-tabs)


273-273: Hard tabs
Column: 5

(MD010, no-hard-tabs)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
usermods/user_fx/README.md (1)

37-55: Table still contains placeholders and minor typos

The “Size” column is still filled with ???, and there are a few spelling issues inside the descriptions (vriables, Fuction, RBG).
This was already flagged in a previous review but hasn’t been addressed.

-| `SEGMENT.setPixelColor / setPixelColorXY`       | ---    | Fuction that paints a single pixel to your specified color.  `setPixelColor` assumes 1D array and requires one positional argument, while  `setPixelColorXY` takes two positional arguments (x and y), and then the RBG color value. |
+| `SEGMENT.setPixelColor / setPixelColorXY`       | ---    | Function that paints a single pixel to your specified color. `setPixelColor` assumes a 1-D array and requires one positional argument, while `setPixelColorXY` takes two positional arguments (x and y) and then the RGB color value. |

-| `SEGMENT.color_from_palette()`                  | ???    | Gets a single color from the currently selected palette for a segment. (This function which should be favoured over `ColorFromPalette()`.) <br />Defined in ...
+| `SEGMENT.color_from_palette()`                  | uint32 | Returns one RGB color from the active palette for the segment (preferred over `ColorFromPalette()`). <br />Defined in ...

-| `fade`                                          | ???    | ...
+| `fade*`                                         | helper | ...

-| `move()`                                        | ???    | ...
+| `move()`                                        | helper | ...

-| `blur / blur2d`                                 | ???    | ...
+| `blur / blur2d`                                 | helper | ...

Either supply the real sizes (e.g. uint32, helper, or remove the column entirely) and fix the misspellings, or the table will continue to look unfinished.
Also consider adding the trailing | in each row to satisfy MD055.

🧹 Nitpick comments (7)
usermods/user_fx/README.md (7)

3-6: Correct obvious spelling mistake in first paragraph

depracateddeprecated

This is the very first thing readers will see—leaving a typo here undermines credibility.

-...load in depracated WLED effects...
+...load in deprecated WLED effects...

24-25: Fix typo “abour” → “about”

-...go abour creating your own in the section below.
+...go about creating your own in the section below.

160-162: Minor typo inside inline comment

fo codeof code

-* The conditional statement in the first line fo code ensures the effect updates on a fixed interval...
+* The conditional statement in the first line of code ensures the effect updates on a fixed interval...

300-304: Typo and casing (“tep by step”, “Sinelon base”)

-we will break this effect down tep by step.
+We will break this effect down step by step.

-static uint16_t sinelon_base(bool dual, bool rainbow=false) {
+static uint16_t sinelon_base(bool dual, bool rainbow = false) {

Consistent casing and correct spelling improve readability.


416-422: Spelling: “speicfy” → “specify”

-And then the last part defines the metadata strings for each effect to speicfy how it will be portrayed in the UI:
+And then the last part defines the metadata strings for each effect to specify how it will be portrayed in the UI:

464-468: Spelling: “instatiation” → “instantiation”

-The final part of this file handles instatiation and initialization:
+The final part of this file handles instantiation and initialization:

477-481: Grammar: missing “to” before verb

-So now let's say that you wanted add the effects
+So now let's say that you wanted to add the effects
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1e6a992 and 9970594.

📒 Files selected for processing (1)
  • usermods/user_fx/README.md (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: netmindz
PR: wled/WLED#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.
Learnt from: netmindz
PR: wled/WLED#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.
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.
usermods/user_fx/README.md (4)
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: netmindz
PR: wled/WLED#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.
Learnt from: netmindz
PR: wled/WLED#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.
Learnt from: KrX3D
PR: wled/WLED#4237
File: usermods/INA219_v2/INA219_v2.cpp:265-276
Timestamp: 2025-04-18T22:27:58.634Z
Learning: When implementing MQTT message handling in WLED usermods, use `strstr(topic, "/specific/path")` instead of `strcmp_P(topic, PSTR("/specific/path"))` to properly match topics that include the device prefix. The full MQTT topic typically follows the pattern `<mqttDeviceTopic>/specific/path`.
🪛 LanguageTool
usermods/user_fx/README.md

[style] ~20-~20: Consider removing “of” to be more concise
Context: ...area is where you place the FX code for all of the custom effects you want to use. This m...

(ALL_OF_THE)


[style] ~22-~22: As a shorter alternative for ‘able to’, consider using “can”.
Context: ...mods have to be registered so that they are able to be compiled into your binary. We will ...

(BE_ABLE_TO)


[style] ~22-~22: Avoid the passive voice after ‘to be able to’.
Context: ... be registered so that they are able to be compiled into your binary. We will go into grea...

(ABLE_TO_PASSIVE)


[grammar] ~40-~40: Possible subject-verb agreement error detected.
Context: ...16-bit | These are state variables that persists between function calls, and they are fr...

(PLURAL_THAT_AGREEMENT)


[uncategorized] ~46-~46: Possible missing article found.
Context: ...--- | Gets user-selected colors from UI, where x is an integer 1, 2, or 3 for p...

(AI_HYDRA_LEO_MISSING_THE)


[uncategorized] ~47-~47: Possible missing article found.
Context: ...ecified color. setPixelColor assumes 1D array and requires one positional argum...

(AI_HYDRA_LEO_MISSING_A)


[uncategorized] ~49-~49: Possible missing comma found.
Context: ...y selected palette for a segment. (This function which should be favoured over `ColorFro...

(AI_HYDRA_LEO_MISSING_COMMA)


[typographical] ~62-~62: It appears that a comma is missing.
Context: ... Understanding 2D WLED Effects In this section we give some advice to those who are ne...

(DURING_THAT_TIME_COMMA)


[uncategorized] ~66-~66: Use a comma before ‘and’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...le. This file handles all other imports and it has all the global variable declarat...

(COMMA_COMPOUND_SENTENCE)


[uncategorized] ~82-~82: Possible missing comma found.
Context: ...lock contains several constant variable definitions which essentially serve to extract the ...

(AI_HYDRA_LEO_MISSING_COMMA)


[misspelling] ~103-~103: Nonstandard phrase. Did you mean: “from 0 to 255”?
Context: ...MENT.speed (user-controllable parameter from 0–255) to a value between 20 and 80 Hz. * T...

(FROM_X_Y)


[uncategorized] ~105-~105: Possible missing comma found.
Context: ...gher speed = more frames per second). * Next we convert refresh rate from Hz to mill...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~109-~109: Possible missing comma found.
Context: ...re diffusion = smoother flame spread. * Next we assign SEGMENT.intensity (user inp...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~178-~178: Possible missing preposition found.
Context: ...whether we even attempt to spawn sparks this frame. * hw_random8() gives a rando...

(AI_HYDRA_LEO_MISSING_IN)


[uncategorized] ~209-~209: Possible missing article found.
Context: ...Starting with the current heat value of pixel (x, y) assigned v: * if there’s a p...

(AI_HYDRA_LEO_MISSING_A)


[uncategorized] ~234-~234: Possible missing comma found.
Context: ... color-rendering for each pixel row.) * Next we update the main segment data with th...

(AI_HYDRA_LEO_MISSING_COMMA)


[grammar] ~236-~236: Use the plural noun “” with the number ‘255’.
Context: ...olor` from the current palette with 255 brightness, and no wrapping in palette lookup. *...

(IN_CD_PUNCTUATION)


[typographical] ~238-~238: Consider adding a comma after ‘Finally’ for more clarity.
Context: ... flames (e.g., yellow → red → black). * Finally we set the rendered color for the pixel...

(RB_LY_COMMA)


[grammar] ~240-~240: The word “fallback” is a noun. The verb is spelled with a space.
Context: ...h row. * If palette use is disabled, we fallback to fading a base color. * SEGCOLOR(0)...

(NOUN_VERB_CONFUSION)


[grammar] ~261-~261: Did you mean the adverb/preposition “within”?
Context: ...ines how the effect is to be interacted with in the UI: ```cpp static const char data...

(WITH_IN)


[typographical] ~288-~288: The word “otherwise” is an adverb that can’t be used like a conjunction, and therefore needs to be separated from the sentence.
Context: ...s is enabled, the effect uses a palette ColorFromPalette(), otherwise it fades from SEGCOLOR(0). The first...

(THUS_SENTENCE)


[style] ~290-~290: ‘in conjunction with’ might be wordy. Consider a shorter alternative.
Context: ...s to be selected by the user. But used in conjunction with the checkbox argument, palette use can ...

(EN_WORDINESS_PREMIUM_IN_CONJUNCTION_WITH)


[uncategorized] ~338-~338: Loose punctuation mark.
Context: ...2_t color2 = SEGCOLOR(2); ``` * color1: main moving dot color, chosen from pale...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~339-~339: Loose punctuation mark.
Context: ...he current position as index. * color2: secondary color from user-configured co...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~341-~341: This word is normally spelled with a hyphen.
Context: ... account the optional argument for if a Rainbow colored palette is in use: ```cpp if (rainbow...

(RAINBOW_COLORED)


[style] ~355-~355: ‘takes into account’ might be wordy. Consider a shorter alternative.
Context: ...with the selected color. The next line takes into account another one of the optional arguments f...

(EN_WORDINESS_PREMIUM_TAKES_INTO_ACCOUNT)


[uncategorized] ~355-~355: Possible missing comma found.
Context: ...ect to potentially handle dual mirrored dots which create the animation: ```cpp if...

(AI_HYDRA_LEO_MISSING_COMMA)


[grammar] ~385-~385: The verb form ‘has’ does not seem to match the subject ‘checks’.
Context: ...e first line checks if current position has changed since last frame. (Prevents ho...

(SUBJECT_VERB_AGREEMENT_PLURAL)


[uncategorized] ~385-~385: Possible missing article found.
Context: ...s if current position has changed since last frame. (Prevents holes if the dot move...

(AI_HYDRA_LEO_MISSING_THE)


[uncategorized] ~454-~454: Possible missing comma found.
Context: ...important one that registers the custom effect so WLED knows about it. * 255: Tempor...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~457-~457: Loose punctuation mark.
Context: ...ction. * _data_FX_MODE_DIFFUSIONFIRE: Metadata string stored in PROGMEM, desc...

(UNLIKELY_OPENING_PUNCTUATION)


[grammar] ~477-~477: The verb “add” needs to be in the to-infinitive form.
Context: ...this Usermod So now let's say that you wanted add the effects "Diffusion Fire" and "Sine...

(MISSING_TO_BEFORE_A_VERB)


[style] ~479-~479: Did you mean ‘different from’? ‘Different than’ is often considered colloquial style.
Context: ...ell--and to name it something different than what's already inside the core WLED cod...

(DIFFERENT_THAN)


[duplication] ~483-~483: Possible typo: you repeated a word.
Context: ... Usermod class. * Compile the code! ## Compiling Compiling WLED yourself is beyond the scope of th...

(ENGLISH_WORD_REPEAT_RULE)

🪛 markdownlint-cli2 (0.17.2)
usermods/user_fx/README.md

39-39: Table pipe style
Expected: leading_and_trailing; Actual: leading_only; Missing trailing pipe

(MD055, table-pipe-style)


269-269: Hard tabs
Column: 12

(MD010, no-hard-tabs)


271-271: Hard tabs
Column: 5

(MD010, no-hard-tabs)


272-272: Hard tabs
Column: 5

(MD010, no-hard-tabs)


273-273: Hard tabs
Column: 5

(MD010, no-hard-tabs)


274-274: Hard tabs
Column: 5

(MD010, no-hard-tabs)


275-275: Hard tabs
Column: 5

(MD010, no-hard-tabs)


276-276: Hard tabs
Column: 12

(MD010, no-hard-tabs)


277-277: Hard tabs
Column: 5

(MD010, no-hard-tabs)


278-278: Hard tabs
Column: 5

(MD010, no-hard-tabs)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
usermods/user_fx/README.md (4)

3-6: Fix multiple typos in opening paragraph
depracateddeprecated, user'susers', plus minor grammar tweaks.

-This Usermod is a common place to put various user's WLED Effects.  It gives you a way to load in your own custom WLED effects, or to load in depracated WLED effects that you want to bring back--all without having to mess with the core WLED source code.
+This usermod is a common place to put various users' WLED effects. It lets you load your own custom effects—or resurrect deprecated ones—without modifying the core WLED source code.

18-25: Minor spelling + wording cleanup
abourabout; tighten phrasing for clarity.

-We will go into greater detail on how custom effects work in the usermod and how to go abour creating your own in the section below.
+We’ll dive into how custom effects work in this usermod and how to create your own in the sections below.

45-46: Remove unresolved placeholder question
The parenthetical “(and how it relates to meta string??)” is a note to the author, not the reader.

-`SEGCOLOR(x)`                                   | —      | Gets user-selected colors from UI, where x is an integer 1, 2, or 3 for primary, secondary, and tertiary colors, respectively. (and how it relates to meta string??) |
+`SEGCOLOR(x)`                                   | —      | Retrieves the user-selected color `x` (1 = primary, 2 = secondary, 3 = tertiary). |

266-276: Replace hard tabs with spaces to satisfy MD010
The metadata-parameter table uses literal tab characters, triggering markdown-lint. Convert to two or four spaces.

-| Parameter	| Default tooltip label |
+| Parameter | Default tooltip label |

(repeat for every row)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9970594 and 41afdf4.

📒 Files selected for processing (1)
  • usermods/user_fx/README.md (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: netmindz
PR: wled/WLED#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.
Learnt from: netmindz
PR: wled/WLED#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.
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.
usermods/user_fx/README.md (5)
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: netmindz
PR: wled/WLED#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.
Learnt from: netmindz
PR: wled/WLED#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.
Learnt from: KrX3D
PR: wled/WLED#4585
File: usermods/seven_segment_display_reloaded_v2/seven_segment_display_reloaded_v2.h:121-137
Timestamp: 2025-04-27T10:06:22.545Z
Learning: In the Seven Segment Display Reloaded usermod, the dimension mismatch between the default array (umSSDRNumbers[11][7]) and the override (umSSDRNumbers[11][10] = umSSDR_NUMBERS) is intentional by design, allowing for different use cases with varying numbers of segments per digit.
Learnt from: KrX3D
PR: wled/WLED#4237
File: usermods/INA219_v2/INA219_v2.cpp:265-276
Timestamp: 2025-04-18T22:27:58.634Z
Learning: When implementing MQTT message handling in WLED usermods, use `strstr(topic, "/specific/path")` instead of `strcmp_P(topic, PSTR("/specific/path"))` to properly match topics that include the device prefix. The full MQTT topic typically follows the pattern `<mqttDeviceTopic>/specific/path`.
🪛 LanguageTool
usermods/user_fx/README.md

[style] ~20-~20: Consider removing “of” to be more concise
Context: ...area is where you place the FX code for all of the custom effects you want to use. This m...

(ALL_OF_THE)


[style] ~22-~22: As a shorter alternative for ‘able to’, consider using “can”.
Context: ...mods have to be registered so that they are able to be compiled into your binary. We will ...

(BE_ABLE_TO)


[style] ~22-~22: Avoid the passive voice after ‘to be able to’.
Context: ... be registered so that they are able to be compiled into your binary. We will go into grea...

(ABLE_TO_PASSIVE)


[grammar] ~40-~40: Possible subject-verb agreement error detected.
Context: ...16-bit | These are state variables that persists between function calls, and they are fr...

(PLURAL_THAT_AGREEMENT)


[uncategorized] ~46-~46: Possible missing article found.
Context: ...ecified color. setPixelColor assumes 1D array and requires one positional argum...

(AI_HYDRA_LEO_MISSING_A)


[uncategorized] ~48-~48: Possible missing comma found.
Context: ...y selected palette for a segment. (This function which should be favoured over `ColorFro...

(AI_HYDRA_LEO_MISSING_COMMA)


[style] ~53-~53: Consider removing “of” to be more concise
Context: ..._fcn.cpp). | Importing wled.h brings all of the variables, files, and functions listed ...

(ALL_OF_THE)


[typographical] ~59-~59: It appears that a comma is missing.
Context: ... Understanding 2D WLED Effects In this section we give some advice to those who are ne...

(DURING_THAT_TIME_COMMA)


[uncategorized] ~63-~63: Use a comma before ‘and’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...le. This file handles all other imports and it has all the global variable declarat...

(COMMA_COMPOUND_SENTENCE)


[uncategorized] ~79-~79: Possible missing comma found.
Context: ...lock contains several constant variable definitions which essentially serve to extract the ...

(AI_HYDRA_LEO_MISSING_COMMA)


[misspelling] ~100-~100: Nonstandard phrase. Did you mean: “from 0 to 255”?
Context: ...MENT.speed (user-controllable parameter from 0–255) to a value between 20 and 80 Hz. * T...

(FROM_X_Y)


[uncategorized] ~102-~102: Possible missing comma found.
Context: ...gher speed = more frames per second). * Next we convert refresh rate from Hz to mill...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~106-~106: Possible missing comma found.
Context: ...re diffusion = smoother flame spread. * Next we assign SEGMENT.intensity (user inp...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~175-~175: Possible missing preposition found.
Context: ...whether we even attempt to spawn sparks this frame. * hw_random8() gives a rando...

(AI_HYDRA_LEO_MISSING_IN)


[uncategorized] ~206-~206: Possible missing article found.
Context: ...Starting with the current heat value of pixel (x, y) assigned v: * if there’s a p...

(AI_HYDRA_LEO_MISSING_A)


[uncategorized] ~231-~231: Possible missing comma found.
Context: ... color-rendering for each pixel row.) * Next we update the main segment data with th...

(AI_HYDRA_LEO_MISSING_COMMA)


[grammar] ~233-~233: Use the plural noun “” with the number ‘255’.
Context: ...olor` from the current palette with 255 brightness, and no wrapping in palette lookup. *...

(IN_CD_PUNCTUATION)


[typographical] ~235-~235: Consider adding a comma after ‘Finally’ for more clarity.
Context: ... flames (e.g., yellow → red → black). * Finally we set the rendered color for the pixel...

(RB_LY_COMMA)


[grammar] ~237-~237: The word “fallback” is a noun. The verb is spelled with a space.
Context: ...h row. * If palette use is disabled, we fallback to fading a base color. * SEGCOLOR(0)...

(NOUN_VERB_CONFUSION)


[grammar] ~258-~258: Did you mean the adverb/preposition “within”?
Context: ...ines how the effect is to be interacted with in the UI: ```cpp static const char data...

(WITH_IN)


[typographical] ~285-~285: The word “otherwise” is an adverb that can’t be used like a conjunction, and therefore needs to be separated from the sentence.
Context: ...s is enabled, the effect uses a palette ColorFromPalette(), otherwise it fades from SEGCOLOR(0). The first...

(THUS_SENTENCE)


[style] ~287-~287: ‘in conjunction with’ might be wordy. Consider a shorter alternative.
Context: ...s to be selected by the user. But used in conjunction with the checkbox argument, palette use can ...

(EN_WORDINESS_PREMIUM_IN_CONJUNCTION_WITH)


[uncategorized] ~335-~335: Loose punctuation mark.
Context: ...2_t color2 = SEGCOLOR(2); ``` * color1: main moving dot color, chosen from pale...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~336-~336: Loose punctuation mark.
Context: ...he current position as index. * color2: secondary color from user-configured co...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~338-~338: This word is normally spelled with a hyphen.
Context: ... account the optional argument for if a Rainbow colored palette is in use: ```cpp if (rainbow...

(RAINBOW_COLORED)


[style] ~352-~352: ‘takes into account’ might be wordy. Consider a shorter alternative.
Context: ...with the selected color. The next line takes into account another one of the optional arguments f...

(EN_WORDINESS_PREMIUM_TAKES_INTO_ACCOUNT)


[uncategorized] ~352-~352: Possible missing comma found.
Context: ...ect to potentially handle dual mirrored dots which create the animation: ```cpp if...

(AI_HYDRA_LEO_MISSING_COMMA)


[grammar] ~382-~382: The verb form ‘has’ does not seem to match the subject ‘checks’.
Context: ...e first line checks if current position has changed since last frame. (Prevents ho...

(SUBJECT_VERB_AGREEMENT_PLURAL)


[uncategorized] ~382-~382: Possible missing article found.
Context: ...s if current position has changed since last frame. (Prevents holes if the dot move...

(AI_HYDRA_LEO_MISSING_THE)


[uncategorized] ~451-~451: Possible missing comma found.
Context: ...important one that registers the custom effect so WLED knows about it. * 255: Tempor...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~454-~454: Loose punctuation mark.
Context: ...ction. * _data_FX_MODE_DIFFUSIONFIRE: Metadata string stored in PROGMEM, desc...

(UNLIKELY_OPENING_PUNCTUATION)


[grammar] ~474-~474: The verb “add” needs to be in the to-infinitive form.
Context: ...this Usermod So now let's say that you wanted add the effects "Diffusion Fire" and "Sine...

(MISSING_TO_BEFORE_A_VERB)


[style] ~476-~476: Did you mean ‘different from’? ‘Different than’ is often considered colloquial style.
Context: ...ell--and to name it something different than what's already inside the core WLED cod...

(DIFFERENT_THAN)


[duplication] ~480-~480: Possible typo: you repeated a word.
Context: ... Usermod class. * Compile the code! ## Compiling Compiling WLED yourself is beyond the scope of th...

(ENGLISH_WORD_REPEAT_RULE)

🪛 markdownlint-cli2 (0.17.2)
usermods/user_fx/README.md

39-39: Table pipe style
Expected: leading_and_trailing; Actual: leading_only; Missing trailing pipe

(MD055, table-pipe-style)


266-266: Hard tabs
Column: 12

(MD010, no-hard-tabs)


268-268: Hard tabs
Column: 5

(MD010, no-hard-tabs)


269-269: Hard tabs
Column: 5

(MD010, no-hard-tabs)


270-270: Hard tabs
Column: 5

(MD010, no-hard-tabs)


271-271: Hard tabs
Column: 5

(MD010, no-hard-tabs)


272-272: Hard tabs
Column: 5

(MD010, no-hard-tabs)


273-273: Hard tabs
Column: 12

(MD010, no-hard-tabs)


274-274: Hard tabs
Column: 5

(MD010, no-hard-tabs)


275-275: Hard tabs
Column: 5

(MD010, no-hard-tabs)

Comment on lines 37 to 52
| Syntax Element | Size | Description |
| :---------------------------------------------- | :----- | :---------- |
| `SEGMENT.intensity / speed / custom1 etc.` | 8-bit | These read-only variables help you control aspects of your custom effect using the UI sliders. You can edit these vriables through the UI sliders when WLED is running your effect. (These variables can be controlled by the API as well.)
| `SEGENV.aux0 / aux1` | 16-bit | These are state variables that persists between function calls, and they are free to be overwritten by the user for any use case. |
| `SEGENV.call` | 32-bit | A counter for how many times this effect function has been invoked since it started. |
| `strip.now` | 32-bit | Current timestamp in milliseconds. (Equivalent to `millis()`, but use `strip.now()` instead.) |
| `SEGLEN / SEG_W / SEG_H` | 16-bit | These variables are macros that help define the length and width of your LED strip/matrix segment. |
| `hw_random8()` | 8-bit | Generates a random integer. All random number functions can be found [here](https://github.com/wled/WLED/blob/7b0075d3754fa883fc1bbc9fbbe82aa23a9b97b8/wled00/fcn_declare.h#L535). |
| `SEGCOLOR(x)` | --- | Gets user-selected colors from UI, where x is an integer 1, 2, or 3 for primary, secondary, and tertiary colors, respectively. (and how it relates to meta string??) |
| `SEGMENT.setPixelColor / setPixelColorXY` | --- | Fuction that paints a single pixel to your specified color. `setPixelColor` assumes 1D array and requires one positional argument, while `setPixelColorXY` takes two positional arguments (x and y), and then the RBG color value. |
| `SEGPALETTE` | --- | This is the currently selected palette for the currently processing segment. |
| `SEGMENT.color_from_palette()` | 32-bit | Gets a single color from the currently selected palette for a segment. (This function which should be favoured over `ColorFromPalette()`.) <br />Defined in [FX_fcn.cpp](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp). |
| `fade` | --- | There are several different fade functions that make it easy to accomplish different fading tasks; these are all detailed in [FX_fcn.cpp](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp). An example would be `fadeToBlackBy()` which can be used to fade all pixels to black. |
| `move()` | --- | Moves/shifts pixels in the desired direction. Defined in [FX_fcn.cpp](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp). |
| `blur / blur2d` | --- | Blurs all pixels for the desired segment. Defined in [FX_fcn.cpp](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp). |

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Table rendering is broken — add trailing pipes & fix typos
GitHub markdown requires matching pipes; current table violates MD055 and renders incorrectly. Also fix misspellings and stray text.

-| Syntax Element                                  | Size   | Description |
-| :---------------------------------------------- | :----- | :---------- |
-| `SEGMENT.intensity / speed / custom1 etc.`      | 8-bit  | These read-only variables help you control aspects of your custom effect using the UI sliders.  You can edit these vriables through the UI sliders when WLED is running your effect. (These variables can be controlled by the API as well.)
+| Syntax element                                   | Size   | Description |
+| :-----------------------------------------------| :-----:| :---------- |
+| `SEGMENT.intensity / speed / custom1 …`          | 8-bit  | Read-only variables that map to the UI sliders and API. |
@@
-| `SEGCOLOR(x)`                                   | ---    | Gets user-selected colors from UI, where x is an integer 1, 2, or 3 for primary, secondary, and tertiary colors, respectively. (and how it relates to meta string??) |
-| `SEGMENT.setPixelColor / setPixelColorXY`       | ---    | Fuction that paints a single pixel to your specified color.  `setPixelColor` assumes 1D array and requires one positional argument, while  `setPixelColorXY` takes two positional arguments (x and y), and then the RBG color value. |
+| `SEGCOLOR(x)`                                   | —      | Retrieves UI-selected color `x` (1 = primary, 2 = secondary, 3 = tertiary). |
+| `SEGMENT.setPixelColor / setPixelColorXY`       | —      | Function that paints a pixel. `setPixelColor` is 1-D; `setPixelColorXY` expects `(x, y)`. |
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
| Syntax Element | Size | Description |
| :---------------------------------------------- | :----- | :---------- |
| `SEGMENT.intensity / speed / custom1 etc.` | 8-bit | These read-only variables help you control aspects of your custom effect using the UI sliders. You can edit these vriables through the UI sliders when WLED is running your effect. (These variables can be controlled by the API as well.)
| `SEGENV.aux0 / aux1` | 16-bit | These are state variables that persists between function calls, and they are free to be overwritten by the user for any use case. |
| `SEGENV.call` | 32-bit | A counter for how many times this effect function has been invoked since it started. |
| `strip.now` | 32-bit | Current timestamp in milliseconds. (Equivalent to `millis()`, but use `strip.now()` instead.) |
| `SEGLEN / SEG_W / SEG_H` | 16-bit | These variables are macros that help define the length and width of your LED strip/matrix segment. |
| `hw_random8()` | 8-bit | Generates a random integer. All random number functions can be found [here](https://github.com/wled/WLED/blob/7b0075d3754fa883fc1bbc9fbbe82aa23a9b97b8/wled00/fcn_declare.h#L535). |
| `SEGCOLOR(x)` | --- | Gets user-selected colors from UI, where x is an integer 1, 2, or 3 for primary, secondary, and tertiary colors, respectively. (and how it relates to meta string??) |
| `SEGMENT.setPixelColor / setPixelColorXY` | --- | Fuction that paints a single pixel to your specified color. `setPixelColor` assumes 1D array and requires one positional argument, while `setPixelColorXY` takes two positional arguments (x and y), and then the RBG color value. |
| `SEGPALETTE` | --- | This is the currently selected palette for the currently processing segment. |
| `SEGMENT.color_from_palette()` | 32-bit | Gets a single color from the currently selected palette for a segment. (This function which should be favoured over `ColorFromPalette()`.) <br />Defined in [FX_fcn.cpp](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp). |
| `fade` | --- | There are several different fade functions that make it easy to accomplish different fading tasks; these are all detailed in [FX_fcn.cpp](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp). An example would be `fadeToBlackBy()` which can be used to fade all pixels to black. |
| `move()` | --- | Moves/shifts pixels in the desired direction. Defined in [FX_fcn.cpp](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp). |
| `blur / blur2d` | --- | Blurs all pixels for the desired segment. Defined in [FX_fcn.cpp](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp). |
| Syntax element | Size | Description |
| :----------------------------------------------- | :-----: | :---------- |
| `SEGMENT.intensity / speed / custom1 ` | 8-bit | Read-only variables that map to the UI sliders and API. |
| `SEGENV.aux0 / aux1` | 16-bit | These are state variables that persist between function calls and can be overwritten by the user. |
| `SEGENV.call` | 32-bit | A counter for how many times this effect function has been invoked since it started. |
| `strip.now` | 32-bit | Current timestamp in milliseconds (equivalent to `millis()`, but use `strip.now()`). |
| `SEGLEN / SEG_W / SEG_H` | 16-bit | Macros defining the length and width of your LED strip/matrix segment. |
| `hw_random8()` | 8-bit | Generates a random integer. All random number functions are listed [here](https://github.com/wled/WLED/blob/7b0075d3754fa883fc1bbc9fbbe82aa23a9b97b8/wled00/fcn_declare.h#L535). |
| `SEGCOLOR(x)` | | Retrieves UI-selected color `x` (1 = primary, 2 = secondary, 3 = tertiary). |
| `SEGMENT.setPixelColor / setPixelColorXY` | | Function that paints a pixel. `setPixelColor` is 1D; `setPixelColorXY` expects `(x, y)`. |
| `SEGPALETTE` | | The currently selected palette for the processing segment. |
| `SEGMENT.color_from_palette()` | 32-bit | Gets a single color from the current segment palette. (Prefer over `ColorFromPalette()`.)<br/>Defined in [FX_fcn.cpp](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp). |
| `fade` || Various fade functions (e.g. `fadeToBlackBy()`). See [FX_fcn.cpp](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp). |
| `move()` | | Moves/shifts pixels in the desired direction. Defined in [FX_fcn.cpp](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp). |
| `blur / blur2d` | | Blurs all pixels for the segment. Defined in [FX_fcn.cpp](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp). |
🧰 Tools
🪛 LanguageTool

[grammar] ~40-~40: Possible subject-verb agreement error detected.
Context: ...16-bit | These are state variables that persists between function calls, and they are fr...

(PLURAL_THAT_AGREEMENT)


[uncategorized] ~46-~46: Possible missing article found.
Context: ...ecified color. setPixelColor assumes 1D array and requires one positional argum...

(AI_HYDRA_LEO_MISSING_A)


[uncategorized] ~48-~48: Possible missing comma found.
Context: ...y selected palette for a segment. (This function which should be favoured over `ColorFro...

(AI_HYDRA_LEO_MISSING_COMMA)

🪛 markdownlint-cli2 (0.17.2)

39-39: Table pipe style
Expected: leading_and_trailing; Actual: leading_only; Missing trailing pipe

(MD055, table-pipe-style)

🤖 Prompt for AI Agents
In usermods/user_fx/README.md between lines 37 and 52, the markdown table is
missing trailing pipes on each line, causing broken rendering and violating
markdown lint rule MD055. Also, fix typos such as "vriables" to "variables,"
"SEGENV" to "SEGENV," "Fuction" to "Function," and clarify stray text like "(and
how it relates to meta string??)" by removing or rephrasing it. Add trailing
pipes at the end of each table row and correct all spelling errors to ensure
proper table formatting and readability.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
usermods/user_fx/README.md (1)

37-52: Table still breaks MD055 & contains typos – add trailing pipes and clean wording

Previous feedback on this exact table hasn’t been applied; rendering is still broken and several typos remain. Example issues:
• no trailing | → GitHub table collapses
vriablesvariables
FuctionFunction
RBGRGB
• “persists” → “persist”

-| Syntax Element                                  | Size   | Description |
-| :---------------------------------------------- | :----- | :---------- |
-| `SEGMENT.intensity / speed / custom1 etc.`      | 8-bit  | These read-only variables help you control aspects of your custom effect using the UI sliders.  You can edit these vriables through the UI sliders when WLED is running your effect. (These variables can be controlled by the API as well.)
-| `SEGENV.aux0 / aux1`                            | 16-bit | These are state variables that persists between function calls, and they are free to be overwritten by the user for any use case. |
-| `SEGENV.call`                                   | 32-bit | A counter for how many times this effect function has been invoked since it started. |
-| `strip.now`                                     | 32-bit | Current timestamp in milliseconds.  (Equivalent to `millis()`, but use `strip.now()` instead.) |
+| Syntax element                                   | Size  | Description |
+| :-----------------------------------------------| :----:| :---------- |
+| `SEGMENT.intensity / speed / custom1 …`          | 8-bit | Read-only variables mapped to the UI sliders (and API). |
+| `SEGENV.aux0 / aux1`                             | 16-bit | User-owned state variables that persist between calls. |
+| `SEGENV.call`                                    | 32-bit | Invocation counter since the effect started. |
+| `strip.now`                                      | 32-bit | Current timestamp in milliseconds (`millis()` alias). |

…and continue the same way for the remaining rows, ensuring each ends with a pipe.

🧹 Nitpick comments (3)
usermods/user_fx/README.md (3)

3-6: Fix spelling + minor grammar in the introduction

depracateddeprecated, Multiple Effects can be specified … → add comma after “specified”, and consider trimming the double-space before “as we will illustrate”.

-This Usermod is a common place to put various user's WLED Effects.  It gives you a way to load in your own custom WLED effects, or to load in depracated WLED effects that you want to bring back--all without having to mess with the core WLED source code.
-Multiple Effects can be specified inside this single usermod, as we will illustrate below.  You will be able to define them with custom names, sliders, etc. as with any other Effect.
+This usermod is a common place to host various WLED effects. It lets you load your own custom effects or revive deprecated ones—without touching core WLED source code.
+Multiple effects can be specified inside this single usermod, as we illustrate below. You can give each effect custom names, sliders, etc., just like any other effect.

59-66: Typos in section header paragraph

tep by stepstep by step; missing comma after “imports”.

-In this section we give some advice to those who are new to WLED Effect creation.  We will illustrate how to load in multiple Effects using this single usermod, and we will do a deep dive into the anatomy of a 1D Effect as well as a 2D Effect.
+In this section, we give advice to newcomers to WLED effect creation. We illustrate how to load multiple effects with this single usermod and dive into the anatomy of both 1D and 2D effects.

266-276: Replace hard tabs with spaces in the metadata-parameter table

The table uses literal tab characters, violating MD010 and rendering inconsistently on some editors. Convert tabs to two or three spaces per column.

No diff shown because the change is mechanical across all rows.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 41afdf4 and a7225f6.

📒 Files selected for processing (1)
  • usermods/user_fx/README.md (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: netmindz
PR: wled/WLED#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.
Learnt from: netmindz
PR: wled/WLED#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.
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.
usermods/user_fx/README.md (13)
Learnt from: netmindz
PR: wled/WLED#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.
Learnt from: netmindz
PR: wled/WLED#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.
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: KrX3D
PR: wled/WLED#4585
File: usermods/seven_segment_display_reloaded_v2/seven_segment_display_reloaded_v2.h:121-137
Timestamp: 2025-04-27T10:06:22.545Z
Learning: In the Seven Segment Display Reloaded usermod, the dimension mismatch between the default array (umSSDRNumbers[11][7]) and the override (umSSDRNumbers[11][10] = umSSDR_NUMBERS) is intentional by design, allowing for different use cases with varying numbers of segments per digit.
Learnt from: KrX3D
PR: wled/WLED#4237
File: usermods/INA219_v2/INA219_v2.cpp:265-276
Timestamp: 2025-04-18T22:27:58.634Z
Learning: When implementing MQTT message handling in WLED usermods, use `strstr(topic, "/specific/path")` instead of `strcmp_P(topic, PSTR("/specific/path"))` to properly match topics that include the device prefix. The full MQTT topic typically follows the pattern `<mqttDeviceTopic>/specific/path`.
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: 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: 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: willmmiles
PR: wled/WLED#4712
File: wled00/FX_fcn.cpp:992-993
Timestamp: 2025-06-07T15:58:42.579Z
Learning: In WLED segments, the backing pixel buffer is always allocated to the full physical segment size, but effect rendering only uses a subset when mirror or grouping are enabled. For 2D segments, this subset is vWidth() * vHeight(), and for 1D segments it's vLength(). Color processing operations like fade_out should iterate over this rendering subset, not the full allocated buffer.
Learnt from: KrX3D
PR: wled/WLED#4585
File: usermods/seven_segment_display_reloaded_v2/seven_segment_display_reloaded_v2.h:121-136
Timestamp: 2025-04-27T09:37:28.415Z
Learning: Using PROGMEM for the seven-segment font array (umSSDRNumbers) in the WLED SSDR usermod causes compilation problems, so it should be left as a regular array.
Learnt from: blazoncek
PR: wled/WLED#4658
File: wled00/led.cpp:90-91
Timestamp: 2025-04-24T09:31:06.879Z
Learning: In the WLED codebase, the `getSegment()` function guards against out-of-bounds segment IDs, and `getFirstSelectedSegId()` falls back to `getMainSegmentId()` if no segments are selected, ensuring no crashes when used through the `setValuesFromFirstSelectedSeg()` macro.
Learnt from: blazoncek
PR: wled/WLED#4658
File: wled00/led.cpp:90-91
Timestamp: 2025-04-24T09:31:06.879Z
Learning: In the WLED codebase, the `getSegment()` function guards against out-of-bounds segment IDs, and `getFirstSelectedSegId()` falls back to `getMainSegmentId()` if no segments are selected, ensuring no crashes when used through the `setValuesFromFirstSelectedSeg()` macro.
Learnt from: blazoncek
PR: wled/WLED#4658
File: wled00/led.cpp:90-91
Timestamp: 2025-04-24T09:31:06.879Z
Learning: In the WLED codebase, the `getSegment()` function guards against out-of-bounds segment IDs by falling back to the main segment ID, and `getFirstSelectedSegId()` falls back to `getMainSegmentId()` if no segments are selected, ensuring no crashes when used through the `setValuesFromFirstSelectedSeg()` macro.
🪛 LanguageTool
usermods/user_fx/README.md

[style] ~20-~20: Consider removing “of” to be more concise
Context: ...area is where you place the FX code for all of the custom effects you want to use. This m...

(ALL_OF_THE)


[style] ~22-~22: As a shorter alternative for ‘able to’, consider using “can”.
Context: ...mods have to be registered so that they are able to be compiled into your binary. We will ...

(BE_ABLE_TO)


[style] ~22-~22: Avoid the passive voice after ‘to be able to’.
Context: ... be registered so that they are able to be compiled into your binary. We will go into grea...

(ABLE_TO_PASSIVE)


[grammar] ~40-~40: Possible subject-verb agreement error detected.
Context: ...16-bit | These are state variables that persists between function calls, and they are fr...

(PLURAL_THAT_AGREEMENT)


[uncategorized] ~46-~46: Possible missing article found.
Context: ...ecified color. setPixelColor assumes 1D array and requires one positional argum...

(AI_HYDRA_LEO_MISSING_A)


[uncategorized] ~48-~48: Possible missing comma found.
Context: ...y selected palette for a segment. (This function which should be favoured over `ColorFro...

(AI_HYDRA_LEO_MISSING_COMMA)


[style] ~53-~53: Consider removing “of” to be more concise
Context: ..._fcn.cpp). | Importing wled.h brings all of the variables, files, and functions listed ...

(ALL_OF_THE)


[typographical] ~59-~59: It appears that a comma is missing.
Context: ... Understanding 2D WLED Effects In this section we give some advice to those who are ne...

(DURING_THAT_TIME_COMMA)


[uncategorized] ~63-~63: Use a comma before ‘and’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...le. This file handles all other imports and it has all the global variable declarat...

(COMMA_COMPOUND_SENTENCE)


[uncategorized] ~79-~79: Possible missing comma found.
Context: ...lock contains several constant variable definitions which essentially serve to extract the ...

(AI_HYDRA_LEO_MISSING_COMMA)


[misspelling] ~100-~100: Nonstandard phrase. Did you mean: “from 0 to 255”?
Context: ...MENT.speed (user-controllable parameter from 0–255) to a value between 20 and 80 Hz. * T...

(FROM_X_Y)


[uncategorized] ~102-~102: Possible missing comma found.
Context: ...gher speed = more frames per second). * Next we convert refresh rate from Hz to mill...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~106-~106: Possible missing comma found.
Context: ...re diffusion = smoother flame spread. * Next we assign SEGMENT.intensity (user inp...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~175-~175: Possible missing preposition found.
Context: ...whether we even attempt to spawn sparks this frame. * hw_random8() gives a rando...

(AI_HYDRA_LEO_MISSING_IN)


[uncategorized] ~206-~206: Possible missing article found.
Context: ...Starting with the current heat value of pixel (x, y) assigned v: * if there’s a p...

(AI_HYDRA_LEO_MISSING_A)


[uncategorized] ~231-~231: Possible missing comma found.
Context: ... color-rendering for each pixel row.) * Next we update the main segment data with th...

(AI_HYDRA_LEO_MISSING_COMMA)


[grammar] ~233-~233: Use the plural noun “” with the number ‘255’.
Context: ...olor` from the current palette with 255 brightness, and no wrapping in palette lookup. *...

(IN_CD_PUNCTUATION)


[typographical] ~235-~235: Consider adding a comma after ‘Finally’ for more clarity.
Context: ... flames (e.g., yellow → red → black). * Finally we set the rendered color for the pixel...

(RB_LY_COMMA)


[grammar] ~237-~237: The word “fallback” is a noun. The verb is spelled with a space.
Context: ...h row. * If palette use is disabled, we fallback to fading a base color. * SEGCOLOR(0)...

(NOUN_VERB_CONFUSION)


[grammar] ~258-~258: Did you mean the adverb/preposition “within”?
Context: ...ines how the effect is to be interacted with in the UI: ```cpp static const char data...

(WITH_IN)


[typographical] ~285-~285: The word “otherwise” is an adverb that can’t be used like a conjunction, and therefore needs to be separated from the sentence.
Context: ...s is enabled, the effect uses a palette ColorFromPalette(), otherwise it fades from SEGCOLOR(0). The first...

(THUS_SENTENCE)


[style] ~287-~287: ‘in conjunction with’ might be wordy. Consider a shorter alternative.
Context: ...s to be selected by the user. But used in conjunction with the checkbox argument, palette use can ...

(EN_WORDINESS_PREMIUM_IN_CONJUNCTION_WITH)


[uncategorized] ~335-~335: Loose punctuation mark.
Context: ...2_t color2 = SEGCOLOR(2); ``` * color1: main moving dot color, chosen from pale...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~336-~336: Loose punctuation mark.
Context: ...he current position as index. * color2: secondary color from user-configured co...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~338-~338: This word is normally spelled with a hyphen.
Context: ... account the optional argument for if a Rainbow colored palette is in use: ```cpp if (rainbow...

(RAINBOW_COLORED)


[style] ~352-~352: ‘takes into account’ might be wordy. Consider a shorter alternative.
Context: ...with the selected color. The next line takes into account another one of the optional arguments f...

(EN_WORDINESS_PREMIUM_TAKES_INTO_ACCOUNT)


[uncategorized] ~352-~352: Possible missing comma found.
Context: ...ect to potentially handle dual mirrored dots which create the animation: ```cpp if...

(AI_HYDRA_LEO_MISSING_COMMA)


[grammar] ~382-~382: The verb form ‘has’ does not seem to match the subject ‘checks’.
Context: ...e first line checks if current position has changed since last frame. (Prevents ho...

(SUBJECT_VERB_AGREEMENT_PLURAL)


[uncategorized] ~382-~382: Possible missing article found.
Context: ...s if current position has changed since last frame. (Prevents holes if the dot move...

(AI_HYDRA_LEO_MISSING_THE)


[uncategorized] ~451-~451: Possible missing comma found.
Context: ...important one that registers the custom effect so WLED knows about it. * 255: Tempor...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~454-~454: Loose punctuation mark.
Context: ...ction. * _data_FX_MODE_DIFFUSIONFIRE: Metadata string stored in PROGMEM, desc...

(UNLIKELY_OPENING_PUNCTUATION)


[grammar] ~474-~474: The verb “add” needs to be in the to-infinitive form.
Context: ...this Usermod So now let's say that you wanted add the effects "Diffusion Fire" and "Sine...

(MISSING_TO_BEFORE_A_VERB)


[style] ~476-~476: Did you mean ‘different from’? ‘Different than’ is often considered colloquial style.
Context: ...ell--and to name it something different than what's already inside the core WLED cod...

(DIFFERENT_THAN)


[duplication] ~480-~480: Possible typo: you repeated a word.
Context: ... Usermod class. * Compile the code! ## Compiling Compiling WLED yourself is beyond the scope of th...

(ENGLISH_WORD_REPEAT_RULE)

🪛 markdownlint-cli2 (0.17.2)
usermods/user_fx/README.md

39-39: Table pipe style
Expected: leading_and_trailing; Actual: leading_only; Missing trailing pipe

(MD055, table-pipe-style)


266-266: Hard tabs
Column: 12

(MD010, no-hard-tabs)


268-268: Hard tabs
Column: 5

(MD010, no-hard-tabs)


269-269: Hard tabs
Column: 5

(MD010, no-hard-tabs)


270-270: Hard tabs
Column: 5

(MD010, no-hard-tabs)


271-271: Hard tabs
Column: 5

(MD010, no-hard-tabs)


272-272: Hard tabs
Column: 5

(MD010, no-hard-tabs)


273-273: Hard tabs
Column: 12

(MD010, no-hard-tabs)


274-274: Hard tabs
Column: 5

(MD010, no-hard-tabs)


275-275: Hard tabs
Column: 5

(MD010, no-hard-tabs)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
usermods/user_fx/README.md (3)

3-6: Fix spelling & tone in the opening paragraph
Minor spelling errors (“depracated”) and conversational phrasing reduce polish.

-This Usermod is a common place to put various user's WLED Effects.  It gives you a way to load in your own custom WLED effects, or to load in depracated WLED effects that you want to bring back--all without having to mess with the core WLED source code.
+This usermod serves as a central place for custom or formerly-deprecated WLED effects, letting you add them without touching the core WLED source code.

24-25: Typo: “abour” → “about”

-We will go into greater detail on how custom effects work in the usermod and how to go abour creating your own in the section below.
+We will go into greater detail on how custom effects work in the usermod and how to go about creating your own in the section below.

266-276: Remove hard tabs and quote parameter names in the metadata table

Hard tabs violate MD010 and render inconsistently. Also quoting the parameter names improves readability.

-| Parameter	| Default tooltip label |
-| :-------- | :-------------------- |
-| sx	       | Effect speed |
-| ix	       | Effect intensity |
-| c1	       | Custom 1 |
-| c2	       | Custom 2 |
-| c3	       | Custom 3 |
-| o1       	| Option 1 |
-| o2	       | Option 2 |
-| o3	       | Option 3 |
+| Parameter | Default tooltip label |
+| :-------- | :-------------------- |
+| `sx` | Effect speed |
+| `ix` | Effect intensity |
+| `c1` | Custom 1 |
+| `c2` | Custom 2 |
+| `c3` | Custom 3 |
+| `o1` | Option 1 |
+| `o2` | Option 2 |
+| `o3` | Option 3 |
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a7225f6 and b208703.

📒 Files selected for processing (1)
  • usermods/user_fx/README.md (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: netmindz
PR: wled/WLED#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.
Learnt from: netmindz
PR: wled/WLED#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.
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.
usermods/user_fx/README.md (13)
Learnt from: netmindz
PR: wled/WLED#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.
Learnt from: netmindz
PR: wled/WLED#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.
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: KrX3D
PR: wled/WLED#4585
File: usermods/seven_segment_display_reloaded_v2/seven_segment_display_reloaded_v2.h:121-137
Timestamp: 2025-04-27T10:06:22.545Z
Learning: In the Seven Segment Display Reloaded usermod, the dimension mismatch between the default array (umSSDRNumbers[11][7]) and the override (umSSDRNumbers[11][10] = umSSDR_NUMBERS) is intentional by design, allowing for different use cases with varying numbers of segments per digit.
Learnt from: KrX3D
PR: wled/WLED#4237
File: usermods/INA219_v2/INA219_v2.cpp:265-276
Timestamp: 2025-04-18T22:27:58.634Z
Learning: When implementing MQTT message handling in WLED usermods, use `strstr(topic, "/specific/path")` instead of `strcmp_P(topic, PSTR("/specific/path"))` to properly match topics that include the device prefix. The full MQTT topic typically follows the pattern `<mqttDeviceTopic>/specific/path`.
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: 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: 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: willmmiles
PR: wled/WLED#4712
File: wled00/FX_fcn.cpp:992-993
Timestamp: 2025-06-07T15:58:42.579Z
Learning: In WLED segments, the backing pixel buffer is always allocated to the full physical segment size, but effect rendering only uses a subset when mirror or grouping are enabled. For 2D segments, this subset is vWidth() * vHeight(), and for 1D segments it's vLength(). Color processing operations like fade_out should iterate over this rendering subset, not the full allocated buffer.
Learnt from: KrX3D
PR: wled/WLED#4585
File: usermods/seven_segment_display_reloaded_v2/seven_segment_display_reloaded_v2.h:121-136
Timestamp: 2025-04-27T09:37:28.415Z
Learning: Using PROGMEM for the seven-segment font array (umSSDRNumbers) in the WLED SSDR usermod causes compilation problems, so it should be left as a regular array.
Learnt from: blazoncek
PR: wled/WLED#4658
File: wled00/led.cpp:90-91
Timestamp: 2025-04-24T09:31:06.879Z
Learning: In the WLED codebase, the `getSegment()` function guards against out-of-bounds segment IDs, and `getFirstSelectedSegId()` falls back to `getMainSegmentId()` if no segments are selected, ensuring no crashes when used through the `setValuesFromFirstSelectedSeg()` macro.
Learnt from: blazoncek
PR: wled/WLED#4658
File: wled00/led.cpp:90-91
Timestamp: 2025-04-24T09:31:06.879Z
Learning: In the WLED codebase, the `getSegment()` function guards against out-of-bounds segment IDs, and `getFirstSelectedSegId()` falls back to `getMainSegmentId()` if no segments are selected, ensuring no crashes when used through the `setValuesFromFirstSelectedSeg()` macro.
Learnt from: blazoncek
PR: wled/WLED#4658
File: wled00/led.cpp:90-91
Timestamp: 2025-04-24T09:31:06.879Z
Learning: In the WLED codebase, the `getSegment()` function guards against out-of-bounds segment IDs by falling back to the main segment ID, and `getFirstSelectedSegId()` falls back to `getMainSegmentId()` if no segments are selected, ensuring no crashes when used through the `setValuesFromFirstSelectedSeg()` macro.
🪛 LanguageTool
usermods/user_fx/README.md

[style] ~20-~20: Consider removing “of” to be more concise
Context: ...area is where you place the FX code for all of the custom effects you want to use. This m...

(ALL_OF_THE)


[style] ~22-~22: As a shorter alternative for ‘able to’, consider using “can”.
Context: ...mods have to be registered so that they are able to be compiled into your binary. We will ...

(BE_ABLE_TO)


[style] ~22-~22: Avoid the passive voice after ‘to be able to’.
Context: ... be registered so that they are able to be compiled into your binary. We will go into grea...

(ABLE_TO_PASSIVE)


[uncategorized] ~33-~33: You might be missing the article “the” here.
Context: ...elColor()` 4. The function is called at current frame rate. Below are some helpful var...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[grammar] ~40-~40: Possible subject-verb agreement error detected.
Context: ...16-bit | These are state variables that persists between function calls, and they are fr...

(PLURAL_THAT_AGREEMENT)


[uncategorized] ~41-~41: A punctuation mark might be missing here.
Context: ...itten by the user for any use case. | | [SEGENV.call](https://github.com/wled/W...

(AI_EN_LECTOR_MISSING_PUNCTUATION)


[uncategorized] ~46-~46: You might be missing the article “the” here.
Context: ...cro that gets user-selected colors from UI, where x is an integer 1, 2, or 3 for p...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[uncategorized] ~47-~47: You might be missing the article “a” here.
Context: ...ecified color. setPixelColor assumes 1D array and requires one positional argum...

(AI_EN_LECTOR_MISSING_DETERMINER_A)


[uncategorized] ~48-~48: Possible missing comma found.
Context: ...y selected palette for a segment. (This function which should be favoured over `ColorFro...

(AI_HYDRA_LEO_MISSING_COMMA)


[style] ~53-~53: Consider removing “of” to be more concise
Context: ...d segment. | Importing wled.h brings all of the variables, files, and functions listed ...

(ALL_OF_THE)


[typographical] ~59-~59: It appears that a comma is missing.
Context: ... Understanding 2D WLED Effects In this section we give some advice to those who are ne...

(DURING_THAT_TIME_COMMA)


[uncategorized] ~63-~63: Use a comma before ‘and’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...le. This file handles all other imports and it has all the global variable declarat...

(COMMA_COMPOUND_SENTENCE)


[uncategorized] ~79-~79: Possible missing comma found.
Context: ...lock contains several constant variable definitions which essentially serve to extract the ...

(AI_HYDRA_LEO_MISSING_COMMA)


[misspelling] ~100-~100: Nonstandard phrase. Did you mean: “from 0 to 255”?
Context: ...MENT.speed (user-controllable parameter from 0–255) to a value between 20 and 80 Hz. * T...

(FROM_X_Y)


[uncategorized] ~102-~102: Possible missing comma found.
Context: ...gher speed = more frames per second). * Next we convert refresh rate from Hz to mill...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~102-~102: You might be missing the article “the” here.
Context: ...e frames per second). * Next we convert refresh rate from Hz to milliseconds. (It’s eas...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[uncategorized] ~106-~106: Possible missing comma found.
Context: ...re diffusion = smoother flame spread. * Next we assign SEGMENT.intensity (user inp...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~128-~128: You might be missing the article “the” here.
Context: ...nd the effect can’t proceed. * It calls previously defined mode_static() fallback effect...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[uncategorized] ~157-~157: The preposition “of” seems more likely in this position.
Context: ...conditional statement in the first line fo code ensures the effect updates on a fi...

(AI_EN_LECTOR_REPLACEMENT_PREPOSITION)


[uncategorized] ~175-~175: Possible missing preposition found.
Context: ...whether we even attempt to spawn sparks this frame. * hw_random8() gives a rando...

(AI_HYDRA_LEO_MISSING_IN)


[uncategorized] ~206-~206: Possible missing article found.
Context: ...Starting with the current heat value of pixel (x, y) assigned v: * if there’s a p...

(AI_HYDRA_LEO_MISSING_A)


[uncategorized] ~231-~231: Possible missing comma found.
Context: ... color-rendering for each pixel row.) * Next we update the main segment data with th...

(AI_HYDRA_LEO_MISSING_COMMA)


[grammar] ~233-~233: Use the plural noun “” with the number ‘255’.
Context: ...olor` from the current palette with 255 brightness, and no wrapping in palette lookup. *...

(IN_CD_PUNCTUATION)


[typographical] ~235-~235: Consider adding a comma after ‘Finally’ for more clarity.
Context: ... flames (e.g., yellow → red → black). * Finally we set the rendered color for the pixel...

(RB_LY_COMMA)


[grammar] ~237-~237: The word “fallback” is a noun. The verb is spelled with a space.
Context: ...h row. * If palette use is disabled, we fallback to fading a base color. * SEGCOLOR(0)...

(NOUN_VERB_CONFUSION)


[grammar] ~258-~258: Did you mean the adverb/preposition “within”?
Context: ...ines how the effect is to be interacted with in the UI: ```cpp static const char data...

(WITH_IN)


[typographical] ~285-~285: The word “otherwise” is an adverb that can’t be used like a conjunction, and therefore needs to be separated from the sentence.
Context: ...s is enabled, the effect uses a palette ColorFromPalette(), otherwise it fades from SEGCOLOR(0). The first...

(THUS_SENTENCE)


[style] ~287-~287: ‘in conjunction with’ might be wordy. Consider a shorter alternative.
Context: ...s to be selected by the user. But used in conjunction with the checkbox argument, palette use can ...

(EN_WORDINESS_PREMIUM_IN_CONJUNCTION_WITH)


[uncategorized] ~303-~303: You might be missing the article “a” here.
Context: ... line of code defines sinelon base as static helper function. This is how all effec...

(AI_EN_LECTOR_MISSING_DETERMINER_A)


[uncategorized] ~335-~335: Loose punctuation mark.
Context: ...2_t color2 = SEGCOLOR(2); ``` * color1: main moving dot color, chosen from pale...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~335-~335: You might be missing the article “a” here.
Context: ...r1`: main moving dot color, chosen from palette using the current position as index. * ...

(AI_EN_LECTOR_MISSING_DETERMINER_A)


[uncategorized] ~336-~336: Loose punctuation mark.
Context: ...he current position as index. * color2: secondary color from user-configured co...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~338-~338: This word is normally spelled with a hyphen.
Context: ... account the optional argument for if a Rainbow colored palette is in use: ```cpp if (rainbow...

(RAINBOW_COLORED)


[style] ~352-~352: ‘takes into account’ might be wordy. Consider a shorter alternative.
Context: ...with the selected color. The next line takes into account another one of the optional arguments f...

(EN_WORDINESS_PREMIUM_TAKES_INTO_ACCOUNT)


[uncategorized] ~352-~352: Possible missing comma found.
Context: ...ect to potentially handle dual mirrored dots which create the animation: ```cpp if...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~362-~362: You might be missing the article “the” here.
Context: ...If color2 is not set (0), fallback to same palette color as color1. * In `rain...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[uncategorized] ~382-~382: You might be missing the article “the” here.
Context: ...pos; } ``` * The first line checks if current position has changed since last frame. ...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[grammar] ~382-~382: The verb form ‘has’ does not seem to match the subject ‘checks’.
Context: ...e first line checks if current position has changed since last frame. (Prevents ho...

(SUBJECT_VERB_AGREEMENT_PLURAL)


[uncategorized] ~382-~382: You might be missing the article “the” here.
Context: ...s if current position has changed since last frame. (Prevents holes if the dot move...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[uncategorized] ~383-~383: You might be missing the article “a” here.
Context: ....aux0) and new position (pos) to ensure smooth continuous trail. * Works in both dir...

(AI_EN_LECTOR_MISSING_DETERMINER_A)


[uncategorized] ~451-~451: Possible missing comma found.
Context: ...important one that registers the custom effect so WLED knows about it. * 255: Tempor...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~454-~454: Loose punctuation mark.
Context: ...ction. * _data_FX_MODE_DIFFUSIONFIRE: Metadata string stored in PROGMEM, desc...

(UNLIKELY_OPENING_PUNCTUATION)


[grammar] ~474-~474: The verb “add” needs to be in the to-infinitive form.
Context: ...this Usermod So now let's say that you wanted add the effects "Diffusion Fire" and "Sine...

(MISSING_TO_BEFORE_A_VERB)


[style] ~476-~476: Did you mean ‘different from’? ‘Different than’ is often considered colloquial style.
Context: ...ell--and to name it something different than what's already inside the core WLED cod...

(DIFFERENT_THAN)


[duplication] ~480-~480: Possible typo: you repeated a word.
Context: ... Usermod class. * Compile the code! ## Compiling Compiling WLED yourself is beyond the scope of th...

(ENGLISH_WORD_REPEAT_RULE)

🪛 markdownlint-cli2 (0.17.2)
usermods/user_fx/README.md

39-39: Table pipe style
Expected: leading_and_trailing; Actual: leading_only; Missing trailing pipe

(MD055, table-pipe-style)


266-266: Hard tabs
Column: 12

(MD010, no-hard-tabs)


268-268: Hard tabs
Column: 5

(MD010, no-hard-tabs)


269-269: Hard tabs
Column: 5

(MD010, no-hard-tabs)


270-270: Hard tabs
Column: 5

(MD010, no-hard-tabs)


271-271: Hard tabs
Column: 5

(MD010, no-hard-tabs)


272-272: Hard tabs
Column: 5

(MD010, no-hard-tabs)


273-273: Hard tabs
Column: 12

(MD010, no-hard-tabs)


274-274: Hard tabs
Column: 5

(MD010, no-hard-tabs)


275-275: Hard tabs
Column: 5

(MD010, no-hard-tabs)

Comment on lines 37 to 52
| Syntax Element | Size | Description |
| :---------------------------------------------- | :----- | :---------- |
| [`SEGMENT.intensity / speed / custom1 etc.`](https://github.com/wled/WLED/blob/main/wled00/FX.h) | 8-bit | These read-only variables help you control aspects of your custom effect using the UI sliders. You can edit these vriables through the UI sliders when WLED is running your effect. (These variables can be controlled by the API as well.)
| [`SEGENV.aux0 / aux1`](https://github.com/wled/WLED/blob/main/wled00/FX.h) | 16-bit | These are state variables that persists between function calls, and they are free to be overwritten by the user for any use case. |
| [`SEGENV.call`](https://github.com/wled/WLED/blob/main/wled00/FX.h) | 32-bit | A counter for how many times this effect function has been invoked since it started. |
| [`strip.now`](https://github.com/wled/WLED/blob/main/wled00/FX.h) | 32-bit | Current timestamp in milliseconds. (Equivalent to `millis()`, but use `strip.now()` instead.) |
| [`SEGLEN / SEG_W / SEG_H`](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp) | 16-bit | These variables are macros that help define the length and width of your LED strip/matrix segment. |
| [`SEGPALETTE`]((https://github.com/danewhero/WLED/blob/user_fx/wled00/FX.h)) | --- | Macro that gets the currently selected palette for the currently processing segment. |
| [`hw_random8()`](https://github.com/wled/WLED/blob/7b0075d3754fa883fc1bbc9fbbe82aa23a9b97b8/wled00/fcn_declare.h#L535) | 8-bit | One of several functions that generates a random integer. |
| `SEGCOLOR(x)` | 32-bit | Macro that gets user-selected colors from UI, where x is an integer 1, 2, or 3 for primary, secondary, and tertiary colors, respectively. |
| [`SEGMENT.setPixelColor`](https://github.com/danewhero/WLED/blob/user_fx/wled00/FX_fcn.cpp) / [`setPixelColorXY`](https://github.com/danewhero/WLED/blob/user_fx/wled00/FX_2Dfcn.cpp) | --- | Fuction that paints a single pixel to your specified color. `setPixelColor` assumes 1D array and requires one positional argument, while `setPixelColorXY` takes two positional arguments (x and y), and then the RBG color value. |
| [`SEGMENT.color_from_palette()`](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp) | 32-bit | Gets a single color from the currently selected palette for a segment. (This function which should be favoured over `ColorFromPalette()`.) |
| [`fade`](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp) | --- | There are several different fade functions that make it easy to accomplish different fading tasks. An example would be `fadeToBlackBy()` which can be used to fade all pixels to black. |
| [`move()`](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp) | --- | Moves/shifts pixels in the desired direction. |
| [`blur / blur2d`](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp) | --- | Blurs all pixels for the desired segment. |

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Table doesn’t render – add trailing pipes, repair links & typos

The MD055 violation breaks table formatting; there are also typos (“vriables”, “Fuction”, “RBG”) and links that point to your personal fork. Suggested rewrite:

-| Syntax Element                                  | Size   | Description |
-| :---------------------------------------------- | :----- | :---------- |
-| [`SEGMENT.intensity / speed / custom1 etc.`](https://github.com/wled/WLED/blob/main/wled00/FX.h)      | 8-bit  | These read-only variables help you control aspects of your custom effect using the UI sliders.  You can edit these vriables through the UI sliders when WLED is running your effect. (These variables can be controlled by the API as well.)
-| [`SEGENV.aux0 / aux1`](https://github.com/wled/WLED/blob/main/wled00/FX.h)                            | 16-bit | These are state variables that persists between function calls, and they are free to be overwritten by the user for any use case. |
-| [`SEGENV.call`](https://github.com/wled/WLED/blob/main/wled00/FX.h)                                   | 32-bit | A counter for how many times this effect function has been invoked since it started. |
-| [`strip.now`](https://github.com/wled/WLED/blob/main/wled00/FX.h)                  | 32-bit | Current timestamp in milliseconds.  (Equivalent to `millis()`, but use `strip.now()` instead.) |
-| [`SEGLEN / SEG_W / SEG_H`](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp)                        | 16-bit | These variables are macros that help define the length and width of your LED strip/matrix segment. |
-| [`SEGPALETTE`]((https://github.com/danewhero/WLED/blob/user_fx/wled00/FX.h))                            | ---    | Macro that gets the currently selected palette for the currently processing segment. |
-| [`hw_random8()`](https://github.com/wled/WLED/blob/7b0075d3754fa883fc1bbc9fbbe82aa23a9b97b8/wled00/fcn_declare.h#L535)                               | 8-bit  | One of several functions that generates a random integer. |
-| `SEGCOLOR(x)`                                   | 32-bit | Macro that gets user-selected colors from UI, where x is an integer 1, 2, or 3 for primary, secondary, and tertiary colors, respectively. |
-| [`SEGMENT.setPixelColor`](https://github.com/danewhero/WLED/blob/user_fx/wled00/FX_fcn.cpp) / [`setPixelColorXY`](https://github.com/danewhero/WLED/blob/user_fx/wled00/FX_2Dfcn.cpp)       | ---    | Fuction that paints a single pixel to your specified color.  `setPixelColor` assumes 1D array and requires one positional argument, while  `setPixelColorXY` takes two positional arguments (x and y), and then the RBG color value. |
-| [`SEGMENT.color_from_palette()`](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp)                  | 32-bit | Gets a single color from the currently selected palette for a segment. (This function which should be favoured over `ColorFromPalette()`.) |
-| [`fade`](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp)                                          | ---    | There are several different fade functions that make it easy to accomplish different fading tasks.  An example would be `fadeToBlackBy()` which can be used to fade all pixels to black.  |
-| [`move()`](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp)                            | ---    | Moves/shifts pixels in the desired direction. |
-| [`blur / blur2d`](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp)                      | ---    | Blurs all pixels for the desired segment. |
+| Syntax element | Size | Description |
+| :------------- | :---: | :---------- |
+| [`SEGMENT.intensity`, `speed`, `custom1` …](https://github.com/WLED/WLED/blob/main/wled00/FX.h) | 8-bit | Variables mapped to UI sliders & JSON API. |
+| [`SEGENV.aux0`, `aux1`](https://github.com/WLED/WLED/blob/main/wled00/FX.h) | 16-bit | User-definable state that persists between frames. |
+| [`SEGENV.call`](https://github.com/WLED/WLED/blob/main/wled00/FX.h) | 32-bit | Invocation counter since effect start. |
+| [`strip.now`](https://github.com/WLED/WLED/blob/main/wled00/FX.h) | 32-bit | Current time in ms (prefer over `millis()`). |
+| [`SEGLEN`, `SEG_W`, `SEG_H`](https://github.com/WLED/WLED/blob/main/wled00/FX_fcn.cpp) | 16-bit | Macros for segment length/width/height. |
+| `SEGPALETTE` | — | Currently selected palette for the segment. |
+| [`hw_random8()`](https://github.com/WLED/WLED/blob/main/wled00/fcn_declare.h) | 8-bit | Fast hardware RNG (0-255). |
+| `SEGCOLOR(x)` | 32-bit | User-selected colors (`x` = 1, 2, 3). |
+| [`SEGMENT.setPixelColor`](https://github.com/WLED/WLED/blob/main/wled00/FX_fcn.cpp) / [`setPixelColorXY`](https://github.com/WLED/WLED/blob/main/wled00/FX_2Dfcn.cpp) | — | Function to paint pixels (1-D / 2-D). |
+| [`SEGMENT.color_from_palette()`](https://github.com/WLED/WLED/blob/main/wled00/FX_fcn.cpp) | 32-bit | Palette helper (preferred over `ColorFromPalette`). |
+| [`fade*`](https://github.com/WLED/WLED/blob/main/wled00/FX_fcn.cpp) | — | Fade utilities (`fadeToBlackBy`, etc.). |
+| [`move()`](https://github.com/WLED/WLED/blob/main/wled00/FX_fcn.cpp) | — | Shifts pixels along the segment. |
+| [`blur`, `blur2d`](https://github.com/WLED/WLED/blob/main/wled00/FX_fcn.cpp) | — | Blur helpers for 1-D/2-D segments. |
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
| Syntax Element | Size | Description |
| :---------------------------------------------- | :----- | :---------- |
| [`SEGMENT.intensity / speed / custom1 etc.`](https://github.com/wled/WLED/blob/main/wled00/FX.h) | 8-bit | These read-only variables help you control aspects of your custom effect using the UI sliders. You can edit these vriables through the UI sliders when WLED is running your effect. (These variables can be controlled by the API as well.)
| [`SEGENV.aux0 / aux1`](https://github.com/wled/WLED/blob/main/wled00/FX.h) | 16-bit | These are state variables that persists between function calls, and they are free to be overwritten by the user for any use case. |
| [`SEGENV.call`](https://github.com/wled/WLED/blob/main/wled00/FX.h) | 32-bit | A counter for how many times this effect function has been invoked since it started. |
| [`strip.now`](https://github.com/wled/WLED/blob/main/wled00/FX.h) | 32-bit | Current timestamp in milliseconds. (Equivalent to `millis()`, but use `strip.now()` instead.) |
| [`SEGLEN / SEG_W / SEG_H`](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp) | 16-bit | These variables are macros that help define the length and width of your LED strip/matrix segment. |
| [`SEGPALETTE`]((https://github.com/danewhero/WLED/blob/user_fx/wled00/FX.h)) | --- | Macro that gets the currently selected palette for the currently processing segment. |
| [`hw_random8()`](https://github.com/wled/WLED/blob/7b0075d3754fa883fc1bbc9fbbe82aa23a9b97b8/wled00/fcn_declare.h#L535) | 8-bit | One of several functions that generates a random integer. |
| `SEGCOLOR(x)` | 32-bit | Macro that gets user-selected colors from UI, where x is an integer 1, 2, or 3 for primary, secondary, and tertiary colors, respectively. |
| [`SEGMENT.setPixelColor`](https://github.com/danewhero/WLED/blob/user_fx/wled00/FX_fcn.cpp) / [`setPixelColorXY`](https://github.com/danewhero/WLED/blob/user_fx/wled00/FX_2Dfcn.cpp) | --- | Fuction that paints a single pixel to your specified color. `setPixelColor` assumes 1D array and requires one positional argument, while `setPixelColorXY` takes two positional arguments (x and y), and then the RBG color value. |
| [`SEGMENT.color_from_palette()`](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp) | 32-bit | Gets a single color from the currently selected palette for a segment. (This function which should be favoured over `ColorFromPalette()`.) |
| [`fade`](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp) | --- | There are several different fade functions that make it easy to accomplish different fading tasks. An example would be `fadeToBlackBy()` which can be used to fade all pixels to black. |
| [`move()`](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp) | --- | Moves/shifts pixels in the desired direction. |
| [`blur / blur2d`](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp) | --- | Blurs all pixels for the desired segment. |
| Syntax element | Size | Description |
| :------------- | :---: | :---------- |
| [`SEGMENT.intensity`, `speed`, `custom1`](https://github.com/WLED/WLED/blob/main/wled00/FX.h) | 8-bit | Variables mapped to UI sliders & JSON API. |
| [`SEGENV.aux0`, `aux1`](https://github.com/WLED/WLED/blob/main/wled00/FX.h) | 16-bit | User-definable state that persists between frames. |
| [`SEGENV.call`](https://github.com/WLED/WLED/blob/main/wled00/FX.h) | 32-bit | Invocation counter since effect start. |
| [`strip.now`](https://github.com/WLED/WLED/blob/main/wled00/FX.h) | 32-bit | Current time in ms (prefer over `millis()`). |
| [`SEGLEN`, `SEG_W`, `SEG_H`](https://github.com/WLED/WLED/blob/main/wled00/FX_fcn.cpp) | 16-bit | Macros for segment length/width/height. |
| `SEGPALETTE` | | Currently selected palette for the segment. |
| [`hw_random8()`](https://github.com/WLED/WLED/blob/main/wled00/fcn_declare.h) | 8-bit | Fast hardware RNG (0–255). |
| `SEGCOLOR(x)` | 32-bit | User-selected colors (`x` = 1, 2, 3). |
| [`SEGMENT.setPixelColor`](https://github.com/WLED/WLED/blob/main/wled00/FX_fcn.cpp) / [`setPixelColorXY`](https://github.com/WLED/WLED/blob/main/wled00/FX_2Dfcn.cpp) || Functions to paint pixels (1-D / 2-D). |
| [`SEGMENT.color_from_palette()`](https://github.com/WLED/WLED/blob/main/wled00/FX_fcn.cpp) | 32-bit | Palette helper (preferred over `ColorFromPalette`). |
| [`fade*`](https://github.com/WLED/WLED/blob/main/wled00/FX_fcn.cpp) | | Fade utilities (`fadeToBlackBy`, etc.). |
| [`move()`](https://github.com/WLED/WLED/blob/main/wled00/FX_fcn.cpp) | | Shifts pixels along the segment. |
| [`blur`, `blur2d`](https://github.com/WLED/WLED/blob/main/wled00/FX_fcn.cpp) | | Blur helpers for 1-D/2-D segments. |
🧰 Tools
🪛 LanguageTool

[grammar] ~40-~40: Possible subject-verb agreement error detected.
Context: ...16-bit | These are state variables that persists between function calls, and they are fr...

(PLURAL_THAT_AGREEMENT)


[uncategorized] ~41-~41: A punctuation mark might be missing here.
Context: ...itten by the user for any use case. | | [SEGENV.call](https://github.com/wled/W...

(AI_EN_LECTOR_MISSING_PUNCTUATION)


[uncategorized] ~46-~46: You might be missing the article “the” here.
Context: ...cro that gets user-selected colors from UI, where x is an integer 1, 2, or 3 for p...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[uncategorized] ~47-~47: You might be missing the article “a” here.
Context: ...ecified color. setPixelColor assumes 1D array and requires one positional argum...

(AI_EN_LECTOR_MISSING_DETERMINER_A)


[uncategorized] ~48-~48: Possible missing comma found.
Context: ...y selected palette for a segment. (This function which should be favoured over `ColorFro...

(AI_HYDRA_LEO_MISSING_COMMA)

🪛 markdownlint-cli2 (0.17.2)

39-39: Table pipe style
Expected: leading_and_trailing; Actual: leading_only; Missing trailing pipe

(MD055, table-pipe-style)

🤖 Prompt for AI Agents
In usermods/user_fx/README.md around lines 37 to 52, the markdown table does not
render correctly due to missing trailing pipes on each line, contains typos such
as "vriables", "Fuction", and "RBG", and has links pointing to a personal fork
instead of the main repository. Fix the table by adding trailing pipes at the
end of each row, correct the typos to "variables", "Function", and "RGB", and
update all links to point to the official WLED main repository instead of the
personal fork.

| `FX_fcn` | ??? | |
| `move()` | ??? | |
| `blur` | ??? | |
| `SEGMENT.intensity / speed / custom1 etc.` | 8-bit | These read-only variables help you control aspects of your custom effect using the UI sliders. You can edit these vriables through the UI sliders when WLED is running your effect. (These variables can be controlled by the API as well.)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

list them all

Copy link
Author

@danewhero danewhero Jul 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alright I'll make this change.
And in the Discord posts, @blazoncek said that SEGMENT.custom3 is 5-bit. Is this true, and if so, why?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because bit(s) were stolen for something else I believe

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, 5bit, the other 3bits in that uint8 are the three checkmarks iirc.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bit packing for esp8266
each bool takes 1 byte, packed, you can stuff 8 bits into byte

| `SEGCOLOR(x)` | --- | Gets user-selected colors from UI, where x is an integer 1, 2, or 3 for primary, secondary, and tertiary colors, respectively. (and how it relates to meta string??) |
| `SEGMENT.setPixelColor / setPixelColorXY` | --- | Fuction that paints a single pixel to your specified color. `setPixelColor` assumes 1D array and requires one positional argument, while `setPixelColorXY` takes two positional arguments (x and y), and then the RBG color value. |
| `SEGPALETTE` | --- | This is the currently selected palette for the currently processing segment. |
| `SEGMENT.color_from_palette()` | ??? | Gets a single color from the currently selected palette for a segment. (This function which should be favoured over `ColorFromPalette()`.) <br />Defined in [FX_fcn.cpp](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp). |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

returns a 32bit color WRGB (4 bytes in this order)

Copy link
Author

@danewhero danewhero Jul 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which one returns the color WRGB. is it color_from_palette()?

Copy link
Collaborator

@DedeHai DedeHai Jul 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any color function from WLED does currently

| `SEGPALETTE` | --- | This is the currently selected palette for the currently processing segment. |
| `SEGMENT.color_from_palette()` | ??? | Gets a single color from the currently selected palette for a segment. (This function which should be favoured over `ColorFromPalette()`.) <br />Defined in [FX_fcn.cpp](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp). |

| `fade` | ??? | There are several different fade functions that make it easy to accomplish different fading tasks; these are all detailed in [FX_fcn.cpp](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp). An example would be `fadeToBlackBy()` which can be used to fade all pixels to black. |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

list the different functions and what they do


| `fade` | ??? | There are several different fade functions that make it easy to accomplish different fading tasks; these are all detailed in [FX_fcn.cpp](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp). An example would be `fadeToBlackBy()` which can be used to fade all pixels to black. |
| `move()` | ??? | Moves/shifts pixels in the desired direction. Defined in [FX_fcn.cpp](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp). |
| `blur / blur2d` | ??? | Blurs all pixels for the desired segment. Defined in [FX_fcn.cpp](https://github.com/wled/WLED/blob/main/wled00/FX_fcn.cpp). |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blur als has the option smear, which does not fade the blurred pixel(s)

@netmindz netmindz changed the title Update README.md Update user_fx usermod README.md Jul 27, 2025
@netmindz netmindz added the documentation documentation should be updated to explain behaviour label Jul 27, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
usermods/user_fx/README.md (1)

37-51: Table still breaks MD055 & contains stale links / typos

The earlier feedback was only partially applied:

  1. Missing trailing pipes (|) on every data row → renders inconsistently.
  2. Rows 44 & 47 still point to your personal fork (danewhero/WLED/blob/user_fx) rather than wled/WLED/main.
  3. Spelling issues: vriables, Fuction, RBG.

Example fix (apply pattern to all rows):

-| [`SEGPALETTE`](https://github.com/danewhero/WLED/blob/user_fx/wled00/FX.h)                            | ---    | Macro that gets the currently selected palette for the currently processing segment. |
+| [`SEGPALETTE`](https://github.com/wled/WLED/blob/main/wled00/FX.h) | — | Retrieves the palette selected for the current segment. |

-| ...setPixelColorXY`](https://github.com/danewhero/WLED/blob/user_fx/wled00/FX_2Dfcn.cpp)       | ---    | Fuction that paints a single pixel to your specified color.  `setPixelColor` assumes 1D array and requires one positional argument, while  `setPixelColorXY` takes two positional arguments (x and y), and then the RBG color value. |
+| ...setPixelColorXY`](https://github.com/wled/WLED/blob/main/wled00/FX_2Dfcn.cpp) | — | Function that paints a single pixel. `setPixelColor` is 1-D; `setPixelColorXY` takes `(x, y)` then the RGB value. |

Don’t forget to add a closing | at the end of every row.

🧹 Nitpick comments (6)
usermods/user_fx/README.md (6)

3-6: Fix intro typos and wording for professionalism

depracateddeprecated, and consider tightening phrasing (“custom WLED effects or deprecated effects you want to revive”). Small polish, big first-impression gains.

-...load in depracated WLED effects that you want to bring back--all without...
+...load in deprecated WLED effects that you want to bring back—all without...

24-25: Correct typo “abour” → “about”

Minor spelling slip.

-We will go into greater detail on how custom effects work in the usermod and how to go abour creating your own in the section below.
+We will go into greater detail on how custom effects work in the usermod and how to go about creating your own in the section below.

297-299: Spell-check heading narrative

tep by stepstep by step.

-we will break this effect down tep by step.
+We will break this effect down step by step.

338-345: Minor wording & grammar

The next part taked into accountThe next part takes into account.

-The next part taked into account the optional argument for if a Rainbow colored palette is in use:
+The next part takes into account the optional argument when a rainbow palette is in use:

461-465: Typo: “instatiation” → “instantiation”

-The final part of this file handles instatiation and initialization:
+The final part of this file handles instantiation and initialization:

480-482: Typo in “official”

-...on the offical WLED documentation website.
+...on the official WLED documentation website.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b208703 and 08fcfdd.

📒 Files selected for processing (1)
  • usermods/user_fx/README.md (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
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: netmindz
PR: wled/WLED#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.
Learnt from: netmindz
PR: wled/WLED#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.
usermods/user_fx/README.md (16)

Learnt from: netmindz
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.

Learnt from: netmindz
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.

Learnt from: willmmiles
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.

Learnt from: KrX3D
PR: #4237
File: usermods/INA219_v2/INA219_v2.cpp:265-276
Timestamp: 2025-04-18T22:27:58.634Z
Learning: When implementing MQTT message handling in WLED usermods, use strstr(topic, "/specific/path") instead of strcmp_P(topic, PSTR("/specific/path")) to properly match topics that include the device prefix. The full MQTT topic typically follows the pattern <mqttDeviceTopic>/specific/path.

Learnt from: blazoncek
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: blazoncek
PR: #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: blazoncek
PR: #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: willmmiles
PR: #4712
File: wled00/FX_fcn.cpp:992-993
Timestamp: 2025-06-07T15:58:42.579Z
Learning: In WLED segments, the backing pixel buffer is always allocated to the full physical segment size, but effect rendering only uses a subset when mirror or grouping are enabled. For 2D segments, this subset is vWidth() * vHeight(), and for 1D segments it's vLength(). Color processing operations like fade_out should iterate over this rendering subset, not the full allocated buffer.

Learnt from: KrX3D
PR: #4585
File: usermods/seven_segment_display_reloaded_v2/seven_segment_display_reloaded_v2.h:121-136
Timestamp: 2025-04-27T09:37:28.415Z
Learning: Using PROGMEM for the seven-segment font array (umSSDRNumbers) in the WLED SSDR usermod causes compilation problems, so it should be left as a regular array.

Learnt from: blazoncek
PR: #4658
File: wled00/led.cpp:90-91
Timestamp: 2025-04-24T09:31:06.879Z
Learning: In the WLED codebase, the getSegment() function guards against out-of-bounds segment IDs, and getFirstSelectedSegId() falls back to getMainSegmentId() if no segments are selected, ensuring no crashes when used through the setValuesFromFirstSelectedSeg() macro.

Learnt from: blazoncek
PR: #4658
File: wled00/led.cpp:90-91
Timestamp: 2025-04-24T09:31:06.879Z
Learning: In the WLED codebase, the getSegment() function guards against out-of-bounds segment IDs, and getFirstSelectedSegId() falls back to getMainSegmentId() if no segments are selected, ensuring no crashes when used through the setValuesFromFirstSelectedSeg() macro.

Learnt from: blazoncek
PR: #4658
File: wled00/led.cpp:90-91
Timestamp: 2025-04-24T09:31:06.879Z
Learning: In the WLED codebase, the getSegment() function guards against out-of-bounds segment IDs by falling back to the main segment ID, and getFirstSelectedSegId() falls back to getMainSegmentId() if no segments are selected, ensuring no crashes when used through the setValuesFromFirstSelectedSeg() macro.

Learnt from: DedeHai
PR: #4682
File: wled00/FX.cpp:8997-9005
Timestamp: 2025-05-09T18:43:15.355Z
Learning: In the WLED codebase, SEGMENT.custom3 is always constrained to the range 0-31 and will not exceed this range.

Learnt from: KrX3D
PR: #4585
File: usermods/seven_segment_display_reloaded_v2/seven_segment_display_reloaded_v2.h:121-137
Timestamp: 2025-04-27T10:06:22.545Z
Learning: In the Seven Segment Display Reloaded usermod, the dimension mismatch between the default array (umSSDRNumbers[11][7]) and the override (umSSDRNumbers[11][10] = umSSDR_NUMBERS) is intentional by design, allowing for different use cases with varying numbers of segments per digit.

Learnt from: KrX3D
PR: #4585
File: usermods/seven_segment_display_reloaded_v2/seven_segment_display_reloaded_v2.cpp:430-435
Timestamp: 2025-04-28T20:51:29.773Z
Learning: In WLED, bri is a global variable used for brightness control.

Learnt from: DedeHai
PR: #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 dxdx + dydy to be a practical concern in particle system effects.

🪛 LanguageTool
usermods/user_fx/README.md

[style] ~20-~20: Consider removing “of” to be more concise
Context: ...area is where you place the FX code for all of the custom effects you want to use. This m...

(ALL_OF_THE)


[style] ~22-~22: As a shorter alternative for ‘able to’, consider using “can”.
Context: ...mods have to be registered so that they are able to be compiled into your binary. We will ...

(BE_ABLE_TO)


[style] ~22-~22: Avoid the passive voice after ‘to be able to’.
Context: ... be registered so that they are able to be compiled into your binary. We will go into grea...

(ABLE_TO_PASSIVE)


[style] ~53-~53: Consider removing “of” to be more concise
Context: ...d segment. | Importing wled.h brings all of the variables, files, and functions listed ...

(ALL_OF_THE)


[style] ~287-~287: ‘in conjunction with’ might be wordy. Consider a shorter alternative.
Context: ...s to be selected by the user. But used in conjunction with the checkbox argument, palette use can ...

(EN_WORDINESS_PREMIUM_IN_CONJUNCTION_WITH)


[style] ~352-~352: ‘takes into account’ might be wordy. Consider a shorter alternative.
Context: ...with the selected color. The next line takes into account another one of the optional arguments f...

(EN_WORDINESS_PREMIUM_TAKES_INTO_ACCOUNT)


[style] ~476-~476: Did you mean ‘different from’? ‘Different than’ is often considered colloquial style.
Context: ...ell--and to name it something different than what's already inside the core WLED cod...

(DIFFERENT_THAN)

🪛 markdownlint-cli2 (0.17.2)
usermods/user_fx/README.md

39-39: Table pipe style
Expected: leading_and_trailing; Actual: leading_only; Missing trailing pipe

(MD055, table-pipe-style)


266-266: Hard tabs
Column: 12

(MD010, no-hard-tabs)


268-268: Hard tabs
Column: 5

(MD010, no-hard-tabs)


269-269: Hard tabs
Column: 5

(MD010, no-hard-tabs)


270-270: Hard tabs
Column: 5

(MD010, no-hard-tabs)


271-271: Hard tabs
Column: 5

(MD010, no-hard-tabs)


272-272: Hard tabs
Column: 5

(MD010, no-hard-tabs)


273-273: Hard tabs
Column: 12

(MD010, no-hard-tabs)


274-274: Hard tabs
Column: 5

(MD010, no-hard-tabs)


275-275: Hard tabs
Column: 5

(MD010, no-hard-tabs)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation documentation should be updated to explain behaviour
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants