#voron #v0 #neopixel #klipper #led #led-effect #rainbow-barf #3d-printing
# Overview
The Klipper-side counterpart to [[Voron V0 NeoPixel Power Injection]]: that note covers volts and amps, this one covers `chain_count`, `color_order`, chain ordering, and `led_effect` segmentation on [[V0.4351]].
Presenting symptom (2026-08-27): the Rainbow Barf at the front of the Kirigami bed doesn't behave, and the suspicion was that it needed different `color_order` treatment than a regular NeoPixel. **It doesn't.** The Barf is ordinary WS2812B running GRB like everything else in the chain. The actual problem is that it's being counted as one pixel when it is eight.
# Resources
- [[Voron V0 NeoPixel Power Injection]] — electrical side: injection, fusing, bulk cap, star-power topology
- [[V0.4351]] — printer build note, *Neopixel Chain* section
- [[SKR Pico GPIO Budget And Servo Control]] — what IO is left if a second chain is needed
- [Klipper `[neopixel]` config reference](https://www.klipper3d.org/Config_Reference.html#neopixel)
- [julianschill/klipper-led_effect](https://github.com/julianschill/klipper-led_effect)
- [tanaes/whopping_Voron_mods — Rainbow Barf Logo LED](https://github.com/tanaes/whopping_Voron_mods/blob/main/LEDs/Rainbow_Barf_Logo_LED/Code/stealthburner_led_effects_barf.cfg)
- [Rainbow Barf LED Harness | KB3D Wiki](https://wiki.kb-3d.com/en/home/linneo/voron/harnesses/RainbowBarfLEDHarness)
- [Rainbow Barf LED Toolhead Support for StealthBurner · klippain #164](https://github.com/Frix-x/klippain/issues/164)
# Design
## The Rainbow Barf is eight pixels, not one
This is the core misconception. "Rainbow Barf" names a **PCB carrying 8 individually addressable RGB LEDs**, not a single multi-color LED. Eight separate pixels behind the logo is the entire point of the mod — it's what lets the logo run a gradient across itself rather than glowing one flat color.
Corroborated independently: the LED inventory in [[Voron V0 NeoPixel Power Injection]] lists Rainbow Barf Logo at **8× WS2812B-2020 (LCSC C965555)**, taken from the upstream BOM/CPL rather than from this session's guesswork.
**Consequence of under-counting:** `chain_count` shorter than the physical chain means every LED past that index never receives data. Klipper does not error, warn, or hint — the tail simply stays dark. This is the single easiest NeoPixel fault to misread as a wiring or power problem.
Over-counting is harmless by comparison: surplus bits clock off the end of the chain and vanish. That asymmetry is what makes over-provisioning a safe diagnostic (see [[#Mapping the chain]]).
## RGB vs RGBW — not the problem here
The common StealthBurner gotcha is a mixed chain: 8 RGB Barf pixels plus 2 RGBW toolhead pixels, needing `chain_count: 10` and a mixed `color_order`. **A V0 doesn't have those toolhead LEDs**, and the power note confirms no RGBW anywhere in this build — so plain `color_order: GRB` is correct as-is.
Worth recording anyway, because it's the first thing everyone suspects:
- **Physical ID:** an RGBW die has a visible yellowish phosphor square on it. No yellow patch means RGB.
- **Why it matters structurally:** an RGBW pixel consumes 4 bytes where RGB consumes 3. One mistyped pixel misaligns *every* downstream pixel's data, so the symptom is "everything after this point shows wrong colors" — which looks like a data-integrity or grounding fault, not a config error.
- **Klipper handles mixed chains** with a per-LED comma-separated list, one entry per pixel:
```ini
color_order: GRB, GRB, GRB, GRB, GRB, GRB, GRB, GRB, GRBW, GRBW
```
## Chain inventory — unresolved
Three sources, three different numbers:
| Source | Claim | Total |
|---|---|---|
| `printer.cfg` as flashed | `chain_count: 9` | 9 |
| [[V0.4351]] *Neopixel Chain* section | UFO Front 1 → UFO Bottom 8 → Skirt L 1 → Skirt R 1 | 11 |
| Recollection (2026-08-27) | Barf at bed front + ~7 in the UFO | ~15 if Barf is 8 |
| [[Voron V0 NeoPixel Power Injection]] inventory | 3 Barf + 2 Matchstick + 7 discrete | 51 (planned, includes spares) |
==None of these agree. Do not write a config from any of them — map the chain physically (below) and make the measured result authoritative, then correct the other three notes to match.==
The 51-pixel figure in the power note is a *planned* build including boards that may turn out to be spares; that note already carries its own TODO to reconcile against [[V0.4351]]. Mapping settles both at once.
# Configuration
## Current state (as of 2026-08-27, unmodified)
```ini
[neopixel board_rgb]
pin: gpio24
chain_count: 9
color_order: GRB
initial_RED: 0.0
initial_GREEN: 0.1
initial_BLUE: 0.0
[led_effect rainbow]
autostart: true
frame_rate: 10
leds:
neopixel:board_rgb
layers:
gradient 1 1 top (1.0, 0.0, 0.0),(0.0, 1.0, 0.0),(0.0, 0.0, 1.0)
```
Two problems visible without touching the printer:
1. `chain_count: 9` is almost certainly short — 8 Barf pixels alone nearly exhaust it.
2. `[led_effect rainbow]` addresses `neopixel:board_rgb` with no range, so it spans the **entire** chain. Even with the count fixed, the Barf and the UFO can't be driven independently.
## Target — segmented effects
Once the real boundaries are known, address ranges rather than the whole chain. Indexes below are placeholders pending the mapping:
```ini
[led_effect barf_logo]
leds:
neopixel:board_rgb (1-8)
layers:
gradient 1 1 top (1.0, 0.0, 0.0),(0.0, 1.0, 0.0),(0.0, 0.0, 1.0)
[led_effect ufo_worklight]
leds:
neopixel:board_rgb (9-15)
layers:
static 0 0 top (1.0, 1.0, 1.0)
```
That's the payoff: Barf doing gradient duty while the UFO stays white as a work light.
# Troubleshooting
## Mapping the chain
The only reliable way to settle index → physical LED. Takes about five minutes.
1. **Over-provision** `chain_count: 20` temporarily. Safe in a way that under-counting is not.
2. `FIRMWARE_RESTART`
3. `STOP_LED_EFFECTS` — **critical.** `[led_effect rainbow]` has `autostart: true` and will overwrite anything set manually, making the whole exercise look broken.
4. Blank everything: `SET_LED LED=board_rgb RED=0 GREEN=0 BLUE=0 TRANSMIT=1`
5. Walk the chain one pixel at a time, recording which physical LED lights:
```gcode
SET_LED LED=board_rgb RED=1 GREEN=0 BLUE=0 INDEX=1 TRANSMIT=1
SET_LED LED=board_rgb RED=1 GREEN=0 BLUE=0 INDEX=2 TRANSMIT=1
```
6. The index where nothing lights any more is one past the true chain length.
7. Set `chain_count` to the measured value, restore the effects, and record the segment boundaries below.
## Measured chain map
==Not yet run. Fill in index → physical LED, then set `chain_count` and the `led_effect` ranges from this table.==
| Index | Physical LED | Board |
|---|---|---|
| 1 | | |
| 2 | | |
## If colors are wrong rather than dark
Dark tail = `chain_count` too low. Wrong *colors* from a given point onward = byte misalignment, i.e. an RGBW pixel in a chain declared RGB (or vice versa). Check for the yellow phosphor square before assuming a data or grounding fault — see [[#RGB vs RGBW — not the problem here]].
If colors corrupt only under heavy load (full white), that's a brownout, not a config fault — see [[Voron V0 NeoPixel Power Injection]].
# TODO
- [ ] ==Run the mapping procedure and fill in [[#Measured chain map]].==
- [ ] ==Set `chain_count` to the measured value.==
- [ ] ==Split `[led_effect rainbow]` into per-segment effects using real index ranges.==
- [ ] ==Confirm no RGBW pixels in the chain (check for yellow phosphor) — expected all-RGB per the power note.==
- [ ] ==Correct the *Neopixel Chain* section of [[V0.4351]] once the real counts are known.== It currently says 11.
- [ ] ==Feed the measured count back into the LED inventory in [[Voron V0 NeoPixel Power Injection]]== — resolves that note's open reconciliation TODO and re-sizes the fuse.
# Build Log
## 2026-08-27
- Traced the "Rainbow Barf misconfigured" suspicion to a pixel-count error, not a `color_order` error. Barf is 8 addressable RGB pixels; config counts the whole chain as 9.
- Confirmed Rainbow Barf pixel count against the upstream BOM figure already recorded in [[Voron V0 NeoPixel Power Injection]].
- Established that `color_order: GRB` is correct for this build — no RGBW anywhere.
- Documented the `SET_LED INDEX` mapping procedure, including the `STOP_LED_EFFECTS` prerequisite that makes it work.
- Noted the four-way disagreement in chain inventory across config, [[V0.4351]], recollection, and the power note. Mapping is the tiebreaker.
# References
- [Klipper `[neopixel]` config reference](https://www.klipper3d.org/Config_Reference.html#neopixel) — `chain_count`, `color_order`, per-LED lists
- [Klipper `SET_LED` command reference](https://www.klipper3d.org/G-Codes.html#set_led) — `INDEX`, `TRANSMIT`
- [julianschill/klipper-led_effect — LED_Effect.md](https://github.com/julianschill/klipper-led_effect/blob/master/docs/LED_Effect.md) — range syntax, `STOP_LED_EFFECTS`
> [!note] Provenance
> Built from a chat session on 2026-08-27 alongside the hotend and Squiggly Purge work logged in [[V0.4351]]. Pixel counts are from upstream BOM data, not measured on this printer — the mapping procedure exists precisely because nothing here has been verified against the physical chain yet.