Version and board
This guide follows WLED 16.0.1, the current release on GitHub. WLED switched from 0.x numbering to 16.0.0 because that release moved the ESP32 builds onto a new platform (ESP-IDF 4.4.8 and Arduino-ESP32 2.0.18). The project recommends every user upgrade to 16.0.1.
The WLED quick start recommends an ESP32 for new builds: it's the more capable chip, and ESP8266 support is coming to an end. The steps below use a classic ESP32 dev board. ESP32-S2, S3 and C3 boards have their own firmware files and different usable pins.
Parts list
- A classic ESP32 development board with at least 4 MB of flash (the web installer doesn't support smaller chips).
- A 5 V addressable strip such as WS2812B, 1 m with 60 LEDs. SK6812 RGBW strips add a dedicated white LED, which gives a cleaner warm white for room lighting than mixing red, green and blue.
- A 5 V power supply sized with the maths below.
- A 500โ1000 ยตF capacitor rated 6.3 V or higher, and a 300โ500 ฮฉ resistor, from Adafruit's NeoPixel best practices.
- Optional: a 74AHCT125 or 74HCT245 level shifter, used when the data wire to the strip can't be kept short.
- Hook-up wire and a USB data cable.
Work out the power budget
WLED's brightness limiter assumes 55 mA per LED at full white for 5 V WS281x strips. That's the default "mA/LED" value for an LED output (settings reference). Multiply it by your LED count for the worst case:
| LEDs | Current at full white | Power at 5 V |
|---|---|---|
| 30 | 1.65 A | 8.25 W |
| 60 | 3.3 A | 16.5 W |
| 144 | 7.92 A | 39.6 W |
| 300 | 16.5 A | 82.5 W |
You have two ways to handle that number. Buy a supply rated above it, or buy a smaller one and set WLED's limiter to the supply's rating so it dims the whole strip to stay under the limit. Don't go much larger than you need: the WLED wiring guide points out that an oversized supply can push far more energy through thin wires if something shorts.
The same guide sets a few hard limits. Never draw more than 1 A through a board's USB port. Consider power injection above about 150 LEDs, using wire no thinner than 22 AWG. Fuse supplies over 100 W, with an inline fuse on the positive lead close to the supply, rated just above the strip's expected draw. Never connect two supplies' positive rails to the same strip; joining their grounds is fine.
Wire the strip
Disconnect everything from power while wiring.
- Supply +5 V to the strip's +5 V.
- Supply GND to the strip's GND and to a GND pin on the ESP32. Without a shared ground the data signal has no reference and the LEDs won't respond, even when the ESP32 runs from USB.
- ESP32 GPIO16 to the strip's Data In, through the 300โ500 ฮฉ resistor. Put the resistor at the strip end of the wire.
- The capacitor across the strip's + and โ terminals, observing its polarity.
- Optional: the ESP32's 5V or VIN pin to supply +5 V, so the board runs from the same supply instead of USB.
GPIO16 is WLED's default for ESP32, and the quick start lists GPIO4, GPIO13 and GPIO16โ33 as usable. Board makers label pins differently, so match the GPIO number on your board's pinout rather than the silkscreen position. Data arrows printed on the strip point away from Data In.
Adafruit adds two habits worth keeping. If the strip and the ESP32 have separate supplies, power the strip first. If you must connect to a live circuit, connect ground first, then +5 V, then data, and disconnect in reverse order.
The ESP32's data output is 3.3 V, while a 5 V strip ideally wants a 5 V data signal. A short wire usually works anyway; if the run to the first LED can't be kept short, put the level shifter in the data line.
Flash WLED
Option 1: the web installer
The WLED web installer flashes the board from the browser. It needs a desktop browser that can open serial ports: Chrome, Edge, Opera, or Firefox 151 or newer. Safari can't be used (Install WLED Binary).
- Connect the ESP32 by USB. Leave the strip's supply off for now.
- Open the installer, select the latest release and click Install.
- Pick the board's serial port in the browser prompt and wait for the flash to finish.
If no port is offered, try a different cable, then install the driver for the board's USB-to-serial chip (CP210x and CH340 are common). On Linux, the port can be listed but still refuse to open until your user is in the group that owns the serial device.
Option 2: esptool
Use this when the browser route isn't available. esptool needs Python 3.10 or newer (esptool installation).
- From the latest release, download
WLED_16.0.1_ESP32.bin, the build for classic ESP32 boards. ESP32-S2, S3 and C3 boards have their own files, listed on the release page. - Download the version 4 bootloader file,
esp32_bootloader_v4.bin, from the link on the Install WLED Binary page. - Connect only the board you mean to flash, so esptool can't pick the wrong one.
python -m pip install esptool
# First install on this board only: the bootloader goes at offset 0x0
python -m esptool --port COM5 write-flash 0x0 esp32_bootloader_v4.bin
# The firmware goes at offset 0x10000
python -m esptool --port COM5 write-flash 0x10000 WLED_16.0.1_ESP32.bin
Replace COM5 with your port (/dev/ttyUSB0 or similar on Linux). The WLED page writes the command as esptool.py, the tool's older name; python -m esptool is the form esptool's documentation says works with every Python install, including Windows Store Python. If esptool sits at Connecting..., hold the board's BOOT button for a few seconds. If flashing still fails, python -m esptool --port COM5 erase-flash wipes the chip, including any WLED settings, before you try again.
For ESP32 boards, WLED's docs warn against ESP Home Flasher, which leaves a very small filesystem and causes problems saving presets.
Check: unplug USB, switch on the strip's supply and reconnect the board. The first 30 LEDs light up orange.
First boot and Wi-Fi
- On a phone or laptop, join the Wi-Fi network WLED-AP. The default password is
wled1234. - Open
wled.meor4.3.2.1in a browser. - Open Config (the gear icon), then WiFi & Network. The WLED wiki still calls this page WiFi Setup. Scan for or type your network name and enter its password, which is case-sensitive.
- Set an mDNS address such as
wled-livingroom. - Change the AP password on the same page (8 to 63 characters).
wled1234is the same on every WLED device, and the access point comes back when the controller can't reach your network. - Click Save & Connect and reconnect your phone or laptop to your home Wi-Fi.
Check: open http://wled-livingroom.local. Once WLED has joined your network, 4.3.2.1 and wled.me stop working. If the .local name doesn't resolve on your device, the WLED app finds the controller on your network, or you can look up its address in your router's DHCP lease list (Networking Fundamentals explains DHCP).
Tell WLED about the strip
Open Config โ LED & Hardware (LED Preferences in the wiki):
- Enable automatic brightness limiter: leave it on, and set Maximum PSU Current to your supply's rating in mA (for example 3000 for a 3 A supply). If the LEDs are powered from the ESP32's 5 V pin, keep it below 1000.
- Under LED outputs, set the first output:
- Type: WS281x RGB for WS2812B, SK6812 RGBW for RGBW strips.
- mA/LED: "55mA (typ. 5V WS281x)" suits the strip in this guide. Choose Custom if your strip's datasheet gives another figure.
- Length: 60, or however many LEDs you have.
- GPIO: 16, matching your wiring.
- Color order: GRB is the default. If red and green come out swapped, try another order.
Save. The top of the page shows the total LED count and a recommended supply for the brightest white, which is a quick check on your power maths. The page also warns that more than 800 LEDs on one output can cause stability or lag problems.
Check: on the main page, pick solid red, then green, then blue. Every LED along the strip should match. Config โ Pin Info, new in WLED 16, lists every pin assignment if you want to confirm the data pin. The same data is available at http://wled-livingroom.local/json/pins.
Lock down the settings
WLED's web interface has no user login, so anyone on your network can change the lights and settings. The options in Config โ Security & Updates close the obvious gaps. That page's settings can only be changed while the OTA lock is off, so start by unlocking it:
- If Lock wireless (OTA) software update is ticked, enter the Passphrase (the default is
wledotaon every device), untick the lock and save. - Set a Settings PIN, an optional 4-digit PIN asked for before any settings page opens. The page warns that it travels unencrypted, so don't reuse a PIN that matters anywhere else.
- Tick Deny access to WiFi settings if locked so the Wi-Fi page can't be changed while the lock is on.
- Leave Only allow update from same network/WiFi ticked. It rejects firmware uploads from other subnets. If the controller sits on a separate IoT or guest VLAN, the page suggests setting a PIN rather than unticking this.
- Type a new passphrase of your own, tick the OTA lock again, and save. While it's locked, firmware can't be replaced over Wi-Fi.
If you enable MQTT later, the settings page notes that the broker username and password are sent over an unencrypted connection, so give WLED its own broker account. Keep the controller on your local network rather than exposing it to the internet.
Segments, presets and timers
Segments split one physical strip into sections that each have their own color, effect and brightness. That suits a strip that runs under a desk and then behind a monitor. On the Segments tab, add a segment and set its start and stop LED numbers.
Presets save the current state under a name and an ID. Set up a look, save it as a new preset on the Presets tab, and you can recall it from the UI, Home Assistant or the API. A playlist steps through several presets on a timer.
Time-controlled presets, under Config โ Time & Macros, apply a preset at a set time or relative to sunrise or sunset. There are up to 8 timers plus sunrise and sunset, and each can be limited to certain weekdays and dates. Sunrise and sunset need your latitude and longitude on the same page, and an accurate clock (NTP is on the same page too). Apply preset at boot, under General settings on the LED & Hardware page, chooses what the strip shows after a power cut.
Home Assistant
Home Assistant's WLED integration needs WLED 0.14.0 or newer, so 16.0.1 qualifies. It usually discovers the controller automatically and shows it as Discovered. If it doesn't, go to Settings โ Devices & services โ Add Integration โ WLED and enter the hostname or IP address.
- With one segment, the strip is a single light entity. With two or more, each segment gets its own light plus a master light for power and overall brightness. The Keep Master Light option keeps the master even with one segment, which helps if automations add and remove segments.
- The integration also adds selects for presets and playlists, an estimated-current sensor when the brightness limiter is on, and an update entity that can install new stable WLED releases.
- Segment names set in WLED aren't used; Home Assistant names segments by number.
- Only a segment's primary color can be set from Home Assistant. For effects that use secondary colors, save the full look as a WLED preset and activate the preset.
If you don't run Home Assistant yet, the Raspberry Pi Setup Guide sets up a Pi that can host it.
Script it with the JSON API
WLED's JSON API accepts a POST of part of its state object to /json/state. From Bash or any shell with curl:
# On at half brightness
curl -X POST "http://wled-livingroom.local/json/state" -H "Content-Type: application/json" -d '{"on":true,"bri":128}'
# First segment to teal
curl -X POST "http://wled-livingroom.local/json/state" -H "Content-Type: application/json" -d '{"seg":[{"col":[[0,255,200]]}]}'
# Apply preset 1
curl -X POST "http://wled-livingroom.local/json/state" -H "Content-Type: application/json" -d '{"ps":1}'
# Toggle on/off and return the new state
curl -X POST "http://wled-livingroom.local/json/state" -H "Content-Type: application/json" -d '{"on":"t","v":true}'
In PowerShell, Invoke-RestMethod avoids the quoting problems JSON has with curl.exe:
Invoke-RestMethod -Method Post -Uri "http://wled-livingroom.local/json/state" -ContentType "application/json" -Body '{"on":true,"bri":128}'
# Device details: version, Wi-Fi and LED count
Invoke-RestMethod -Uri "http://wled-livingroom.local/json/info"
Check: a successful POST returns {"success":true}. Add "v":true to get the full state back instead, as the toggle example does.
Optional: music-reactive effects
Audio reactive effects are part of every official WLED build since 0.15.0, so no special firmware is needed (audio reactive docs).
- Use an I2S digital microphone such as the INMP441. Tie its L/R pin to GND so it sends on the left channel, which WLED reads.
- Analog microphones work on a classic ESP32 but give poor results. On/off "sound sensor" modules (LM393, KY-038, KY-037) can't be used at all.
- Configure the microphone under Config โ Usermods โ AudioReactive, then press the board's reset button. The I2S driver is set up at boot, so a saved change has no effect until a hard reset.
To tune it, the docs suggest selecting the Gravimeter effect, setting Gain to 200 or more, Squelch to 1 and AGC off. In a quiet room, raise Squelch until the LEDs stop reacting to background noise, then lower Gain to around 40 and adjust it while music plays. AGC in Normal mode can then follow volume changes.
Run several controllers together
Under Config โ Sync Interfaces, WLED Broadcast keeps controllers in step:
- Give every controller in the group the same UDP port.
- Choose which of the 8 sync groups each controller sends to and receives from.
- On the controller you'll operate, enable Send notifications on direct change.
- On the others, choose what to apply: brightness, color, effects and palette.
For music effects across several controllers, one ESP32 with a microphone can set AudioReactive to Send and the rest to Receive. It multicasts to 239.0.0.1 on UDP port 11988 by default, and this is how an ESP8266, which has no microphone input, joins in.
Back up and update
Backup: under Backup & Restore on the Security & Updates page, Backup presets and Backup configuration each download a JSON file. Passwords aren't included, so note your Wi-Fi and AP passwords separately. Restoring overwrites what's on the device.
Update over Wi-Fi:
- Take both backups.
- On Security & Updates, enter the OTA passphrase, untick the OTA lock and save.
- Under Software Update, open Update WLED and upload the release binary for your board, for example
WLED_16.0.1_ESP32.bin. - Once the controller restarts, tick the lock again and save.
Home Assistant's update entity is the other route. Reflashing over USB with either method above also works and is the fallback if an update fails.
Troubleshooting
- No LEDs light after flashing. Check the shared ground first, then the data pin number in LED Preferences, then that the wire goes to Data In and not Data Out.
- WLED-AP doesn't appear. Make sure you flashed the binary for your chip; the release lists a separate file for each ESP32 variant. A custom build may also use a different AP name.
4.3.2.1stopped working. That's expected once the controller is on your home network. Use the mDNS address, the WLED app or the IP from your router.- The far end of the strip looks dim or discolored. Add power injection at the far end, using the same supply.
- Red and green are swapped. Change Color order on the LED & Hardware page.
- LEDs flicker. Shorten the data wire or add the level shifter. On LED & Hardware, Show Advanced Settings exposes the choice between the I2S and RMT output drivers; the settings reference suggests trying the other one.
- The update page says "OTA lock active". Unlock it with the passphrase on Security & Updates first.
- Settings on Security & Updates won't save. They only change while the OTA lock is off.
- Firmware upload is rejected from another network. That's the "Only allow update from same network/WiFi" setting. Upload from the controller's own subnet.
- Audio sync drops out or lags. The audio reactive docs suggest disabling WMM (Wi-Fi Multimedia) or QoS on your router, which can interfere with UDP multicast.
Removing or resetting
- Factory reset on Security & Updates (with the OTA lock off) erases all settings and presets but keeps WLED installed.
python -m esptool --port COM5 erase-flashremoves WLED and everything stored on the chip. Flash other firmware afterwards.- Delete the WLED entry under Settings โ Devices & services in Home Assistant before you retire the controller.
- Switch off the strip's supply before changing any wiring.
- Uninstall esptool with
python -m pip uninstall esptoolif you no longer need it.
Next projects
- ESP32 BME280 Weather Station covers Arduino IDE and arduino-cli setup on an ESP32, useful if you want to write your own firmware.
- TinyML Gesture Recognition on Nano 33 BLE Sense or ESP32 trains a motion model that runs offline on a microcontroller.
- Networking Fundamentals explains the subnets and DHCP leases behind finding and isolating IoT devices.



