English | Türkçe
A minimal ESP32-S2/S3 firmware that turns a WS2812/NeoPixel LED strip into a native Windows 11 Dynamic Lighting device (HID LampArray) — no companion app, no drivers, no CDC/serial. Windows controls the strip directly through Settings → Personalization → Dynamic Lighting.
This is the standalone, app-free version of the LampArray implementation originally built for CaYaCooler (a smart cooler controller). If you just want Dynamic Lighting on an LED strip and nothing else, this is it.
firmware/CaYaLight/CaYaLight.ino -> the entire firmware (single file)
- Native Windows 11 Dynamic Lighting (HID LampArray) — device shows up as CaYaLight
- Pure HID device: no CDC/serial at all (enabling CDC makes Windows fail to recognize the LampArray device)
- Falls back to a built-in rainbow animation whenever Windows isn't driving it (
autonomousMode) - Single
.inofile, no companion PC app required — Windows' own Dynamic Lighting UI is the only "app" you need
| Part | Note |
|---|---|
| ESP32-S2 or ESP32-S3 dev board | Needs native USB OTG — plain ESP32 (no S2/S3) is not supported. |
| WS2812/NeoPixel LED strip | Default 30 LEDs, wired to GPIO 4. Change LED_PIN / LED_COUNT in the firmware to match your strip. |
Wiring: strip DIN → GPIO4 (a ~330Ω series resistor on DIN is recommended), strip GND ↔ ESP32 GND (common ground required). If the strip draws more current than the board's 5V rail can supply, power it from a separate 5V source and keep grounds common. A 3.3V→5V level shifter on DIN improves signal stability but usually isn't required for short runs.
- Boards Manager → install "esp32" by Espressif, version 3.x (the firmware needs the
ledcAttach-era USB HID API). - Library Manager → install "Adafruit NeoPixel".
- Select your ESP32-S2/S3 board, then set:
- USB Mode: USB-OTG (TinyUSB)
- USB CDC On Boot: Disabled ← required — with CDC enabled, Windows won't recognize the Dynamic Lighting device.
- Open
firmware/CaYaLight/CaYaLight.ino, select the correct port, Upload.
If you previously flashed a board with a broken HID descriptor, unplug it and remove the device from Device Manager before replugging — this clears Windows' cached USB descriptor.
- Plug the board in. Windows should detect a new HID device named CaYaLight.
- Open Settings → Personalization → Dynamic Lighting. The device should appear in the list — enable it.
- Any Dynamic Lighting–aware effect (Windows' built-in effects, or per-app lighting from games/apps that support it) will now drive the strip directly.
- When nothing is actively addressing the lamps, the firmware falls back to a simple built-in rainbow animation so the strip is never left dark.
No PC app, no drivers, no COM port — it's a standard HID LampArray device from Windows' point of view.
- The HID report descriptor is a byte-for-byte copy of Microsoft's verified LampArray example (ArduinoHidForWindows).
- Important fix vs. naive implementations:
LampMultiUpdate/LampRangeUpdate/LampArrayControlare Feature reports (0xB1), not Output reports (0x91). Windows drives the entire LampArray exclusively viaSET_FEATURE/GET_FEATURE— if these are implemented as Output reports, Windows never attaches the driver and the device never shows up under Dynamic Lighting. Handled in_onSetFeature/_onGetFeature. LampMultiUpdatelayout:LampCount(1 byte),LampUpdateFlags(1 byte), 8×LampId(16-bit each), then colors per-lamp interleaved as(R,G,B,I) × 8— not planarR[8],G[8],B[8],I[8].IntensityLevelCount = 1, so the host always sends final RGB values directly; the intensity channel is unused.LampArrayKind = Peripheral (4)gives a colored-grid icon in the Dynamic Lighting UI; change thekvalue insendArrayAttr()to alter it.- Device identity (name, VID/PID) is set via
USB.productName()etc. beforeUSB.begin().
MIT © 2026 Çağan Turgut (CaYatur)
Uses Adafruit NeoPixel (LGPL-3.0) as a separate Arduino library dependency.