Welcome to ESP32 Core Board repository
9. RGB LED Effects
RGB LED Effects
RGB LED Effects1. RGB LED Effects Overview2. Core Concepts2.1 WS2812B Protocol Key Points2.2 Adafruit NeoPixel Library2.3 Linear Interpolation (Lerp)3. Hardware Dependencies4. Project Architecture and Flow5. Source Code5.1 Header Files and Global Variables5.2 setup() — Initialize NeoPixel5.3 loop() — Color Loop5.4 fadeToColor() — Linear Interpolation Fade6. Operation Flow6.1 Build and Flash6.2 Normal Phenomena6.3 Verification Methods7. Common Problems
1. RGB LED Effects Overview
WS2812B is a single-wire cascadable addressable RGB LED that can control color and brightness through a single data line. This experiment drives the on-board WS2812B (GPIO48), smoothly transitioning between 7 rainbow colors in a loop. The Adafruit NeoPixel library encapsulates the underlying RMT timing, and calling setPixelColor + show updates the color.
Typical Application Scenarios:
| Application Type | Example |
|---|---|
| Consumer Electronics | Ambient lights, gaming peripherals RGB, chassis lighting effects |
| Industrial Indicators | Device status lights (Green=Normal, Red=Fault, Yellow=Standby) |
| Commercial Display | LED strips, pixel matrix screens, advertising light boxes |
| Smart Home | Panel backlight, scene lighting, notification reminder lights |
2. Core Concepts
2.1 WS2812B Protocol Key Points
Single-wire NZR zero-code: Each LED requires 24 bits of data (G→R→B, 8 bits each)
Communication Rate: 800kHz (
NEO_KHZ800), each bit is approximately 1.25μsData Encoding: 1 code = High 0.8μs + Low 0.45μs; 0 code = High 0.4μs + Low 0.85μs
Cascade Method: Each LED consumes the first 24 bits, and the remaining signal is reshaped and forwarded to the next one
Color Order: GRB (Green-Red-Blue), different from common RGB order
ESP32 generates precise pulse timing through the RMT (Remote Control) peripheral without bit-banging to occupy the CPU.
2.2 Adafruit NeoPixel Library
xAdafruit_NeoPixel pixels(LED_NUM, PIN, NEO_GRB + NEO_KHZ800);
pixels.setPixelColor(0, pixels.Color(R, G, B)); // Write frame bufferpixels.show(); // Send via RMT serialpixels.setBrightness(100); // Global brightness 0~255
setPixelColoronly writes to the RAM buffer, andshow()actually sends data to the LED. When batch updating multiple LEDs, callsetPixelColorindividually first, then callshow()only once at the end.
2.3 Linear Interpolation (Lerp)
Smooth transition between two colors, interpolating RGB three channels separately:
xxxxxxxxxxr = r1 + (r2 - r1) × i / stepsg = g1 + (g2 - g1) × i / stepsb = b1 + (b2 - b1) × i / stepsWhere i ranges from 0 to steps, and i/steps is the interpolation ratio (0.0 ~ 1.0)
3. Hardware Dependencies
| Pin | Peripheral | Configuration | Description |
|---|---|---|---|
| GPIO48 | WS2812B | Data Output | Single-wire NZR protocol, 800kHz |
Requires installing the Adafruit NeoPixel library: Arduino IDE → Library Manager → Search "Adafruit NeoPixel" → Install.
4. Project Architecture and Flow
xxxxxxxxxxsetup()├─ Serial.begin(115200) // Serial debug├─ pixels.begin() // Initialize RMT peripheral├─ pixels.setBrightness(100) // Global brightness 100/255└─ pixels.clear() + show() // Turn off all LEDsloop()├─ fadeToColor(current, target, 100 steps, 20ms) // Fade for 2 seconds├─ current_index advances└─ target_index = (target + 1) % 7 // Loop to next colorfadeToColor(from, to, steps, delay)└─ for i=0..steps:├─ r = r1 + (r2-r1)*i/steps // RGB three channel interpolation├─ setPixelColor(0, r, g, b) // Write frame buffer├─ show() // Send data└─ delay(20ms)
5. Source Code
Complete source code: Source Code → Arduino → 1.Basic Peripherals → 9.RGB → 9.RGB.ino
5.1 Header Files and Global Variables
When constructing the Adafruit_NeoPixel object, specify the LED count, pin, and color format. Predefine 7 rainbow colors for loop switching.
xxxxxxxxxx
Adafruit_NeoPixel pixels(LED_NUM, BLINK_GPIO, NEO_GRB + NEO_KHZ800);
const uint32_t colors[] = { pixels.Color(255, 0, 0), // Red pixels.Color(255, 128, 0), // Orange pixels.Color(255, 255, 0), // Yellow pixels.Color(0, 255, 0), // Green pixels.Color(0, 255, 255), // Cyan pixels.Color(0, 0, 255), // Blue pixels.Color(128, 0, 255), // Purple};
int current_index = 0;int target_index = 1;
COLOR_COUNTcalculates the array length at compile time. Adding colors only requires modifying thecolors[]array, and the loop automatically adapts.
5.2 setup() — Initialize NeoPixel
setBrightness(100) proportionally dims all colors to approximately 39%, protecting eyes and reducing power consumption.
xxxxxxxxxxvoid setup() { Serial.begin(115200); pixels.begin(); pixels.setBrightness(100); pixels.clear(); pixels.show();}
clear()writes all zeros to the frame buffer, andshow()sends the all-zero data out, ensuring the LED is off at power-on.
5.3 loop() — Color Loop
Each transition to the next color uses fadeToColor for smooth transition. Index modulo arithmetic automatically loops.
xxxxxxxxxxvoid loop() { Serial.print(" -> "); Serial.println(color_names[target_index]);
fadeToColor(colors[current_index], colors[target_index], FADE_STEPS, FADE_DELAY);
current_index = target_index; target_index = (target_index + 1) % COLOR_COUNT; // Loop back to 0 at end}5.4 fadeToColor() — Linear Interpolation Fade
Extract RGB three channels from the merged uint32_t color, interpolate each independently, then merge and write back to the frame buffer.
xxxxxxxxxxvoid fadeToColor(uint32_t from, uint32_t to, int steps, int stepDelay) { uint8_t r1 = (from >> 16) & 0xFF; // Extract R component uint8_t g1 = (from >> 8) & 0xFF; // Extract G component uint8_t b1 = from & 0xFF; // Extract B component
uint8_t r2 = (to >> 16) & 0xFF; uint8_t g2 = (to >> 8) & 0xFF; uint8_t b2 = to & 0xFF;
for (int i = 0; i <= steps; i++) { uint8_t r = r1 + (r2 - r1) * i / steps; // Linear interpolate R uint8_t g = g1 + (g2 - g1) * i / steps; // Linear interpolate G uint8_t b = b1 + (b2 - b1) * i / steps; // Linear interpolate B
pixels.setPixelColor(0, pixels.Color(r, g, b)); pixels.show(); delay(stepDelay); }}
(r2 - r1) * imultiplies first then divides to avoid integer division truncating to zero early. When extracting colors,>>16 & 0xFFcorresponds to the high byte (G) of the GRB byte order, not the standard RGB order.
6. Operation Flow
6.1 Build and Flash
Arduino Flash Process: See Arduino → 1. Before Development → 2. Build and Flash.
Install library: Arduino IDE → Sketch → Include Library → Manage Libraries → Search "Adafruit NeoPixel" → Install


6.2 Normal Phenomena
After power-on, the LED smoothly transitions in a loop between the seven rainbow colors, with each transition taking approximately 2 seconds.





6.3 Verification Methods
| Operation | Expected Result |
|---|---|
| Power on and observe | Red→Orange→Yellow→Green→Cyan→Blue→Purple→Red, looping endlessly |
Change FADE_STEPS to 20 | Transition speeds up, step effect becomes obvious |
Change FADE_DELAY to 50 | Transition slows down, smoother effect |
7. Common Problems
| Phenomenon | Cause | Solution |
|---|---|---|
| LED does not light up | NeoPixel library not installed or GPIO error | Install Adafruit NeoPixel in Library Manager, confirm GPIO48 |
| Color display incorrect (red turns green) | Color order reversed | NEO_GRB is WS2812's color order, do not use NEO_RGB |
Compilation error: cannot find Adafruit_NeoPixel.h | Library not installed | Search and install in Library Manager |
| Fade looks choppy | steps too small or stepDelay too large | Increase FADE_STEPS or decrease FADE_DELAY |