yahboom
HomeLearn
Solution
Blog
Online Store
About Us
EN/中文
ESP32 Core Board📖
1. ESP32 Introduction
  • 1. ESP32S3 Overview
  • 2. Environment Setup Introduction
  • 3. Dev Board Introduction
2. ESP-IDF Development Tutorial
1. Before Development
  • 1. Environment Setup (Windows)
  • 2. Environment Setup (Linux)
  • 3. Build and Flash
2. Basic Peripherals
  • 1. LED Control
  • 2. Button Detection
  • 3. Peripheral Interrupts
  • 4. ESP_TIMER
  • 5. GPTIMER
  • 6. Watchdog Timer
  • 7. DMA
  • 8. ADC
  • 9. PWM Breathing LED
  • 10. RGB LED Effects
3. Serial Communication and Storage System
  • 1. Serial UART Communication Experiment
  • 2. I2C_OLED Display Experiment
  • 3. SPI Bus Communication Experiment
  • 4. PSRAM External Memory Experiment
  • 5. Flash Read and Write Experiment
  • 6. USB Emulated Mass Storage Experiment
4. FreeRTOS operating system
  • 1.FreeRTOS Core Concepts Theory
  • 2.Task Creation and Management
  • 3.Queue
  • 4.Binary Semaphore
  • 5.Mutex
  • 6.Event Groups
  • 7.Software Timer
  • 8.Task Scheduler
  • 9.Low Power Mode
  • 10.Deadlock
  • 11.Priority Inversion
5. Network Protocols and Wireless Communication
  • 1. WIFI Network Basics
  • 2. WIFI STA Mode
  • 3. WIFI AP Mode
  • 4. UDP Client Experiment
  • 5. UDP Server Experiment
  • 6. TCP Client Experiment
  • 7. TCP Server Experiment
  • 8. Socket Programming Basics
  • 9. HTTP Client Experiment
  • 10. HTTP Server Experiment
  • 11. MQTT IoT Communication Protocol
  • 12. WIFI OTA Upgrade
  • 13. Bluetooth Fundamentals
  • 14. Bluetooth Slave Mode
  • 15. Bluetooth Master Mode
6. Audio Applications
  • 1.I2S Microphone Recording and U-Disk Playback
  • 2.I2S Audio Playback Experiment
  • 3.Repeater Experiment
7. Xiaozhi AI Voice
  • 1. Burn Xiaozhi Firmware
  • 2. Network and Configuration
  • 3. AI Agent Settings
  • 4. Program Analysis
  • 5. Free Chat
3. Arduino Development Course
1. Before Development
  • 1. Environment Setup
  • 2. Build and Flash
2. Basic Peripherals
  • 1. LED Control
  • 2. Button Detection
  • 3. Peripheral Interrupts
  • 4. ESP_TIMER
  • 5. GPTIMER
  • 6. Watchdog Timer
  • 7. ADC
  • 8. PWM Breathing LED
  • 9. RGB LED Effects
3. Serial Communication and Storage System
  • 1. Serial UART Communication
  • 2. I2C OLED Display
  • 3. SPI Bus Communication
  • 4. Flash Read and Write
  • 5. USB Emulated Mass Storage
4. Network Protocols and Wireless Communication
  • 1. WIFI Network Basics
  • 2. WIFI STA Mode
  • 3. WIFI AP Mode
  • 4. UDP Server Experiment
  • 5. UDP Client Experiment
  • 6. TCP Client Experiment
  • 7. TCP Server Experiment
  • 8. HTTP Client Experiment
  • 9. HTTP Server Experiment
  • 10. MQTT IoT Communication Protocol
  • 11. WIFI OTA Upgrade
  • 12. Bluetooth Fundamentals
  • 13. Bluetooth Slave Mode
  • 14. Bluetooth Master Mode
5. Audio Applications
  • 1.I2S Microphone Recording and U-Disk Playback
  • 2.I2S Audio Playback Experiment
  • 3.Repeater Experiment
4. MicroPython Development Course
1. Before Development
  • 1. Environment Setup
  • 2. Build and Flash
  • 3. Thonny IDE
2. Basic Peripherals
  • 1. LED Control
  • 2. Button Detection
  • 3. Peripheral Interrupts
  • 4. TIMER_IT
  • 5. Watchdog Timer
  • 6. ADC
  • 7. PWM Breathing LED
  • 8. RGB LED Effects
3. Serial Communication and Storage System
  • 1. Serial UART Communication Experiment
  • 2. I2C_OLED Display Experiment
  • 3. SPI Bus Communication Experiment
  • 4. Flash Read and Write Experiment
  • 5. Print Storage
4. Network Protocols and Wireless Communication
  • 1. WIFI Network Basics
  • 2. WIFI STA Mode
  • 3. WIFI AP Mode
  • 4. UDP Client Experiment
  • 5. UDP Server Experiment
  • 6. TCP Client Experiment
  • 7. TCP Server Experiment
  • 8. HTTP Client Experiment
  • 9. HTTP Server Experiment
  • 10. MQTT
  • 11. Bluetooth Fundamentals
  • 12. Bluetooth Slave Mode
  • 13. Bluetooth Master Mode
5. Audio Applications
  • 1. I2S Audio Playback Experiment
  • 2. Repeater Experiment
Download
  • Code
  • Hardware_Info
  • 3D_Model_File
  • Software_Tools
  • VMware
  • VM_File
Download ZIP

Welcome to ESP32 Core Board repository

10. RGB LED Effects

RGB LED Effects


RGB LED Effects1. WS2812 Overview2. Core Concepts2.1 WS2812 Communication Protocol2.2 RMT Peripheral — Protocol Simulator2.3 led_strip Component Introduction2.4 Rainbow 7-Color Definition3. Project Architecture and Flow4. Hardware Dependencies4.1 Method 1: Open Terminal to Download Official Library:4.2 Method 2: Open idf_component.yml File in main Folder:5. Source Code Analysis5.1 Color Data Structure5.2 led_strip Initialization5.3 Main Loop — Color Switching6. Operation Flow6.1 Hardware Preparation6.2 Build and Flash6.3 Normal Output7. Common Issues


1. WS2812 Overview

WS2812 is an addressable smart LED with integrated control chip and RGB LED. Through a single data line, hundreds of LEDs can be cascade-controlled. Each LED has independent RGB color value (0~255 per channel), supporting 16.77 million colors. Widely used in light strips, ambiance lights, pixel screens, and other scenarios.

This experiment uses RMT (Remote Control Transceiver) peripheral to simulate WS2812 communication protocol, driving one WS2812 to cycle through 7 rainbow colors.

WS2812 Characteristics:

FeatureDescription
Communication InterfaceSingle wire (no clock line), asynchronous self-synchronization
Data Format24-bit color (G+R+B each 8-bit, GRB order)
Cascade CapabilityInfinite cascade (each LED forwards data, ≤1024 typical)
Refresh Rate~30Hz (1024 LEDs) ~2kHz (single LED)
Working Voltage3.5~5.3V (data signal recommended ≥3.3V)

Typical Application Scenarios:

Application TypeExample
Consumer electronicsAmbiance lights, gaming peripherals RGB, chassis lighting effects
Industrial indicationEquipment status lights (green=normal, red=fault, yellow=standby)
Commercial displayLED strips, pixel matrix screens, advertisement light boxes
Smart homePanel backlight, scene lighting, notification lights

2. Core Concepts

2.1 WS2812 Communication Protocol

WS2812 uses Non-Return-to-Zero (NRZ) encoding, using different duty cycles to represent 0 and 1:

​x
1-bit encoding:
  "0" code: ┌──┐ ┌────────────────────  (high ~0.4µs, low ~0.85µs)
             └──┘ └────────────────────

  "1" code: ┌─────┐ ┌────────────────  (high ~0.8µs, low ~0.45µs)
             └─────┘ └────────────────

RESET code: ──────────────────────────  (low >50µs, indicates frame end)

Data Frame Structure (single LED):

xxxxxxxxxx
[G7..G0] [R7..R0] [B7..B0]  →  RESET (≥50µs low level)
├── 24-bit GRB data ──┤

Send order: MSB first, each byte high bit first
Each bit takes ~1.25µs, 24-bit totals ~30µs

WS2812 is GRB order, not RGB. Chip datasheet specifies native color order as Green → Red → Blue. Filling RGB values will cause color disorder.

2.2 RMT Peripheral — Protocol Simulator

RMT was originally for infrared remote control, but it's essentially a programmable digital waveform generator, precisely controlling duration of each high/low pulse. WS2812's 1-bit encoding can be perfectly represented by RMT's pulse sequence:

xxxxxxxxxx
RMT configuration:
  Resolution: 10MHz → 1 tick = 0.1µs
  WS2812 "0": high 4 tick (0.4µs), low 8 tick (0.85µs)
  WS2812 "1": high 8 tick (0.8µs), low 4 tick (0.45µs)

Why use RMT instead of SPI or bit-bang?

SolutionAdvantageDisadvantage
RMT (this experiment)Hardware auto-generates precise timing, no CPU waitingOccupies one RMT channel (8 available)
SPIFaster speedNeeds MOSI pin + WS2812 protocol adaptation
Bit-bang (GPIO)Any GPIO, no resource limitOccupies CPU, timing jitter large, not recommended

2.3 led_strip Component Introduction

ESP-IDF Component Manager provides espressif/led_strip component, encapsulating WS2812's underlying RMT/SPI operations:

APIFunction
led_strip_new_rmt_device()Create RMT-driven WS2812 instance
led_strip_set_pixel()Set RGB value for specified pixel
led_strip_refresh()Refresh display (send data to LED)
led_strip_clear()Clear all pixels (all off)

led_strip component is introduced through IDF Component Manager (idf_component.yml), automatically downloaded during compilation.

2.4 Rainbow 7-Color Definition

xxxxxxxxxx
Color    G      R      B      Visual effect
─────────────────────────────────────────────
Red       0    150      0     Pure red
Orange   60    150      0     Red+green → orange
Yellow  150    150      0     Red+green full → yellow
Green   150      0      0     Pure green
Cyan    150      0    150     Green+blue → cyan
Blue      0      0    150     Pure blue
Purple    0    120    150     Red+blue → purple

Brightness set to 150 instead of 255 because WS2812 at 255 full brightness has high power consumption and is glaring. 150 at ~59% brightness is more comfortable for experiment environment while reducing power supply ripple.


3. Project Architecture and Flow

xxxxxxxxxx
app_main()
  ├─ led_strip_new_rmt_device()   Create RMT WS2812 device
  │   strip_config: GPIO48, 1 LED, WS2812, GRB format
  │   rmt_config:    10MHz resolution, DMA disabled
  │
  ├─ led_strip_clear()            All off initial state
  │
  └─ while(1) Main Loop
      ├─ printf("Current color: %s")    Print current color name
      ├─ led_strip_set_pixel(0, R, G, B) Set pixel 0 RGB
      ├─ led_strip_refresh()             Refresh display (send data)
      ├─ color_index++                   Switch to next color
      └─ vTaskDelay(1000ms)             Color switch interval

Data Flow:

xxxxxxxxxx
rainbow_colors[color_index]  Color array (struct {G,R,B})
        ↓
led_strip_set_pixel(0, R, G, B)  Set pixel 0 RGB value
        ↓
led_strip_refresh()  Trigger RMT send
        ↓
RMT hardware: Convert 24-bit GRB data to pulse sequence
        ↓
GPIO48 → WS2812 DIN  → LED displays new color

4. Hardware Dependencies

Hardware Connection:

PinPeripheralDescription
GPIO48WS2812 data line (DIN)RMT pulse output
VDD (5V/3.3V)WS2812 VCCPower (3.3V can light up but dimmer)
GNDCommon groundESP32-S3 GND ↔ WS2812 GND

Dependencies: freertos, led_strip (espressif/led_strip via IDF Component Manager)

4.1 Method 1: Open Terminal to Download Official Library:

  1. Open ESP-IDF terminal

打开ESP-IDF终端

  1. Enter download command in input box

输入下载指令

4.2 Method 2: Open idf_component.yml File in main Folder:

选择idf_component.yml文件

写依赖库

Add led_strip library: Execute the following command in project directory, IDF Component Manager will automatically download and manage dependency.

xxxxxxxxxx
idf.py add-dependency "espressif/led_strip^3.0.3"

5. Source Code Analysis

5.1 Color Data Structure

First define basic constants—which IO LED is connected to, how many LEDs, how many colors to cycle. Then store each color's RGB value in array, because WS2812's data order is GRB (green→red→blue), so green is written first in struct. Finally configure a string array of color names for serial printing.

xxxxxxxxxx
#define BLINK_GPIO             48
#define LED_NUM                1
// Number of colors: 7
#define COLOR_COUNT            7
typedef struct {
    uint8_t green, red, blue;
} led_color_t;

// Seven rainbow colors (GRB format)
static const led_color_t rainbow_colors[] = {
    {  0, 150,   0 },   // Red     (G=0, R=150, B=0)
    { 60, 150,   0 },   // Orange  (G=60, R=150, B=0)
    {150, 150,   0 },   // Yellow  (G=150, R=150, B=0)
    {150,   0,   0 },   // Green   (G=150, R=0, B=0)
    {150,   0, 150 },   // Cyan    (G=150, R=0, B=150)
    {  0,   0, 150 },   // Blue    (G=0, R=0, B=150)
    {  0, 120, 150 },   // Purple  (G=0, R=120, B=150)
};

// Color names (printf, English only)
static const char *color_names[] = {
    "Red", "Orange", "Yellow", "Green", "Cyan", "Blue", "Purple"
};

Struct member order is green, red, blue: Matches WS2812's native GRB order. When code calls led_strip_set_pixel(0, color.red, color.green, color.blue), the RGB order passed is handled internally by led_strip because LED_STRIP_COLOR_COMPONENT_FMT_GRB is configured.

5.2 led_strip Initialization

Initialization in two steps: first configure LED parameters (pin, number, model, color format), second configure RMT parameters (clock resolution, whether to use DMA). Then call led_strip_new_rmt_device() to create device handle, then led_strip_clear() to turn all LEDs off, ensuring powered-on state is deterministic.

xxxxxxxxxx
void app_main(void)
{
    led_strip_config_t strip_config = {
        .strip_gpio_num          = BLINK_GPIO,    // GPIO48
        .max_leds                = LED_NUM,        // 1 LED
        .led_model               = LED_MODEL_WS2812,
        .color_component_format  = LED_STRIP_COLOR_COMPONENT_FMT_GRB,
        // Non-inverted output
        .flags.invert_out        = false,
    };
    led_strip_rmt_config_t rmt_config = {
        // 10MHz = 0.1µs/tick (100ns precision)
        .resolution_hz  = 10 * 1000 * 1000,
        // No DMA (only 1 LED)
        .flags.with_dma = false,
    };

    ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip));
    // Initial all off
    led_strip_clear(led_strip);

Why 10MHz? WS2812 timing precision requirement is within ±150ns. 10MHz (100ns/tick) provides sufficient precision, while not having frequency too high causing RMT memory (64 entries/channel) insufficient to store one frame of data.

Why with_dma = false? Only 1 LED needs 24 RMT entries, far less than RMT memory limit (64/channel). Enabling DMA increases configuration complexity. For controlling hundreds of LEDs, DMA can bypass RMT memory limit.

5.3 Main Loop — Color Switching

After initialization, enter infinite loop: first use printf to print current color name for easy monitoring in serial monitor. Then call led_strip_set_pixel() to fill current color's RGB value, then led_strip_refresh() to send data through RMT, LED changes color. Finally index +1 with modulo for cycling, vTaskDelay 1 second delay before switching to next color.

xxxxxxxxxx
    int color_index = 0;
    while (1) {
        // Print current color
        printf("Current color: %s\n", color_names[color_index]);

        // Pixel index 0 (first LED)
        led_strip_set_pixel(led_strip, 0,
                           rainbow_colors[color_index].red,
                           rainbow_colors[color_index].green,
                           rainbow_colors[color_index].blue);
        // Send data to LED
        led_strip_refresh(led_strip);

        // Cycle index
        color_index = (color_index + 1) % COLOR_COUNT;
        // Delay 1s
        vTaskDelay(pdMS_TO_TICKS(COLOR_CHANGE_INTERVAL));
    }
}

led_strip_set_pixel() parameter order is (R, G, B), different from struct's {G, R, B} definition—because led_strip API uniformly uses (handle, index, R, G, B) interface, color component sorting is handled by color_component_format configuration.

printf() instead of ESP_LOGI(): GPIO48 has no conflict with UART0 (unlike GPIO43/44), serial output can be used. Using printf to output color name (English only, following project encoding standard), convenient for debugging and confirming current color.


6. Operation Flow

6.1 Hardware Preparation

  1. WS2812 module (or first LED of light strip)

  2. Wiring:

xxxxxxxxxx
ESP32-S3          WS2812
─────────────────────────
GPIO48        →    DIN (data input)
VDD (5V)      →    VCC (5V brighter)
GND           →    GND (common ground)

5V power supply recommended: 3.3V can light WS2812, but LED color is dim and unstable (WS2812 datasheet requires VIH ≥ 0.7×VDD, at 3.3V supply input high threshold ~2.3V, GPIO's 3.3V output is above that threshold).

6.2 Build and Flash

For detailed flashing process, see: 1. Before Development → 3. Build and Flash

6.3 Normal Output

Serial monitor:

xxxxxxxxxx
Current color: Red
Current color: Orange
Current color: Yellow
Current color: Green
Current color: Cyan
Current color: Blue
Current color: Purple
Current color: Red       ← Cycle
...

运行打印

LED phenomenon: Switches one color every 1 second, in order red→orange→yellow→green→cyan→blue→purple→red cycle.

实物运行图


7. Common Issues

PhenomenonCauseSolution
LED doesn't light upDIN connected wrong / wrong GPIO / insufficient powerCheck wiring, confirm GPIO48; use multimeter to measure VDD voltage
Wrong color (red becomes green)RGB/GRB order configuration errorConfirm color_component_format = LED_STRIP_COLOR_COMPONENT_FMT_GRB
LED flickers/random color jumpsTiming imprecise / large power supply rippleAdd 100µF electrolytic capacitor + 0.1µF ceramic capacitor in parallel between VDD-GND
When cascading multiple LEDs, first normal, later ones show wrong colorsLater LED data input disturbed / power voltage dropSolder decoupling capacitor every N LEDs; shorten data line length
led_strip_new_rmt_device failsRMT channel resources exhaustedCheck if other code occupies RMT channel
Doesn't light after first flashLED state not initializedled_strip_clear ensures RESET pulse is sent
Colors too dim3.3V power supply / RGB values too lowUse 5V power supply; increase RGB values (e.g., 255)
PWM Breathing LED
Serial UART Communication Experiment

COMPANY

  • About us
  • Team Style
  • Blog

LEARNING & EXPLORATION

  • Tutorials
  • Edge AI hardware
  • Educational robots
  • Embedded intelligent hardware

WHERE TO BUY

  • Yahboom Online Store
  • Amazon
  • Alibaba
  • AliExpress
  • Mercado

TECHNOLOGY SUPPORT

  • Email: support@yahboom.com

BE A DISTRIBUTOR

  • Email: sales@yahboom.com
QR Code

Copyright © 2017-2026 Yahboom. All Rights Reserved.

EN/中文