A step-by-step guide to flashing (or updating) WLED firmware on an ESP32-C3 over USB, configuring it to drive NeoPixel/WS2812 LEDs, and optionally syncing it to CheerLights so your lights change color along with people all over the world.
Based on the tutorial at nothans.com/updating-wled-binary-on-esp32-c3-devices, updated for WLED v16.0.0 and the
wled/WLEDrepository.
- An ESP32-C3 board. This guide was verified on a GLEDOPTO WLED ESP32 Mini (ESP32-C3, QFN32 rev 0.4, 4 MB flash, CH340 USB-serial). The GPIO pins used below (LED on 10, button on 9) are specific to this board; other controllers wire the strip and button to different pins.
- A strip/string of addressable (WS281x) LEDs. This build was tested with CMLAMP WS2811 5V diffused pixels.
- A USB cable that carries data, not just power.
- Python 3 with
pip(used to installesptool). On Windows, get it from python.org; that installer includespip. - The device's serial (COM) port. See Find your COM port.
Two ways to flash. The easiest path for most people is the official web installer at install.wled.me: plug in, click, done. This guide covers the manual
esptoolmethod, which is handy for scripting, offline flashing, and seeing exactly what's happening.
Plug in the board and identify which serial port it enumerated as.
Windows (PowerShell):
Get-CimInstance Win32_PnPEntity | Where-Object { $_.Name -match 'COM\d+' } | Select-Object NameYou'll see something like USB-SERIAL CH340K (COM4). Note the COMx number.
macOS / Linux:
ls /dev/tty.* /dev/ttyUSB* /dev/ttyACM* 2>/dev/nullesptool is the flashing utility from Espressif. Install it with pip:
python -m pip install --user esptoolVerify it runs:
python -m esptool versionIf
python -m esptoolisn't found afterward, the pipScripts/binfolder may not be on yourPATH. Running it aspython -m esptool(as shown throughout this guide) sidesteps that.
Grab the ESP32-C3 build from the latest WLED release. For v16.0.0 that's:
WLED_16.0.0_ESP32-C3.bin
Direct link: https://github.com/wled/WLED/releases/download/v16.0.0/WLED_16.0.0_ESP32-C3.bin
Which C3 file? Use
WLED_<ver>_ESP32-C3.bin. There's also a...-C3-QIO.binvariant for boards whose flash runs in QIO mode. The plainESP32-C3.binworks on the common DIO boards. If yours won't boot after flashing, try the QIO build.
WLED's release .bin for the C3 is an application image that lives in the
app0 partition at flash offset 0x10000. Flash it with:
python -m esptool --port COM4 --baud 460800 write_flash 0x10000 WLED_16.0.0_ESP32-C3.binReplace COM4 with your port (on macOS/Linux it'll look like
/dev/ttyUSB0 or /dev/tty.usbserial-xxxx).
esptool connects, writes, and then verifies the hash of what it wrote:
Wrote 1267104 bytes ... at 0x00010000
Verifying written data...
Hash of data verified.
Hard resetting via RTS pin...
Why
0x10000and not0x0? The WLED release binary is app-only, so it goes in the app partition at0x10000. It relies on the bootloader and partition table already present on the device, which is the case for any board already running WLED (this is an update). Flashing a fresh/blank chip this way can leave it without a valid partition table. If in doubt, use the web installer, which writes the full image.
Make sure it boots the new firmware. A WLED device alternates between two app slots (
app0/app1) on OTA updates. After a serial flash toapp0, clearing the OTA-select region guarantees the bootloader runs what you just wrote:python -m esptool --port COM4 --baud 460800 erase_region 0xE000 0x2000This does not erase your WiFi credentials or presets.
This repo includes flash.ps1, which does all of the above
(install esptool, download the binary, flash, verify, clear otadata):
./flash.ps1 -Port COM4After flashing, the device reboots into WLED. Connect to its access point (Wi-Fi
network WLED-AP, password wled1234) and browse to
http://4.3.2.1. Open Settings → WiFi & Network, enter your WiFi
credentials, and save. The device reboots and joins your network. From then on
you can reach it at http://wled.local (or the hostname it prints, e.g.
http://wled-xxxxxx.local) or its IP.
All the configuration below lives in the Settings menu:
v16 note: LED and pin setup moved into LED & Hardware (older guides and screenshots call this "LED Preferences").
Then set up the LED strip:
- Open Settings → LED & Hardware.
- In the Hardware setup section, set the LED output's data GPIO to 10.
- Enter your LED count and set the LED type to WS281x.
- Set the color order. WLED defaults to GRB (correct for WS2812), but the WS2811 pixels linked above need RGB. Without it, colors come out swapped (e.g. red shows as green). If you're using different LEDs and colors look wrong, this is the setting to change.
- Save.
To use the onboard button for on/off and presets:
- Still in Settings → LED & Hardware, scroll to the Button setup section.
- Set Button 0 to GPIO 9, type pushbutton.
- Save.
Your LEDs should now respond to WLED's web UI and to the button.
CheerLights is a global "internet of things" project that keeps lights all over the world synced to one color. Anyone can change it by posting to social media, and every connected light follows along. WLED can join in over MQTT.
The CheerLights MQTT broker publishes the current color straight to WLED's normal MQTT topics, so there's nothing custom to configure. Point WLED at the broker and leave the default topics alone.
Open Settings → Sync Interfaces → MQTT and set it up like this:
| Field | Value |
|---|---|
| Enable MQTT | ✔ checked |
| Broker | mqtt.cheerlights.com |
| Port | 1883 |
| Username / Password | (leave blank) |
| Device Topic | wled (WLED default) |
| Group Topic | wled/all (WLED default) |
The Device Topic must be wled, because CheerLights publishes the color to
wled/col. If you leave it at WLED's per-device default (wled/xxxxxx), the
color never arrives.
Then:
- Save.
- Power-cycle the board (unplug it and plug it back in). WLED only connects to the MQTT broker on boot, so a reset is required for the change to take effect.
Once it reconnects, your LEDs change color in real time along with CheerLights.
Try it by posting @cheerlights <color> (e.g. @cheerlights purple) on a
supported platform, and watch the strip follow.
USB power is only good for a handful of pixels. A WS281x LED can draw up to about 60 mA at full white, so 100 pixels can pull ~6 A, far more than a USB port's 0.5–0.9 A. Try to drive that many over USB and the board browns out, which can drop it off the bus mid-boot.
Two things keep this in check:
- Set the current limiter. In Settings → LED & Hardware → Automatic Brightness Limiter, set Maximum Current to match your supply. For USB-only, ~400 mA is safe. WLED then scales brightness to stay under that instead of overdrawing.
- Use an external 5 V supply for anything bright. Inject 5 V and GND into the strip, share ground with the ESP32-C3, and raise the current limit to match the supply (e.g. a 5 V 10 A supply → ~9000 mA).
WLED applies an incoming MQTT color to the selected segment(s) only, so you can point CheerLights at a single pixel and do something else with the rest.
- Open the Segments panel.
- Make segment 0 cover just one LED (start
0, stop1) and leave it selected. This is the pixel CheerLights controls. - Add segment 1 for the remaining LEDs (start
1, stop100), deselect it, and give it an effect such as Fire 2012. Because it isn't selected, CheerLights colors won't touch it. - Save it as a preset, then set that preset as the boot default in Settings → LED & Hardware so it survives a power-cycle.
| Symptom | Fix |
|---|---|
| esptool can't connect / "Failed to connect" | Hold the BOOT button while plugging in (or while esptool says Connecting...), then release. Close any serial monitor using the port. |
| Flashes OK but won't boot | Try the ...-C3-QIO.bin build, or clear otadata (erase_region 0xE000 0x2000). |
| Device boots old firmware | Clear otadata so it boots the slot you flashed (see step 4). |
| Board drops off USB / keeps rebooting with many LEDs | Power brownout. Set the current limiter and give the LEDs their own 5 V supply. See Powering your LEDs. |
| Colors are wrong (red shows as green) | Change the color order (WS2811 usually needs RGB). See step 5. |
| CheerLights color never arrives | Check MQTT is enabled, broker is mqtt.cheerlights.com, and Device Topic is wled. Power-cycle after saving. |
No WLED-AP and not on WiFi |
Do a factory reset from Settings → Security & Update, or re-flash. |
| Wrong COM port | Re-run the detection command in step 1 with the board unplugged, then plugged in, to see which port appears. |
- Firmware: WLED by Christian Schwinne (@Aircoookie) and contributors.
- CheerLights: https://cheerlights.com by Hans Scharler.
- Original tutorial: nothans.com.





