ESP32 LED Chaser (Running Light) Experiment
Introduction
This tutorial shows how to create a classic LED chaser (running light) using ESP32 and Arduino. You will learn the hardware wiring, program structure, and several ways to implement the effect, including a more concise version using arrays and loops.
Hardware Design
Bill of Materials (BOM):
| Item | Quantity |
|---|---|
| LED (through-hole) | 5 |
| 1kΩ resistor | 5 |
| Jumper wires | Several |
| Breadboard | 1 |
Each LED anode connects to a separate ESP32 GPIO pin via a 1kΩ resistor; all cathodes connect to GND.

Software Design
1. Basic LED Chaser
The simplest way is to use an array to store the GPIO pins and loop through them to turn each LED on and off in sequence.
// Define GPIO pins for LEDs
const int pin_list[] = {13, 12, 14, 27, 26};
const int size = sizeof(pin_list) / sizeof(pin_list[0]);
void setup() {
for (int i = 0; i < size; i++) {
pinMode(pin_list[i], OUTPUT);
digitalWrite(pin_list[i], LOW); // Ensure all LEDs are off at start
}
}
void loop() {
for (int i = 0; i < size; i++) {
digitalWrite(pin_list[i], HIGH); // Turn on current LED
delay(80);
digitalWrite(pin_list[i], LOW); // Turn off current LED
}
}
Alternative (more concise):
You can use a single variable to track the current LED and update only two pins per step:
const int pin_list[] = {13, 12, 14, 27, 26};
const int size = sizeof(pin_list) / sizeof(pin_list[0]);
int current = 0;
void setup() {
for (int i = 0; i < size; i++) {
pinMode(pin_list[i], OUTPUT);
digitalWrite(pin_list[i], LOW);
}
}
void loop() {
digitalWrite(pin_list[current], HIGH);
digitalWrite(pin_list[(current + size - 1) % size], LOW);
delay(120);
current = (current + 1) % size;
}
2. Bidirectional (Ping-Pong) Chaser
To make the LEDs light up back and forth, use a direction variable:
const int pin_list[] = {13, 12, 14, 27, 26};
const int size = sizeof(pin_list) / sizeof(pin_list[0]);
int current = 0;
int dir = 1;
void setup() {
for (int i = 0; i < size; i++) {
pinMode(pin_list[i], OUTPUT);
digitalWrite(pin_list[i], LOW);
}
}
void loop() {
digitalWrite(pin_list[current], HIGH);
delay(100);
digitalWrite(pin_list[current], LOW);
current += dir;
if (current == size - 1 || current == 0) dir = -dir;
}
3. Moving Light (Single LED Moves)
To create a moving light effect where only one LED is on at a time:
const int pin_list[] = {13, 12, 14, 27, 26};
const int size = sizeof(pin_list) / sizeof(pin_list[0]);
void setup() {
for (int i = 0; i < size; i++) {
pinMode(pin_list[i], OUTPUT);
digitalWrite(pin_list[i], LOW);
}
}
void loop() {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
digitalWrite(pin_list[j], j == i ? HIGH : LOW);
}
delay(180);
}
}
4. Symmetrical (Center-Out) Chaser
This effect lights up LEDs from the center outwards and then back inwards, creating a symmetrical running light:
const int pin_list[] = {13, 12, 14, 27, 26};
const int size = sizeof(pin_list) / sizeof(pin_list[0]);
void setup() {
for (int i = 0; i < size; i++) {
pinMode(pin_list[i], OUTPUT);
digitalWrite(pin_list[i], LOW);
}
}
void loop() {
int mid = size / 2;
// Center out
for (int offset = 0; offset <= mid; offset++) {
for (int i = 0; i < size; i++) digitalWrite(pin_list[i], LOW);
digitalWrite(pin_list[mid - offset], HIGH);
digitalWrite(pin_list[mid + offset], HIGH);
delay(180);
}
// Out to center
for (int offset = mid - 1; offset >= 0; offset--) {
for (int i = 0; i < size; i++) digitalWrite(pin_list[i], LOW);
digitalWrite(pin_list[mid - offset], HIGH);
digitalWrite(pin_list[mid + offset], HIGH);
delay(180);
}
}
5. Random LED Chaser
This effect randomly lights up one LED at a time, creating a dynamic and unpredictable running light:
#include <Arduino.h>
const int pin_list[] = {13, 12, 14, 27, 26};
const int size = sizeof(pin_list) / sizeof(pin_list[0]);
int last = -1;
void setup() {
for (int i = 0; i < size; i++) {
pinMode(pin_list[i], OUTPUT);
digitalWrite(pin_list[i], LOW);
}
randomSeed(analogRead(0));
}
void loop() {
int idx = random(size);
// Avoid lighting the same LED twice in a row
while (idx == last) idx = random(size);
for (int i = 0; i < size; i++) digitalWrite(pin_list[i], LOW);
digitalWrite(pin_list[idx], HIGH);
last = idx;
delay(200);
}