Skip to content

Fireworks only explode in a single color#5492

Open
RussStringham wants to merge 5 commits intowled:mainfrom
RussStringham:fireworks2
Open

Fireworks only explode in a single color#5492
RussStringham wants to merge 5 commits intowled:mainfrom
RussStringham:fireworks2

Conversation

@RussStringham
Copy link
Copy Markdown

@RussStringham RussStringham commented Apr 9, 2026

I have made several enhancements to the Fireworks 1D effect. The primary enhancement is to make the exposion look more like a real firework. When a firework explodes, it explodes as a single color, not a rainbow. I have also added a new Firewworks palette that consists of the colors most commonly used for real fireworks, with their distribution approximately equal to how common they are (white and yellow are more common than in my palette, but they don't look as impressive in LEDs as they do in real life). Other changes will be described in the code diff.

Summary by CodeRabbit

  • New Features

    • Added a "Fireworks" gradient palette for enhanced color effects
    • Added a "Single Color" option to the exploding fireworks effect
  • Improvements

    • Refined exploding fireworks behavior for more consistent flare and spark color handling
    • Improved palette cache validation to detect palette count changes
    • Increased built-in gradient palette count (slightly raising max custom palette capacity)

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 9, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: fcf205a0-259b-4ab3-944a-4ae7294363fd

📥 Commits

Reviewing files that changed from the base of the PR and between 4f6bdb3 and 85924f7.

📒 Files selected for processing (1)
  • wled00/FX.cpp

Walkthrough

Adds a new "Fireworks" gradient palette, increments gradient palette counts, updates frontend palette-cache validation, and adjusts the Exploding Fireworks effect's initialization and spark color/fade behavior.

Changes

Cohort / File(s) Summary
Palettes & counts
wled00/palettes.cpp, wled00/const.h, wled00/FX_fcn.cpp
Added fireworks_gp and registered it in gGradientPalettes; incremented GRADIENT_PALETTE_COUNT (59→60) affecting derived fixed-palette counts; inserted "Fireworks" into JSON_palette_names. Review palette indexing and any hardcoded palette ranges.
Exploding Fireworks effect
wled00/FX.cpp
Tweaked mode_exploding_fireworks: changed peakHeight initialization range, made sparks share a single random colIndex when SEGMENT.check1 is enabled, and altered spark fade logic to conditionally skip cooling-based green/blue dimming. Inspect explosion color and fade branches.
Frontend palette caching
wled00/data/index.js
loadPalettesData() now validates cached previews against both device signature (vid) and palette count (pcount), and writes pcount to localStorage. Verify cache invalidation and preview regeneration logic.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • DedeHai
  • softhack007
  • blazoncek
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fireworks only explode in a single color' accurately describes the main change—adding single-color explosions to the Fireworks 1D effect, which is the primary objective of the PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment thread wled00/FX.cpp
flare->pos = 0;
flare->posX = SEGMENT.is2D() ? hw_random16(2,cols-3) : (SEGMENT.intensity > hw_random8()); // will enable random firing side on 1D
unsigned peakHeight = 75 + hw_random8(180); //0-255
unsigned peakHeight = 84 + hw_random8(146); // 33% to 90% of 256
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

If the firework goes to the very top, it only explodes down, rather than in both directions. If it is too low, it mostly explodes up.

Comment thread wled00/FX.cpp
c = color_blend(BLACK, spColor, uint8_t(prog - 45));
unsigned cooling = (300 - prog) >> 5;
c.g = qsub8(c.g, cooling);
c.b = qsub8(c.b, cooling * 2);
Copy link
Copy Markdown
Author

@RussStringham RussStringham Apr 9, 2026

Choose a reason for hiding this comment

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

The code comes from the original algorithm code. In that code the firework always explodes as white, then fades to yellow, before fading to black. Where the firework here can be any color. If it is already yellow it doesn't fade at all. If it is blue or green it fades completely before the fade to black even starts.

Copy link
Copy Markdown
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)
wled00/FX_fcn.cpp (1)

2102-2102: Sync related palette-range comments with this new entry.

Line 2102 is correct, but nearby Segment::loadPalette() comments still mention 59 gradients (13-71). Please update those to 60 (13-72) to avoid future off-by-one maintenance errors.

Suggested follow-up diff (outside this changed line)
-  // those are followed by 7 fastled palettes (6-12) and 59 gradient palettes (13-71)
+  // those are followed by 7 fastled palettes (6-12) and 60 gradient palettes (13-72)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@wled00/FX_fcn.cpp` at line 2102, Update the nearby palette-range comments in
Segment::loadPalette() to reflect the new entry by changing the stated number of
gradients from 59 to 60 and the index range from 13-71 to 13-72; locate any
comments or documentation strings in the Segment::loadPalette() implementation
that reference "59 gradients (13-71)" and update them to "60 gradients (13-72)"
so the comments remain consistent with the added palette entry.
wled00/const.h (1)

10-10: Consider enforcing palette-count consistency at compile time.

Line 10 is the right update, but this constant can drift again from gGradientPalettes[], risking out-of-bounds indexed access later. A compile-time assertion would lock this down.

Suggested guard (in palette registry source)
+static_assert(
+  (sizeof(gGradientPalettes) / sizeof(gGradientPalettes[0])) == GRADIENT_PALETTE_COUNT,
+  "GRADIENT_PALETTE_COUNT must match gGradientPalettes[] length");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@wled00/const.h` at line 10, The GRADIENT_PALETTE_COUNT constant can drift
from the actual gGradientPalettes[] size; add a compile-time assertion in the
palette registry/source that compares GRADIENT_PALETTE_COUNT with the computed
element count of gGradientPalettes (e.g.,
sizeof(gGradientPalettes)/sizeof(gGradientPalettes[0]) or std::size) so the
build fails if they differ; place the static_assert near the gGradientPalettes
definition or alongside the palette registry initialization so mismatches are
caught at compile time.
wled00/palettes.cpp (1)

825-886: Add a compile-time count guard for palette registry consistency.

GRADIENT_PALETTE_COUNT is maintained manually in wled00/const.h; a static_assert here would prevent silent drift on future edits.

Proposed diff
 const uint8_t* const gGradientPalettes[] PROGMEM = {
   Sunset_Real_gp,               //13-00 Sunset
   es_rivendell_15_gp,           //14-01 Rivendell
   es_ocean_breeze_036_gp,       //15-02 Breeze
@@
   trafficlight_gp,              //71-58 Traffic Light
   fireworks_gp                  //72-59 Fireworks
 };
+
+static_assert(
+  (sizeof(gGradientPalettes) / sizeof(gGradientPalettes[0])) == GRADIENT_PALETTE_COUNT,
+  "GRADIENT_PALETTE_COUNT must match gGradientPalettes length"
+);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@wled00/palettes.cpp` around lines 825 - 886, Add a compile-time guard that
static_asserts the number of entries in gGradientPalettes matches the maintained
GRADIENT_PALETTE_COUNT from const.h: after the const uint8_t* const
gGradientPalettes[] PROGMEM definition, add a static_assert comparing
(sizeof(gGradientPalettes)/sizeof(gGradientPalettes[0])) to
GRADIENT_PALETTE_COUNT with a helpful message so future edits cannot silently
drift; ensure the file includes the header that defines GRADIENT_PALETTE_COUNT
or that the symbol is visible in this TU.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@platformio.ini`:
- Around line 13-36: default_envs was reduced to only esp32dev which shrinks the
CI build matrix and risks missing board-specific regressions; restore a broader
set of environments in platformio.ini by listing the original common targets
(for example nodemcuv2, esp8266_2m, esp01_1m_full and key esp32 variants such as
esp32dev, esp32s3dev_8MB_qspi) instead of a single entry so CI will build the
full matrix; update the default_envs key (the one currently set to esp32dev) to
include multiple env names separated by commas or spaces to re-enable coverage
for ESP8266 and other ESP32 variants.

---

Nitpick comments:
In `@wled00/const.h`:
- Line 10: The GRADIENT_PALETTE_COUNT constant can drift from the actual
gGradientPalettes[] size; add a compile-time assertion in the palette
registry/source that compares GRADIENT_PALETTE_COUNT with the computed element
count of gGradientPalettes (e.g.,
sizeof(gGradientPalettes)/sizeof(gGradientPalettes[0]) or std::size) so the
build fails if they differ; place the static_assert near the gGradientPalettes
definition or alongside the palette registry initialization so mismatches are
caught at compile time.

In `@wled00/FX_fcn.cpp`:
- Line 2102: Update the nearby palette-range comments in Segment::loadPalette()
to reflect the new entry by changing the stated number of gradients from 59 to
60 and the index range from 13-71 to 13-72; locate any comments or documentation
strings in the Segment::loadPalette() implementation that reference "59
gradients (13-71)" and update them to "60 gradients (13-72)" so the comments
remain consistent with the added palette entry.

In `@wled00/palettes.cpp`:
- Around line 825-886: Add a compile-time guard that static_asserts the number
of entries in gGradientPalettes matches the maintained GRADIENT_PALETTE_COUNT
from const.h: after the const uint8_t* const gGradientPalettes[] PROGMEM
definition, add a static_assert comparing
(sizeof(gGradientPalettes)/sizeof(gGradientPalettes[0])) to
GRADIENT_PALETTE_COUNT with a helpful message so future edits cannot silently
drift; ensure the file includes the header that defines GRADIENT_PALETTE_COUNT
or that the symbol is visible in this TU.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8fd0a75c-618d-43fc-90b9-e1dddb86e54a

📥 Commits

Reviewing files that changed from the base of the PR and between 1914e4e and 6824d7c.

📒 Files selected for processing (6)
  • platformio.ini
  • wled00/FX.cpp
  • wled00/FX_fcn.cpp
  • wled00/const.h
  • wled00/data/index.js
  • wled00/palettes.cpp

Comment thread platformio.ini Outdated
Comment thread platformio.ini
Comment thread wled00/FX.cpp

// Higher values make the clouds move faster.
const uint32_t volSpeed = 1 + SEGMENT.speed;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@RussStringham please revert all "whitespace only" changes. They are not necessary, and will cause problems in case we want to cherry-pick your PR from one branch to another.

Comment thread wled00/FX.cpp
c = color_blend(spColor, WHITE, uint8_t((prog - 300)*5));
} else if (prog > 45) { //fade from spark color to black
c = color_blend(BLACK, spColor, uint8_t(prog - 45));
unsigned cooling = (300 - prog) >> 5;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@coderabbitai is removing this block a user-visible change, or just refactoring?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@softhack007 It’s a user-visible change. That block previously biased the fade-to-black phase by reducing green/blue (a “cooling”/warming shift), so spark tails skewed a bit warmer as they dimmed. With it removed, sparks now fade linearly using the palette color (no extra channel bias), which keeps the per‑explosion color more faithful. You’ll notice it most with blue/white explosions; both 1D and 2D paths are affected. If we want the warmer tail back, we could reintroduce it (or gate it behind a flag) without touching the rest of the logic.


🧠 Learnings used
Learnt from: DedeHai
Repo: wled/WLED PR: 5379
File: wled00/FX.cpp:10865-10865
Timestamp: 2026-03-27T18:33:33.813Z
Learning: Repo: wled/WLED
File: wled00/FX.cpp
Context: Slow Transition effect (mode_slow_transition) UI metadata string _data_FX_MODE_SLOW_TRANSITION
Learning: The “Time (min)” control intentionally does not advertise the special case “0 = 10s” in the label; this shortcut is meant to be discovered by users. Do not suggest adding “0=10s” (or similar) to the label in future reviews.

Learnt from: DedeHai
Repo: wled/WLED PR: 4615
File: wled00/FX.cpp:1814-1817
Timestamp: 2026-03-29T07:49:28.820Z
Learning: WLED wled00/FX.cpp::mode_random_chase(): Advancing the shared PRNG before capturing prevSeed on the first call is intentional to decorrelate initial seeds across effects. Do not suggest moving the snapshot earlier; if needed, add a comment to document this behavior.

Learnt from: BobLoeffler68
Repo: wled/WLED PR: 5293
File: usermods/user_fx/user_fx.cpp:149-151
Timestamp: 2026-01-24T18:51:09.740Z
Learning: In WLED's Spinning Wheel effect (usermods/user_fx/user_fx.cpp), the color scale calculation (SEGENV.aux1) must match the position modulo range. When position uses `pos = (pos_fixed >> 16) % SEGLEN`, the color scale must be `aux1 = (255 << 8) / SEGLEN` to distribute the palette evenly across the full position range. Using vstripLen for color scaling while position uses SEGLEN causes palette colors to cycle too quickly and appear incomplete.

Learnt from: DedeHai
Repo: wled/WLED PR: 5434
File: wled00/colors.cpp:79-83
Timestamp: 2026-03-21T11:43:36.767Z
Learning: In WLED's `color_fade()` (wled00/colors.cpp), the `video=true` path computes `maxc = (maxc>>2) + 1` and only preserves a channel if its value strictly exceeds that threshold (`r > maxc`, etc.). This means very dark non-zero channels (e.g., r==1 or r==2) can be dropped to zero in video mode. This is intentional: it prevents flickering in corner regions of gradients and is an accepted design compromise. Do not flag this as a bug in future reviews.

Learnt from: DedeHai
Repo: wled/WLED PR: 4798
File: wled00/FX.cpp:7531-7533
Timestamp: 2025-08-26T11:51:21.817Z
Learning: In WLED PR `#4798`, DedeHai confirmed that certain gamma-related calls in FX.cpp/FX_fcn.cpp/particle systems are intentional for effect-level shaping (e.g., brightness curves, TV sim, Pride 2015 pre-mix), distinct from final output gamma. Do not flag or remove these in future reviews; add comments when feasible to clarify intent.

Learnt from: DedeHai
Repo: wled/WLED PR: 4615
File: wled00/FX.cpp:10824-10824
Timestamp: 2026-03-29T06:08:02.547Z
Learning: WLED: In wled00/FX.cpp::mode_slow_transition(), the change-detection logic intentionally compares data->currentCCT to SEGMENT.cct (not data->endCCT). SEGMENT.cct is set to currentCCT at the end of each call; comparing to endCCT would re-initialize the transition on each frame and stall CCT blending. Do not propose changing this.

Learnt from: freakintoddles2
Repo: wled/WLED PR: 4904
File: wled00/FX.cpp:3915-3930
Timestamp: 2025-09-02T19:42:57.475Z
Learning: WLED wled00/FX.cpp::mode_percent — For time-based options (% of Minute/Hour/Day), behavior is clock-like: at rollover (elapsed==0) intentionally show SEGLEN lit for one tick to represent completion, then move to 1 LED at the next second. This is by design (not a progress bar) and should not be “fixed”.

Learnt from: BobLoeffler68
Repo: wled/WLED PR: 5109
File: wled00/FX.cpp:3174-3343
Timestamp: 2025-11-27T06:33:11.436Z
Learning: WLED Ants effect (wled00/FX.cpp): The author prefers the current velocity initialization using hw_random16(1000, 5000)/5000.0f, resulting in an effective range of ~3.6–10.0 (with VELOCITY_MIN=2.0, VELOCITY_MAX=10.0), and wants the code kept as-is with comments updated to document this behavior. Avoid suggesting changes to span the full 2.0–10.0 range in future reviews.

Learnt from: netmindz
Repo: wled/WLED PR: 4728
File: wled00/FX.h:378-378
Timestamp: 2025-06-15T09:59:52.720Z
Learning: In WLED's FX.h, MODE_COUNT represents the highest FX_MODE_ ID + 1, not the total count of FX_MODE_ definitions. This is because some effects may have been removed but their IDs are not reused, creating gaps in the numbering sequence. MODE_COUNT is used for array bounds and range checking.

Learnt from: netmindz
Repo: wled/WLED PR: 4728
File: wled00/FX.h:378-378
Timestamp: 2025-06-15T09:59:52.720Z
Learning: In WLED's FX.h, MODE_COUNT represents the highest FX_MODE_ ID + 1, not the total count of FX_MODE_ definitions. This is because some effects may have been removed but their IDs are not reused, creating gaps in the numbering sequence. MODE_COUNT is used for array bounds and range checking.

Learnt from: softhack007
Repo: wled/WLED PR: 5443
File: wled00/FX_fcn.cpp:1277-1277
Timestamp: 2026-03-24T12:10:32.630Z
Learning: In WLED's `WS2812FX::service()` (wled00/FX_fcn.cpp), the old condition `|| (doShow && seg.mode == FX_MODE_STATIC)` was an **inclusion** guard — it caused FX_MODE_STATIC to render only when another segment had already set doShow=true. It did NOT skip or protect FX_MODE_STATIC from rendering. The PR `#5443` simplification removes this condition, meaning FX_MODE_STATIC now renders on every `timeToShow` tick uniformly. This is intentional and not a regression. Do not flag FX_MODE_STATIC special-casing as missing in future reviews of this function.

Learnt from: willmmiles
Repo: wled/WLED PR: 5462
File: wled00/json.cpp:1189-1198
Timestamp: 2026-03-30T15:32:08.847Z
Learning: In WLED's `respondModeData()` (wled00/json.cpp), the 256-character `lineBuffer` limit for effect descriptor strings (getModeData) is an intentional constraint that matches the same 256-char limit used ~6 other places in the codebase. It is not new to this PR and should not be flagged as a regression. Lifting it requires a future refactor (better type system or dynamic buffer).

Learnt from: BobLoeffler68
Repo: wled/WLED PR: 5440
File: usermods/user_fx/user_fx.cpp:1304-1313
Timestamp: 2026-03-25T07:03:35.475Z
Learning: In WLED `mode_dissolveplus` (usermods/user_fx/user_fx.cpp), using `hw_random16(SEGLEN)` to select the survivor pixel index is correct and safe for this 1D-only effect. The 0xFFFF unmapped-entry concern from the physical bus mapping does not apply to 1D segments because virtual indices 0..SEGLEN-1 always map to valid physical LEDs without gaps. Do not flag this as a bug in future reviews of 1D effects.

Learnt from: DedeHai
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2026-02-22T20:40:46.281Z
Learning: At low brightness (<30), color_blend() suffers from integer rounding that destroys RGB channel ratios, causing visible hue shifts during transitions (e.g., greenish tints). This can be fixed by applying hue preservation logic similar to color_fade()'s video mode: add 1 to channels that are non-zero and > 13% of max channel `(channel << 5) > maxc`. This preserves color ratios and prevents premature channel zeroing at low brightness without affecting performance at normal brightness levels.

Learnt from: DedeHai
Repo: wled/WLED PR: 4889
File: wled00/json.cpp:310-310
Timestamp: 2026-03-21T18:12:09.437Z
Learning: In WLED's `deserializeSegment()` (wled00/json.cpp), the blend mode field `seg.blendMode` is intentionally written without a post-read clamp (`getVal(elem["bm"], seg.blendMode)`). Out-of-range or unsupported blend mode values are handled safely in `WS2812FX::blendSegment()` (wled00/FX_fcn.cpp), which defaults to mode 0 for any unsupported value via a bounds check against the `BLENDMODES` constant. Do not flag the missing clamp in deserializeSegment as a bug in future reviews.

Learnt from: DedeHai
Repo: wled/WLED PR: 4615
File: wled00/FXparticleSystem.cpp:598-606
Timestamp: 2026-03-09T19:16:30.985Z
Learning: In WLED's FXparticleSystem.cpp, the particle system (both 1D and 2D) is intentionally RGB-only and does not process or output the white channel. The `fast_color_scaleAdd()` function discards the W byte by design. Even though `CRGBW` is used internally for color representation (e.g., `baseRGB`, palette lookups via `ColorFromPalette`), the W channel is never rendered. Do not flag the missing W channel handling in particle system rendering paths as a bug.

Learnt from: softhack007
Repo: wled/WLED PR: 0
File: :0-0
Timestamp: 2025-12-28T14:06:48.772Z
Learning: In WLED post-commit ee9ac947, the rendering pipeline uses per-segment buffers and per-pixel bus updates. Unmapped (0xFFFF) mapping entries are now skipped in WS2812FX::show() (no “clear to black”), which can leave physical gap LEDs with stale/random colors unless they are explicitly cleared. This is a behavior change from pre-0.16 where a full physical buffer was effectively refreshed each frame.

Learnt from: BobLoeffler68
Repo: wled/WLED PR: 5251
File: usermods/user_fx/user_fx.cpp:146-148
Timestamp: 2026-01-01T07:19:40.244Z
Learning: In the WLED Ants effect (usermods/user_fx/user_fx.cpp), the color alternation logic `antIndex % 3 == 1` is intentional and creates a 1/3 vs 2/3 distribution between SEGCOLOR(0) and SEGCOLOR(2). This unbalanced alternation is by design and should not be changed to a balanced mod 2 alternation.

Learnt from: softhack007
Repo: wled/WLED PR: 5355
File: wled00/util.cpp:635-638
Timestamp: 2026-02-07T16:06:08.677Z
Learning: PSRAM-related compilation guards should enable PSRAM code only for ESP32 variants that actually include PSRAM: ESP32-C61, ESP32-C5, and ESP32-P4. Exclude ESP32-C3, ESP32-C6, and ESP8266 from these guards. Apply this rule across the codebase (not just wled00/util.cpp) by reviewing and updating PSRAM guards/macros in all relevant files (C/C++ headers and sources).

Learnt from: softhack007
Repo: wled/WLED PR: 4893
File: wled00/set.cpp:95-95
Timestamp: 2026-03-14T20:56:46.543Z
Learning: Guideline: Ensure WiFi hostname is set after WiFi.mode() but before WiFi.begin() to avoid default esp-XXXXXX hostname being used in DHCP. This ordering only takes effect after the STA interface exists (so avoid placing hostname setting before initConnection). In WLED, place the hostname configuration inside initConnection() (after WiFi.disconnect(true) and before WiFi.begin()) rather than in earlier boot code like deserializeConfig(). This rule should be applied in code reviews for WLED’s network initialization paths in wled00/*.cpp, and note that on ESP8266 the ordering is less strict but still desirable for consistency.

Learnt from: softhack007
Repo: wled/WLED PR: 4838
File: lib/NeoESP32RmtHI/src/NeoEsp32RmtHIMethod.cpp:30-35
Timestamp: 2026-03-27T12:33:48.499Z
Learning: In C/C++ preprocessor conditionals (`#if`, `#elif`) GCC/Clang treat `&&` as short-circuit evaluated during preprocessing. This means guards like `#if defined(ARDUINO_ARCH_ESP32) && ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)` are safe even if the macro/function-like macro on the RHS (e.g., `ESP_IDF_VERSION_VAL`) is not defined on some targets, because the RHS will not be expanded when the LHS is false (e.g., `defined(...)` evaluates to 0). During code review, avoid flagging such cases as “undefined function-like macro invocation” if they are protected by short-circuiting `defined(...) && ...`/`||` logic; some tools like cppcheck may not model this and can produce false positives. Also, don’t suggest refactoring that moves ESP32-specific includes/headers (e.g., `esp_idf_version.h`) outside of these guarded preprocessor blocks, since that will break targets (e.g., ESP8266) where the headers don’t exist.

Learnt from: softhack007
Repo: wled/WLED PR: 5048
File: wled00/cfg.cpp:673-673
Timestamp: 2026-03-27T21:17:45.980Z
Learning: When calling raw lwIP APIs (e.g., around `ntpUdp.begin()` or any `lwIP`/`tcpip`-layer call) in this codebase on ESP32 Arduino-ESP32 platforms where core locking/checking is enabled, wrap the lwIP call with `LOCK_TCPIP_CORE()` / `UNLOCK_TCPIP_CORE()` from `lwip/tcpip.h`. This prevents thread-safety/core-violation crashes without requiring `sdkconfig` changes.

Learnt from: softhack007
Repo: wled/WLED PR: 5048
File: wled00/cfg.cpp:673-673
Timestamp: 2026-03-27T21:17:45.980Z
Learning: When using lwIP “raw” APIs in WLED on ESP32 (Arduino-ESP32 / IDF 5.5+), don’t rely on LOCK_TCPIP_CORE()/UNLOCK_TCPIP_CORE() unless CONFIG_LWIP_TCPIP_CORE_LOCKING=y is guaranteed. CONFIG_LWIP_CHECK_THREAD_SAFETY=y can trigger the assertion “Required to lock TCPIP core functionality!” when raw lwIP calls occur off the TCPIP thread. If the locking mode isn’t enabled (or can’t be changed via sdkconfig), schedule lwIP work (e.g., ntpUdp.begin() and similar raw lwIP calls) via tcpip_callback() so it runs on the TCPIP thread; this should work regardless of the locking-mode setting. Review any similar raw lwIP usage for correct thread/context handling.

Learnt from: softhack007
Repo: wled/WLED PR: 5048
File: wled00/wled.cpp:698-700
Timestamp: 2026-03-28T01:37:15.541Z
Learning: In this WLED codebase, when using `DEBUG_PRINTLN(F("..."))`, an explicit trailing `\n` inside the `F("...")` string (e.g., `DEBUG_PRINTLN(F("Warning!\n"))`) may be intentional to create a blank line in debug output as a visual separator. During code review, do not automatically flag these as “double newline” or recommend removing the `\n`—first verify with the author/context that the extra newline is deliberate.

Learnt from: willmmiles
Repo: wled/WLED PR: 5462
File: wled00/json.cpp:1189-1198
Timestamp: 2026-03-30T15:32:02.808Z
Learning: When working with WLED strings stored in PROGMEM on ESP8266/ESP32, assume you can’t use `strchr_P` for character scanning. If you need to scan a PROGMEM string for a character (e.g., searching for '@' within effect data), review changes to ensure they perform an explicit RAM copy first (e.g., via `strncpy_P` into a buffer) and then scan in RAM. Avoid proposing incremental/streaming PROGMEM character-by-character scans without a RAM buffer on these targets, since it’s impractical with the available APIs.

Learnt from: DedeHai
Repo: wled/WLED PR: 5464
File: wled00/FX_fcn.cpp:1699-1701
Timestamp: 2026-04-09T07:26:09.816Z
Learning: In WLED’s WLED code, if a pixel/buffer allocation uses `BFRALLOC_NOBYTEACCESS` (and especially on classic ESP32 where byte-level access to IRAM-resident buffers is unsafe), avoid using byte-wise operations like `memset`/`memcpy` on that buffer. Specifically, do not combine `BFRALLOC_CLEAR | BFRALLOC_NOBYTEACCESS` and do not perform `memcpy`/`memset` over `Segment::pixels` (e.g., in `setGeometry()`/`finalizeInit()` or copy ctor/assignment). Instead, use element-wise 32-bit access (loop over `uint32_t*` and assign/copy per element) to ensure 32-bit access only.

Learnt from: DedeHai
Repo: wled/WLED PR: 5464
File: wled00/FX_fcn.cpp:1699-1701
Timestamp: 2026-04-09T09:14:29.218Z
Learning: In WLED, when reviewing ESP32 code that uses pixel buffers allocated with `BFRALLOC_NOBYTEACCESS` (e.g., `WS2812FX::_pixels` and `Segment::pixels`), treat `memset`/`memcpy` on those buffers as an intentionally low-risk, accepted pattern. These buffers are designed to be IRAM-safe for 32-bit-only access, and the Xtensa newlib assembly implementations perform 32-bit word stores for word-aligned, word-multiple-sized buffers (so the IRAM constraint is satisfied in practice). Do not flag `memset`/`memcpy` on `BFRALLOC_NOBYTEACCESS` pixel buffers as a critical bug; if any concern arises, downgrade severity to low and focus on potential future regressions rather than an immediate correctness violation.

Comment thread wled00/data/index.js
try {
var d = JSON.parse(lsPalData);
if (d && d.vid == lastinfo.vid) {
if (d && d.vid == lastinfo.vid && d.pcount == lJson.length) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@RussStringham what is the purpose of this change? is it a bugfix?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The new Fireworks palette didn't display the palette at the bottom of the selector, because the cache wasn't regenerated since the vid didn't change. This forced a cache update for the new palette.

Comment thread wled00/data/index.js
localStorage.setItem("wledPalx", JSON.stringify({
p: palettesData,
vid: lastinfo.vid
vid: lastinfo.vid,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@RussStringham please explain

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

See the comment for line 2815

@softhack007

This comment was marked as resolved.

@coderabbitai

This comment was marked as off-topic.

we need to know if all buidenv compile without error - otherwie this PR cannot get merged.
@DedeHai
Copy link
Copy Markdown
Collaborator

DedeHai commented Apr 10, 2026

you'd need to make your new options a checkmark, the way it is now it is an unacceptable breaking change.
That being said: the PS version of the fireworks already does similar things and much more.

@softhack007 softhack007 added the waiting for feedback addition information needed to better understand the issue label Apr 10, 2026
@RussStringham
Copy link
Copy Markdown
Author

you'd need to make your new options a checkmark, the way it is now it is an unacceptable breaking change. That being said: the PS version of the fireworks already does similar things and much more.

I have added a "Single Color" checkmark option to the fireworks effect, which is off by default. When off it behaves as it always has. When checked, it uses my code.

I'm not familiar with this code base. What is the "PS version of fireworks"?

@DedeHai
Copy link
Copy Markdown
Collaborator

DedeHai commented Apr 11, 2026

I'm not familiar with this code base. What is the "PS version of fireworks"?

the FX called fireworks that have PS in front, PS standing for particle system

@softhack007 softhack007 requested a review from DedeHai April 11, 2026 06:39
@DedeHai
Copy link
Copy Markdown
Collaborator

DedeHai commented Apr 13, 2026

The palette needs to be updated so it is useable for other things.. I have a proposal for an improved one but need to test it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effect enhancement waiting for feedback addition information needed to better understand the issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants