ESP32 UNO - Blink multiple LED

Need three lights flashing at three different rates? With the ESP32 Uno you can blink multiple LEDs at once, and no LED has to wait for another. On the ESP32 Uno form board, the ezLED library tracks the timing for each output, so the loop never stops. You can blink 2 LEDs, 3 LEDs or a whole array of LEDs with the same idea.
By the end, you can:
- Wire three LEDs and three resistors to the D7, D8 and D9 headers
- Blink two or three LEDs at different speeds with no delay()
- Install the ezLED library from the Arduino IDE Library Manager
- Store the LEDs in an array and drive them from one for loop on the ESP32 Uno
Components You Need
Or you can buy the following kits:
| 1 | × | DIYables Sensor Kit (18 sensors/displays) |
Additionally, some of these links are for products from our own brand, DIYables .
Buy Note: Use the LED Module for easier wiring. It includes an integrated resistor.
Good to know: the list shows one of each part. For this build, get three LEDs and three 220 ohm resistors, one pair per output.
LED Basics for This Build
After this part, you know where to learn the single LED circuit that each channel here repeats.
| Item | Detail |
|---|---|
| Part used | Standard 5 mm or 3 mm LED |
| Legs | Long leg is the anode (+), short leg is the cathode (-) |
| Resistor | 220 ohm in series, one per LED |
| Drive level | 3.3V from an ESP32 Uno GPIO |
| Full guide | ESP32 Uno - LED tutorial |
Good to know: ESP32 Uno pins output 3.3V. A red, green or yellow LED still lights well behind 220 ohm, just a bit softer than on a 5V board.
ESP32 Uno Pinout
Your sketch talks to GPIO numbers, while the board shows Uno labels such as D7 or D9. Look up each header in the picture below and write down its GPIO before you add a wire.

How to Connect the LEDs
By the end of this part, three LEDs sit on D7, D8 and D9 and share one ground.

This image is created using Fritzing. Click to enlarge image
| Component Pin | ESP32 Uno Pin |
|---|---|
| LED 1 anode (+) via 220 ohm resistor | D7 (GPIO14) |
| LED 2 anode (+) via 220 ohm resistor | D8 (GPIO12) |
| LED 3 anode (+) via 220 ohm resistor | D9 (GPIO13) |
| Cathode (-) of all three LEDs | GND |
WARNING
LED 2 sits on D8, which is GPIO12 on the ESP32 Uno. GPIO12 is a boot strapping pin and must read LOW when the board powers up. A LED plus resistor going to GND keeps it LOW, so this circuit is normally safe. Never add a pull-up or any part that drives D8 HIGH at power-on, or the flash gets the wrong voltage and the board will not start. If an upload fails, pull the D8 wire out, upload, then put it back.
Three-LED Sketch for the ESP32 Uno
This sketch gives each of the three LEDs its own ON time, OFF time and start delay.
A call to delay() freezes the whole board, so a second LED cannot change while the first one waits. The way out is a time check with millis(): each LED flips only when its own period ends. Writing that bookkeeping by hand for three outputs gets messy fast. The ezLED library keeps the timestamps inside each LED object for you.
Upload and Test
- First time with this board? Set it up with ESP32 Uno - Getting Started before you continue.
- Build the circuit by following the wiring table above.
- Plug in the USB Type-C cable between the ESP32 Uno and your computer.
- Select the board in Arduino IDE: pick ESP32 Dev Module and the COM port of the board (CH340).
- Open the Libraries panel with the Libraries icon on the left edge of the Arduino IDE.
- Type "ezLED" into the search field and locate the LED library from ArduinoGetStarted.
- Press Install to add ezLED.
- Search for ezLED created by ArduinoGetStarted.com and click the Install button.
- Paste the sketch into a new Arduino IDE window.
- Press Upload and wait for "Done uploading".

- Check the three LEDs. LED 1 gives a long flash with a short gap, LED 2 is on and off for equal halves of a second, and LED 3 joins in 0.5 s after the other two.
- Pro tip: set LED 3 to blink(100, 900) for a short "heartbeat" pulse once per second. It makes a handy "sketch is alive" light next to the other two.
Upgrade: Blink Multiple LEDs with an Array
By the end of this part, adding a fourth LED means changing one number and one line.
Each LED in the first sketch needs its own object and its own loop() call. An array of ezLED objects groups them, and a single for loop serves them all.
| Code Part | What It Does |
|---|---|
| NUM_LED | Sets how many LEDs live in the array |
| ledArray[NUM_LED] | Holds one ezLED object per pin (GPIO14, GPIO12, GPIO13) |
| ledArray[i].blink() | Gives one slot its ON time, OFF time and start delay |
| for loop in loop() | Calls loop() on every slot so each LED checks its own timer |
The result is the same light pattern as before, with shorter code. For four LEDs, set NUM_LED to 4 and add one more ezLED(...) entry with the new GPIO.
What Else ezLED Can Do
The ezLED library has more patterns ready to use:
| Feature | Example Use |
|---|---|
| Own speed per LED | A fast warning light next to a slow status light |
| Staggered start | A "running light" effect across a row |
| Blink for a set time | Flash for 5 seconds after an event, then stop |
| Blink a set count | Flash 3 times to show an error code |
Open the examples that ship with the library in the Arduino IDE to try each one.
Video Tutorial
See the ESP32 Uno build in action in the video below.
How the First Sketch Works
By the end of this part, you can read each line of the three-LED sketch.
| Code Part | What It Does |
|---|---|
| #define PIN_LED_x | Maps LED 1, 2 and 3 to GPIO14, GPIO12 and GPIO13 |
| ezLED led1(PIN_LED_1) | Creates one LED object that remembers its own timing |
| led1.blink(800, 200) | 800 ms on, 200 ms off, starts right away |
| led3.blink(500, 500, 500) | 500 ms on, 500 ms off, starts after 500 ms |
| led1.loop() | Checks the clock and flips the LED when its time is up |
Every loop() call returns at once, so the main loop keeps spinning and still has time for other jobs, like reading a sensor.
ESP32 Uno vs UNO R4 for This Project
This part shows what changes when you move these LED sketches from the UNO R4 to the ESP32 Uno.
| Item | Arduino UNO R4 | ESP32 Uno |
|---|---|---|
| Logic voltage | 5V | 3.3V |
| LED 1 pin in code | 7 | 14 (D7) |
| LED 2 pin in code | 8 | 12 (D8, strapping pin) |
| LED 3 pin in code | 9 | 13 (D9) |
| Library | ezLED | ezLED (no change) |
| Arduino IDE board | Arduino UNO R4 WiFi | ESP32 Dev Module |
| WiFi and Bluetooth | WiFi only (R4 WiFi) | WiFi plus Bluetooth Classic and BLE |
The same wiring works as-is. Only the pin numbers in the code change. Keep D8 free of anything that pulls it HIGH at power-on.
Go Wireless: Switch the LEDs from Your Phone
After this part, you have an idea for making the LED project wireless.
The ESP32 Uno has WiFi and Bluetooth on board. Instead of fixed blink patterns, you can turn each LED on or off from a phone. A web page or a Bluetooth app shows one switch per pin, and the board drives GPIO14, GPIO12 and GPIO13 to match.
Try These Next
- Add a fourth LED on D6 (GPIO27) and give it a 300 ms on, 300 ms off pattern.
- Make the three LEDs light one after another like a traffic light, using the start delay in blink().
- Flash LED 2 exactly five times when the board boots, then leave it off.
Troubleshooting
| Problem | Possible Cause | Solution |
|---|---|---|
| No COM port appears in Arduino IDE | CH340 driver missing or a charge-only USB cable | Install the CH340 driver and use a USB cable that carries data |
| Upload stops at "Failed to connect" or "Waiting for download" | The board did not enter download mode | Hold the BOOT button while the upload starts, then let go |
| Board does not boot or upload with the LEDs connected | D8 (GPIO12) is a boot strapping pin pulled the wrong way | Unplug the D8 wire while uploading, or move LED 2 to another pin and change the code |
| One LED stays dark | LED is reversed or a jumper is loose | Turn the LED so the long leg faces the resistor, then press each wire in firmly |
| No LED lights at all | Shared GND wire is missing | Run a wire from the LED cathode row to a GND pin on the board |
| ezLED.h no such file error | Library not installed | Install ezLED from the Library Manager and compile again |
| LEDs blink once and freeze | An LED object misses its loop() call | Call loop() for every LED object inside loop() and remove any delay() |
| LED is weak even with a fresh part | Resistor value is too large for 3.3V | Use 220 ohm, not 1k or more |
FAQ
How do I blink two LEDs at different rates on the ESP32 Uno?
Create one ezLED object per LED and give each its own blink() timing. Then call loop() on both objects inside loop(). Delete the third object if you only use two LEDs.
Why is delay() a bad choice for several blinking LEDs?
delay() stops the whole sketch until the time runs out. While one LED waits, the other LEDs cannot change. A millis() time check, or the ezLED library, lets every LED switch on its own schedule.
Is 3.3V enough to light an LED?
Yes. Red, yellow and green LEDs need about 2V, so 3.3V through a 220 ohm resistor gives a clear light. Blue and white LEDs need about 3V and will look dimmer. You can drop to 100 ohm for those, but never wire an LED without a resistor.
How many LEDs can the ESP32 Uno drive directly?
Each GPIO can drive one small LED at a safe current of a few milliamps. Keep the total current low and use a transistor or LED driver for bright or large LEDs. For many LEDs, a shift register or an addressable LED strip is a better choice.
Is it safe to put an LED on D8 of the ESP32 Uno?
Usually yes. D8 is GPIO12, a strapping pin that must be LOW at power-on. An LED with a resistor to GND keeps it LOW. Problems start only if something pulls D8 HIGH during boot.
Does an old Uno LED sketch run on the ESP32 Uno without edits?
Almost. The logic and the ezLED library stay the same. Only the pin numbers change: the UNO R4 code uses 7, 8, 9, and the ESP32 Uno code uses GPIO 14, 12, 13 for the same headers.
Can I fade the LEDs instead of blinking them?
Yes. All the pins used here support PWM, so analogWrite() works on the ESP32 Uno. The ezLED library also has fade functions you can try.
Can I use the A2 to A5 headers for extra LEDs?
No. On the ESP32 Uno, A2 to A5 are GPIO35, 34, 36 and 39, and they are input only. They cannot drive an LED. Use a free digital header such as D2 (GPIO26) or D6 (GPIO27).
What if my project needs more pins than the Uno headers give?
The ESP32 Uno has a few extra holes near the power header: GPIO32 and GPIO33 (I/O, PWM, analog on ADC1, so they also work while WiFi is on) and GPIO15 (I/O, PWM, analog on ADC2). Add a pin header strip there, then use the plain GPIO number in your sketch. For extra LEDs, GPIO32 and GPIO33 are the best picks. Two warnings: GPIO15 and GPIO0 (the IO0 pin at the unused Uno NC position) are boot strapping pins, and a wrong connection can stop the board from booting or uploading, so use GPIO32/33 first. Also never use the six holes under the digital header (SD0 to SD3, CMD, CLK = GPIO6 to GPIO11), because they connect to the flash chip and using them crashes the board.
Do I need to install a driver before uploading?
This board uses a CH340 USB-to-serial chip. Windows and macOS often need the CH340 driver before the COM port shows up. Linux usually has it built in.
Can I control these LEDs over WiFi with the ESP32 Uno?
Yes. The ESP32 Uno has WiFi and Bluetooth. The Web Digital Pins app gives you an ON/OFF button for each pin in a phone browser, with no app to install.