ESP32 C6 example to control WS2812
2025-10-12
This example controls the WS2812 on Waveshare C6 Zero board, keep changing its color, done using VSCode + ESP-IDF
/* Blink Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "led_strip.h"
#include "sdkconfig.h"
static const char *TAG = "example";
/* Use project configuration menu (idf.py menuconfig) to choose the GPIO to blink,
or you can edit the following line and set a number here.
*/
#define BLINK_GPIO CONFIG_BLINK_GPIO
static uint8_t s_led_state = 0;
static uint8_t color_phase = 0; // Phase for color cycling (0-255)
#ifdef CONFIG_BLINK_LED_STRIP
static led_strip_handle_t led_strip;
// Function to create smooth color transitions using HSV to RGB conversion
static void hsv_to_rgb(uint8_t h, uint8_t s, uint8_t v, uint8_t *r, uint8_t *g, uint8_t *b) {
uint8_t region, remainder, p, q, t;
if (s == 0) {
*r = *g = *b = v;
return;
}
region = h / 43;
remainder = (h - (region * 43)) * 6;
p = (v * (255 - s)) >> 8;
q = (v * (255 - ((s * remainder) >> 8))) >> 8;
t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8;
switch (region) {
case 0:
*r = v; *g = t; *b = p;
break;
case 1:
*r = q; *g = v; *b = p;
break;
case 2:
*r = p; *g = v; *b = t;
break;
case 3:
*r = p; *g = q; *b = v;
break;
case 4:
*r = t; *g = p; *b = v;
break;
default:
*r = v; *g = p; *b = q;
break;
}
}
static void blink_led(void)
{
uint8_t r, g, b;
// Convert HSV to RGB for smooth color transitions
// Hue cycles through full spectrum (0-255)
// Saturation = 255 (full saturation for vivid colors)
// Value = 128 (medium brightness)
hsv_to_rgb(color_phase, 255, 128, &r, &g, &b);
/* Set the LED pixel with the calculated RGB values */
led_strip_set_pixel(led_strip, 0, r, g, b);
/* Refresh the strip to send data */
led_strip_refresh(led_strip);
// Increment color phase for smooth transition
color_phase += 2; // Adjust step size for faster/slower color change
}
static void configure_led(void)
{
ESP_LOGI(TAG, "Example configured to blink addressable LED!");
/* LED strip initialization with the GPIO and pixels number*/
led_strip_config_t strip_config = {
.strip_gpio_num = BLINK_GPIO,
.max_leds = 1, // at least one LED on board
};
#if CONFIG_BLINK_LED_STRIP_BACKEND_RMT
led_strip_rmt_config_t rmt_config = {
.resolution_hz = 10 * 1000 * 1000, // 10MHz
.flags.with_dma = false,
};
ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip));
#elif CONFIG_BLINK_LED_STRIP_BACKEND_SPI
led_strip_spi_config_t spi_config = {
.spi_bus = SPI2_HOST,
.flags.with_dma = true,
};
ESP_ERROR_CHECK(led_strip_new_spi_device(&strip_config, &spi_config, &led_strip));
#else
#error "unsupported LED strip backend"
#endif
/* Set all LED off to clear all pixels */
led_strip_clear(led_strip);
}
#elif CONFIG_BLINK_LED_GPIO
static void blink_led(void)
{
/* Set the GPIO level according to the state (LOW or HIGH)*/
gpio_set_level(BLINK_GPIO, s_led_state);
}
static void configure_led(void)
{
ESP_LOGI(TAG, "Example configured to blink GPIO LED!");
gpio_reset_pin(BLINK_GPIO);
/* Set the GPIO as a push/pull output */
gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
}
#else
#error "unsupported LED type"
#endif
void app_main(void)
{
/* Configure the peripheral according to the LED type */
configure_led();
while (1) {
ESP_LOGI(TAG, "Color phase: %d", color_phase);
blink_led();
/* Small delay for smooth color transition */
vTaskDelay(10 / portTICK_PERIOD_MS); // 10ms delay for smooth animation
}
}