5.1 KiB
5.1 KiB
Neopixel Command Calculator — Web Components Library
Overview
Engineering calculator for finding NeoPixel/addressable LED data transmission limits from single hardware sources. Ships as a CDN-ready Web Components library (Lit + Vite) that can be dropped into any JS app via <script> tag.
Repo: https://theres-a-git-in-this-tea.andrewawesomo.net/andrewadmin/neopixel-command-calculator First hardware profile: ESP32-WROOM-32D
Project Structure
neopixel-command-calculator/
├── index.html # Dev server demo
├── package.json / tsconfig.json / vite.config.ts / vitest.config.ts
├── src/
│ ├── index.ts # Entry point — exports + registers all components
│ ├── data/
│ │ ├── protocols.ts # WS2812B, SK6812, APA102, WS2811 timing specs
│ │ └── hardware-profiles.ts # ESP32-WROOM-32D (8 RMT channels, 2 SPI buses)
│ ├── engine/
│ │ ├── types.ts # TimingBreakdown, MaxLedsResult, StrandPlanResult, etc.
│ │ ├── timing.ts # Pure functions: calcDataTimeUs, calcMaxLeds, calcRefreshRate
│ │ └── strand-optimizer.ts # Multi-strand distribution across hardware channels
│ ├── components/
│ │ ├── max-leds.ts # <neopixel-max-leds>
│ │ ├── refresh-explorer.ts # <neopixel-refresh-explorer>
│ │ ├── strand-planner.ts # <neopixel-strand-planner>
│ │ └── shared/
│ │ ├── timing-bar.ts # Stacked bar chart (data | reset | idle)
│ │ ├── math-breakdown.ts # Expandable "show the math" section
│ │ └── styles.ts # CSS custom properties (--npc-accent, --npc-bg, etc.)
│ └── utils/
│ └── format.ts # Number/unit formatting helpers
└── test/
└── engine/
├── timing.test.ts
└── strand-optimizer.test.ts
Three Calculator Components
1. <neopixel-max-leds> — Max LED Count Calculator
- Inputs: protocol, strand count, target refresh rate (Hz), hardware profile
- Outputs: max LEDs per strand, total LEDs, data rate utilization %, timing breakdown
- Shows the math: bit time x bits per LED x LED count vs available frame time
2. <neopixel-refresh-explorer> — Refresh Rate Explorer
- Inputs: LED count per strand, protocol, hardware profile
- Outputs: achievable refresh rates, timing budget visualization (bar chart: data | reset | idle)
- Interactive slider for LED count with real-time refresh rate updates
3. <neopixel-strand-planner> — Multi-Strand Planner
- Inputs: total LED count, protocol, hardware profile
- Outputs: optimal strand split across RMT/SPI channels, per-strand timing, aggregate refresh rate
- Shows which ESP32 pins/peripherals each strand uses
Key Timing Math
One-wire protocols (WS2812B, SK6812, WS2811)
frameBudgetUs = 1,000,000 / targetRefreshHz
maxLeds = floor((frameBudgetUs - resetTimeUs) / (bitsPerLed * bitPeriodNs / 1000))
Example: WS2812B at 30Hz:
- frameBudget = 33,333 us
- dataTimePerLed = 24 bits * 1250ns / 1000 = 30.0 us
- maxLeds = floor((33,333 - 50) / 30.0) = 1,109 LEDs
SPI protocols (APA102)
Clock-dependent, includes start/end frame overhead. At 8MHz SPI / 30Hz -> ~8,203 LEDs (raw timing).
Multi-strand parallel output
All RMT channels transmit simultaneously. Aggregate refresh = 1M / max(frameTimeUs).
- 300 WS2812B on 3 strands -> 327Hz vs 110Hz single strand
Protocol Data
| Protocol | Bits/LED | Bit Period (ns) | Reset (us) | Signal |
|---|---|---|---|---|
| WS2812B | 24 | 1250 | 50 | one-wire |
| SK6812 RGB | 24 | 1250 | 80 | one-wire |
| SK6812 RGBW | 32 | 1250 | 80 | one-wire |
| WS2811 800kHz | 24 | 1250 | 50 | one-wire |
| WS2811 400kHz | 24 | 2500 | 50 | one-wire |
| APA102 | 32 | varies (SPI clock) | 0 | spi |
ESP32-WROOM-32D Hardware Profile
- 8 RMT channels (one-wire protocols, assignable to most GPIOs)
- 2 SPI buses: HSPI (GPIO 13), VSPI (GPIO 23) for APA102-style
- DMA-enabled operation assumed (ESP-IDF 4.4+)
- Default GPIO suggestions: 16, 17, 18, 19, 21, 22, 23, 25 for RMT
Technology Stack
- Framework: Web Components via Lit 3.x
- Build: Vite library mode (ES + UMD bundles)
- Language: TypeScript
- Testing: Vitest for engine unit tests
- Distribution: CDN/script tag — single JS bundle, zero external deps for consumers
Build Output
dist/neopixel-command-calculator.es.js— ES moduledist/neopixel-command-calculator.umd.js— UMD for<script>tag- Lit bundled in (not a peer dep)
Theming
CSS custom properties with --npc-* prefix. Consumers override at any ancestor level:
neopixel-max-leds {
--npc-accent: #ff6b6b;
--npc-bg: #0d1117;
--npc-text: #e6edf3;
}
Implementation Phases
- Foundation — Data models, calculation engine, unit tests
- Shared UI — CSS custom properties, timing-bar, math-breakdown, formatters
- Calculator Components — All three components + dev server demo
- Build + Ship — Vite library mode, UMD bundle test, push to Gitea