#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/rmt.h"
#include "esp_log.h"
#define RMT_TX_CHANNEL RMT_CHANNEL_0
#define RMT_TX_GPIO 8
#define LED_STRIP_LEN 30
static const char *TAG = "ws2812";
typedef struct {
uint8_t r, g, b;
} rgb_t;
static rgb_t led_strip[LED_STRIP_LEN];
static void led_strip_fill_rgb(uint8_t r, uint8_t g, uint8_t b) {
for (int i = 0; i < LED_STRIP_LEN; i++) {
led_strip[i].r = r;
led_strip[i].g = g;
led_strip[i].b = b;
}
}
static void rmt_tx_init() {
rmt_config_t config = RMT_DEFAULT_CONFIG_TX(RMT_TX_GPIO, RMT_TX_CHANNEL);
config.clk_div = 2;
ESP_ERROR_CHECK(rmt_config(&config));
ESP_ERROR_CHECK(rmt_driver_install(config.channel, 0, 0));
}
static void led_strip_update() {
rmt_item32_t items[LED_STRIP_LEN * 24];
int item_idx = 0;
for (int i = 0; i < LED_STRIP_LEN; i++) {
uint32_t color = (led_strip[i].g << 16) | (led_strip[i].r << 8) | led_strip[i].b;
for (int bit = 23; bit >= 0; bit--) {
if (color & (1 << bit)) {
items[item_idx].level0 = 1;
items[item_idx].duration0 = 32; // 800ns
items[item_idx].level1 = 0;
items[item_idx].duration1 = 16; // 400ns
} else {
items[item_idx].level0 = 1;
items[item_idx].duration0 = 16; // 400ns
items[item_idx].level1 = 0;
items[item_idx].duration1 = 32; // 800ns
}
item_idx++;
}
}
ESP_ERROR_CHECK(rmt_write_items(RMT_TX_CHANNEL, items, item_idx, true));
ESP_ERROR_CHECK(rmt_wait_tx_done(RMT_TX_CHANNEL, portMAX_DELAY));
}
void app_main() {
rmt_tx_init();
uint8_t r = 255, g = 0, b = 0;
while (1) {
// Cycle through RGB colors
if (r == 255 && g < 255 && b == 0) {
g++;
} else if (g == 255 && r > 0 && b == 0) {
r--;
} else if (g == 255 && b < 255 && r == 0) {
b++;
} else if (b == 255 && g > 0 && r == 0) {
g--;
} else if (b == 255 && r < 255 && g == 0) {
r++;
} else if (r == 255 && b > 0 && g == 0) {
b--;
}
led_strip_fill_rgb(r, g, b);
led_strip_update();
vTaskDelay(pdMS_TO_TICKS(10)); // Adjust delay to control speed of color cycling
}
}