12 Commits

Author SHA1 Message Date
284553f3f8 C3 Demo 2026-01-17 23:15:51 +01:00
e25971af89 port to ESP32C3 2026-01-09 13:24:19 +01:00
5796b28e1a improve navigation animation 2026-01-06 23:02:54 +01:00
12a8710a2f cleanup 2026-01-06 22:44:36 +01:00
468d2cba74 fix chase rgb animation 2026-01-06 22:39:44 +01:00
d2d5d7dc4b fix chase animation 2026-01-06 22:33:28 +01:00
f1aac6611d fix random animation 2026-01-06 22:21:33 +01:00
733b05eaeb fix confetti animation 2026-01-06 22:06:02 +01:00
715d50c255 enable rainbow with glitter animation 2026-01-06 21:58:11 +01:00
883fff95dd fix rainbow animation 2026-01-06 21:55:00 +01:00
0f62418d93 fix sinelon 2026-01-06 21:35:28 +01:00
12b8acf81c fix navigation animation 2026-01-06 21:16:05 +01:00
9 changed files with 735 additions and 649 deletions

1
.gitignore vendored
View File

@ -291,3 +291,4 @@ dkms.conf
.vscode/settings.json .vscode/settings.json
sdkconfig.defaults sdkconfig.defaults
.clangd

View File

@ -20,29 +20,28 @@ static animation_mode_t current_mode = ANIM_BLACK;
static uint8_t global_hue = 0; static uint8_t global_hue = 0;
static uint32_t frame_counter = 0; static uint32_t frame_counter = 0;
// Beat calculation helper (similar to FastLED beatsin16) // Beat calculation helper
static int16_t beatsin16(uint8_t bpm, int16_t min_val, int16_t max_val) static int16_t beatsin16(uint8_t bpm, int16_t min_val, int16_t max_val)
{ {
uint32_t ms = esp_timer_get_time() / 1000; // Use uint64_t to prevent overflow
uint32_t beat = (ms * bpm * 256) / 60000; uint64_t us = esp_timer_get_time(); // Microseconds
uint8_t beat8 = (beat >> 8) & 0xFF;
// Sin approximation // Calculate beat phase (0-65535 repeating at BPM rate)
float angle = (beat8 / 255.0f) * 2.0f * M_PI; // beats_per_minute → beats_per_microsecond = bpm / 60,000,000
uint64_t beat_phase = (us * (uint64_t)bpm * 65536ULL) / 60000000ULL;
uint16_t beat16 = (uint16_t)(beat_phase & 0xFFFF);
// Convert to angle (0 to 2π)
float angle = (beat16 / 65535.0f) * 2.0f * M_PI;
float sin_val = sinf(angle); float sin_val = sinf(angle);
// Map sin (-1 to +1) to output range (min_val to max_val)
int16_t range = max_val - min_val; int16_t range = max_val - min_val;
int16_t result = min_val + (int16_t)((sin_val + 1.0f) * range / 2.0f); int16_t result = min_val + (int16_t)((sin_val + 1.0f) * range / 2.0f);
return result; return result;
} }
// Beat calculation helper (beatsin8 variant)
static uint8_t beatsin8(uint8_t bpm, uint8_t min_val, uint8_t max_val)
{
return (uint8_t)beatsin16(bpm, min_val, max_val);
}
// Random helper // Random helper
static uint8_t random8(void) static uint8_t random8(void)
{ {
@ -94,20 +93,24 @@ static void anim_white(void)
static void anim_rainbow(void) static void anim_rainbow(void)
{ {
// FastLED's built-in rainbow generator // Rainbow generator
uint16_t num_leds_a = led_get_num_leds_a(); uint16_t num_leds_a = led_get_num_leds_a();
uint16_t num_leds_b = led_get_num_leds_b(); uint16_t num_leds_b = led_get_num_leds_b();
uint16_t num_leds = num_leds_a + num_leds_b;
for (uint16_t i = 0; i < num_leds_a; i++) for (uint16_t i = 0; i < num_leds; i++)
{ {
hsv_t hsv = {(uint8_t)(global_hue + (i * 7)), 255, 255}; hsv_t hsv = {(uint8_t)(global_hue + (i * 7)), 255, 255};
led_set_pixel_a(i, led_hsv_to_rgb(hsv)); rgb_t color = led_hsv_to_rgb(hsv);
if (i < num_leds_a)
{
led_set_pixel_a(num_leds_a - i - 1, color);
} }
else
for (uint16_t i = 0; i < num_leds_b; i++)
{ {
hsv_t hsv = {(uint8_t)(global_hue + (i * 7)), 255, 255}; led_set_pixel_b(i - num_leds_a, color);
led_set_pixel_b(i, led_hsv_to_rgb(hsv)); }
} }
} }
@ -133,7 +136,7 @@ static void add_glitter(uint8_t chance_of_glitter)
static void anim_rainbow_glitter(void) static void anim_rainbow_glitter(void)
{ {
anim_rainbow(); anim_rainbow();
add_glitter(80); add_glitter(255);
} }
static void anim_confetti(void) static void anim_confetti(void)
@ -144,16 +147,16 @@ static void anim_confetti(void)
uint16_t num_leds = led_get_num_leds_a() + led_get_num_leds_b(); uint16_t num_leds = led_get_num_leds_a() + led_get_num_leds_b();
uint16_t pos = random16(num_leds); uint16_t pos = random16(num_leds);
hsv_t hsv = {(uint8_t)(global_hue + random8()), 200, 255}; hsv_t hsv = {(uint8_t)(global_hue + random8()), 255, 255};
rgb_t color = led_hsv_to_rgb(hsv); rgb_t color = led_hsv_to_rgb(hsv);
if (pos < led_get_num_leds_a()) if (pos < led_get_num_leds_a())
{ {
led_add_pixel_a(pos, color); led_set_pixel_a(led_get_num_leds_a() - pos - 1, color);
} }
else else
{ {
led_add_pixel_b(pos - led_get_num_leds_a(), color); led_set_pixel_b(pos - led_get_num_leds_a(), color);
} }
} }
@ -163,14 +166,14 @@ static void anim_sinelon(void)
led_fade_to_black(20); led_fade_to_black(20);
uint16_t num_leds = led_get_num_leds_a() + led_get_num_leds_b(); uint16_t num_leds = led_get_num_leds_a() + led_get_num_leds_b();
int16_t pos = beatsin16(13, 0, num_leds - 1); int16_t pos = beatsin16(13, 0, num_leds);
hsv_t hsv = {global_hue, 255, 192}; hsv_t hsv = {global_hue, 255, 192};
rgb_t color = led_hsv_to_rgb(hsv); rgb_t color = led_hsv_to_rgb(hsv);
if (pos < led_get_num_leds_a()) if (pos < led_get_num_leds_a())
{ {
led_add_pixel_a(pos, color); led_add_pixel_a(led_get_num_leds_a() - pos - 1, color);
} }
else else
{ {
@ -178,42 +181,14 @@ static void anim_sinelon(void)
} }
} }
static void anim_bpm(void)
{
// Colored stripes pulsing at 33 BPM
uint8_t bpm = 33;
uint8_t beat = beatsin8(bpm, 64, 255);
uint16_t num_leds_a = led_get_num_leds_a();
uint16_t num_leds_b = led_get_num_leds_b();
// PartyColors palette simulation
const uint8_t palette_colors[] = {
170, 240, 90, 150, 210, 30, 180, 0,
210, 255, 150, 240, 255, 60, 255, 120};
for (uint16_t i = 0; i < num_leds_a; i++)
{
uint8_t color_index = (global_hue + (i * 2)) & 0x0F;
uint8_t brightness = beat - global_hue + (i * 10);
hsv_t hsv = {palette_colors[color_index], 255, brightness};
led_set_pixel_a(i, led_hsv_to_rgb(hsv));
}
for (uint16_t i = 0; i < num_leds_b; i++)
{
uint8_t color_index = (global_hue + ((i + num_leds_a) * 2)) & 0x0F;
uint8_t brightness = beat - global_hue + ((i + num_leds_a) * 10);
hsv_t hsv = {palette_colors[color_index], 255, brightness};
led_set_pixel_b(i, led_hsv_to_rgb(hsv));
}
}
static void anim_navigation(void) static void anim_navigation(void)
{ {
// Navigation lights: left red, right green, with blinking white // Aviation navigation lights with strobe overlay:
static uint8_t blink_state = 0; // - Red: Port (left) wingtip - steady
// - Green: Starboard (right) wingtip - steady
// - White strobe: Overlays outer nav lights with bright flashes
static uint8_t strobe_counter = 0;
led_clear_all(); led_clear_all();
uint16_t num_leds_a = led_get_num_leds_a(); uint16_t num_leds_a = led_get_num_leds_a();
@ -223,49 +198,32 @@ static void anim_navigation(void)
rgb_t green = {0, 255, 0}; rgb_t green = {0, 255, 0};
rgb_t white = {255, 255, 255}; rgb_t white = {255, 255, 255};
// Left side red (first 3 LEDs of strip A) // Anti-collision strobe pattern: Double flash at ~1 Hz
// Flash duration: 3 frames (~50ms) for high-intensity effect
bool first_flash = (strobe_counter < 3);
bool second_flash = (strobe_counter >= 7 && strobe_counter < 10);
bool strobe_active = (first_flash || second_flash);
// Port (left) - Red navigation light OR white strobe (outer 3 LEDs of strip A)
if (num_leds_a >= 3) if (num_leds_a >= 3)
{ {
led_set_pixel_a(0, red); rgb_t color_a = strobe_active ? white : red;
led_set_pixel_a(1, red); led_set_pixel_a(num_leds_a - 1, color_a);
led_set_pixel_a(2, red); led_set_pixel_a(num_leds_a - 2, red);
led_set_pixel_a(num_leds_a - 3, red);
} }
// Right side green (last 3 LEDs) // Starboard (right) - Green navigation light OR white strobe (outer 3 LEDs of strip B)
if (num_leds_b >= 3) if (num_leds_b >= 3)
{ {
led_set_pixel_b(num_leds_b - 1, green); rgb_t color_b = strobe_active ? white : green;
led_set_pixel_b(num_leds_b - 1, color_b);
led_set_pixel_b(num_leds_b - 2, green); led_set_pixel_b(num_leds_b - 2, green);
led_set_pixel_b(num_leds_b - 3, green); led_set_pixel_b(num_leds_b - 3, green);
} }
else if (num_leds_a >= 6)
{
led_set_pixel_a(num_leds_a - 1, green);
led_set_pixel_a(num_leds_a - 2, green);
led_set_pixel_a(num_leds_a - 3, green);
}
// Blinking white lights (positions 5-6 and 37-38 from original) // Strobe cycle: 90 frames = 1.5 second at 60 FPS
if (blink_state < FRAMES_PER_SECOND / 2) strobe_counter = (strobe_counter + 1) % 90;
{
if (num_leds_a > 6)
{
led_set_pixel_a(5, white);
led_set_pixel_a(6, white);
}
if (num_leds_b > 2)
{
led_set_pixel_b(1, white);
led_set_pixel_b(2, white);
}
else if (num_leds_a > 38)
{
led_set_pixel_a(37, white);
led_set_pixel_a(38, white);
}
}
blink_state = (blink_state + 1) % FRAMES_PER_SECOND;
} }
static void anim_chase(void) static void anim_chase(void)
@ -273,25 +231,45 @@ static void anim_chase(void)
// Red dot sweeping with trailing dots // Red dot sweeping with trailing dots
led_clear_all(); led_clear_all();
uint16_t num_leds = led_get_num_leds_a() + led_get_num_leds_b(); uint16_t num_leds_a = led_get_num_leds_a();
int16_t pos = beatsin16(40, 0, num_leds - 1); uint16_t num_leds_b = led_get_num_leds_b();
uint16_t total_leds = num_leds_a + num_leds_b;
// Get oscillating position across both strips
int16_t center_pos = beatsin16(40, 0, total_leds - 1);
rgb_t red = {255, 0, 0}; rgb_t red = {255, 0, 0};
// Set main dot and trailing dots // Draw center dot with dimmed trailing dots (3 dots total: center ±1)
for (int offset = -2; offset <= 2; offset++) for (int8_t offset = -1; offset <= 1; offset++)
{ {
int16_t led_pos = pos + offset; int16_t led_pos = center_pos + offset;
if (led_pos >= 0 && led_pos < num_leds)
// Skip if position is out of bounds
if (led_pos < 0 || led_pos >= total_leds)
continue;
// Calculate brightness based on distance from center
uint8_t brightness = (offset == 0) ? 255 : 32; // Center: full, trailing: 12%
// Create dimmed color
rgb_t dimmed_red = {
(red.r * brightness) / 255,
(red.g * brightness) / 255,
(red.b * brightness) / 255};
// Map virtual position to physical LED
if (led_pos < num_leds_a)
{ {
if (led_pos < led_get_num_leds_a()) // Strip A (mirrored: position 0 maps to last LED)
{ uint16_t strip_a_index = num_leds_a - led_pos - 1;
led_set_pixel_a(led_pos, red); led_set_pixel_a(strip_a_index, dimmed_red);
} }
else else
{ {
led_set_pixel_b(led_pos - led_get_num_leds_a(), red); // Strip B (direct mapping)
} uint16_t strip_b_index = led_pos - num_leds_a;
led_set_pixel_b(strip_b_index, dimmed_red);
} }
} }
} }
@ -301,26 +279,46 @@ static void anim_chase_rgb(void)
// RGB cycling dot sweeping with trailing dots // RGB cycling dot sweeping with trailing dots
led_clear_all(); led_clear_all();
uint16_t num_leds = led_get_num_leds_a() + led_get_num_leds_b(); uint16_t num_leds_a = led_get_num_leds_a();
int16_t pos = beatsin16(40, 0, num_leds - 1); uint16_t num_leds_b = led_get_num_leds_b();
uint16_t total_leds = num_leds_a + num_leds_b;
// Get oscillating position across both strips
int16_t center_pos = beatsin16(40, 0, total_leds - 1);
hsv_t hsv = {global_hue, 255, 192}; hsv_t hsv = {global_hue, 255, 192};
rgb_t color = led_hsv_to_rgb(hsv); rgb_t color = led_hsv_to_rgb(hsv);
// Set main dot and trailing dots // Draw center dot with dimmed trailing dots (3 dots total: center ±1)
for (int offset = -2; offset <= 2; offset++) for (int8_t offset = -1; offset <= 1; offset++)
{ {
int16_t led_pos = pos + offset; int16_t led_pos = center_pos + offset;
if (led_pos >= 0 && led_pos < num_leds)
// Skip if position is out of bounds
if (led_pos < 0 || led_pos >= total_leds)
continue;
// Calculate brightness based on distance from center
uint8_t brightness = (offset == 0) ? 255 : 32; // Center: full, trailing: 12%
// Create dimmed color
rgb_t dimmed_color = {
(color.r * brightness) / 255,
(color.g * brightness) / 255,
(color.b * brightness) / 255};
// Map virtual position to physical LED
if (led_pos < num_leds_a)
{ {
if (led_pos < led_get_num_leds_a()) // Strip A (mirrored: position 0 maps to last LED)
{ uint16_t strip_a_index = num_leds_a - led_pos - 1;
led_add_pixel_a(led_pos, color); led_set_pixel_a(strip_a_index, dimmed_color);
} }
else else
{ {
led_add_pixel_b(led_pos - led_get_num_leds_a(), color); // Strip B (direct mapping)
} uint16_t strip_b_index = led_pos - num_leds_a;
led_set_pixel_b(strip_b_index, dimmed_color);
} }
} }
} }
@ -331,18 +329,26 @@ static void anim_random(void)
uint16_t num_leds = led_get_num_leds_a() + led_get_num_leds_b(); uint16_t num_leds = led_get_num_leds_a() + led_get_num_leds_b();
uint16_t random_pos = random16(num_leds); uint16_t random_pos = random16(num_leds);
// Randomly clear all (rare event)
if (random_pos == num_leds - 1 && random8() > 200)
{
led_clear_all();
return;
}
// Set random LED to random color
rgb_t random_color = { rgb_t random_color = {
random8(), 0,
random8(), 0,
random8()}; 0};
// Set random LED to random basis color
switch (random16(3))
{
case 0:
random_color.r = 255;
break;
case 1:
random_color.g = 255;
break;
case 2:
random_color.b = 255;
break;
default:
break;
}
if (random_pos < led_get_num_leds_a()) if (random_pos < led_get_num_leds_a())
{ {
@ -357,31 +363,26 @@ static void anim_random(void)
esp_err_t animation_init(void) esp_err_t animation_init(void)
{ {
current_mode = ANIM_BLACK; current_mode = ANIM_BLACK;
global_hue = 0; global_hue = 0U;
frame_counter = 0; frame_counter = 0U;
ESP_LOGI(TAG, "Animation system initialized"); ESP_LOGI(TAG, "Animation initialized");
return ESP_OK; return ESP_OK;
} }
void animation_set_mode(animation_mode_t mode) void animation_set_mode(animation_mode_t mode)
{ {
if (mode >= ANIM_MODE_COUNT) if ((mode >= ANIM_MODE_COUNT) || (mode < 0U))
{ {
mode = ANIM_BLACK; mode = ANIM_BLACK;
} }
current_mode = mode; current_mode = mode;
frame_counter = 0; frame_counter = 0U;
ESP_LOGI(TAG, "Animation mode set to: %s", animation_get_mode_name(mode)); ESP_LOGI(TAG, "Animation mode set to: %s", animation_get_mode_name(mode));
} }
animation_mode_t animation_get_mode(void)
{
return current_mode;
}
void animation_update(void) void animation_update(void)
{ {
// Update global hue every frame (slowly cycles colors) // Update global hue every frame (slowly cycles colors)
@ -421,9 +422,6 @@ void animation_update(void)
case ANIM_SINELON: case ANIM_SINELON:
anim_sinelon(); anim_sinelon();
break; break;
case ANIM_BPM:
anim_bpm();
break;
case ANIM_NAVIGATION: case ANIM_NAVIGATION:
anim_navigation(); anim_navigation();
break; break;
@ -456,7 +454,6 @@ const char *animation_get_mode_name(animation_mode_t mode)
"Rainbow with Glitter", "Rainbow with Glitter",
"Confetti", "Confetti",
"Sinelon", "Sinelon",
"BPM",
"Navigation", "Navigation",
"Chase", "Chase",
"Chase RGB", "Chase RGB",

View File

@ -23,11 +23,10 @@ typedef enum {
ANIM_RAINBOW_GLITTER = 6, // Rainbow with glitter ANIM_RAINBOW_GLITTER = 6, // Rainbow with glitter
ANIM_CONFETTI = 7, // Random colored speckles ANIM_CONFETTI = 7, // Random colored speckles
ANIM_SINELON = 8, // Colored dot sweeping (RGB cycling) ANIM_SINELON = 8, // Colored dot sweeping (RGB cycling)
ANIM_BPM = 9, // Colored stripes @ 33 BPM ANIM_NAVIGATION = 9, // Navigation lights (red left, green right)
ANIM_NAVIGATION = 10, // Navigation lights (red left, green right) ANIM_CHASE = 10, // Red dot sweeping
ANIM_CHASE = 11, // Red dot sweeping ANIM_CHASE_RGB = 11, // RGB cycling dot sweeping
ANIM_CHASE_RGB = 12, // RGB cycling dot sweeping ANIM_RANDOM = 12, // Random mode
ANIM_RANDOM = 13, // Random mode
ANIM_MODE_COUNT ANIM_MODE_COUNT
} animation_mode_t; } animation_mode_t;
@ -43,12 +42,6 @@ esp_err_t animation_init(void);
*/ */
void animation_set_mode(animation_mode_t mode); void animation_set_mode(animation_mode_t mode);
/**
* @brief Get current animation mode
* @return Current mode
*/
animation_mode_t animation_get_mode(void);
/** /**
* @brief Update animation (call periodically, e.g., 30-60 FPS) * @brief Update animation (call periodically, e.g., 30-60 FPS)
*/ */

View File

@ -22,12 +22,20 @@ static const char *TAG = "CONFIG";
#define HARDCODED_CONFIG #define HARDCODED_CONFIG
#ifdef HARDCODED_CONFIG #ifdef HARDCODED_CONFIG
#define HARDCODED_CONFIG_LED_STRIP_A_PIN 12U #define HARDCODED_CONFIG_LED_STRIP_A_PIN 2U
#define HARDCODED_CONFIG_LED_STRIP_B_PIN 14U #define HARDCODED_CONFIG_LED_STRIP_B_PIN 3U
#define HARDCODED_CONFIG_LED_STRIP_A_COUNT 7U #define HARDCODED_CONFIG_LED_STRIP_A_COUNT 1U
#define HARDCODED_CONFIG_LED_STRIP_B_COUNT 7U #define HARDCODED_CONFIG_LED_STRIP_B_COUNT 1U
#define HARDCODED_CONFIG_PWM_PIN 13U #define HARDCODED_CONFIG_PWM_PIN 1U
#define HARDCODED_CONFIG_LOCALBTN_PIN GPIO_NUM_0
#if defined(CONFIG_IDF_TARGET_ESP32C3)
#define HARDCODED_CONFIG_LOCALBTN_PIN 9
#elif defined(CONFIG_IDF_TARGET_ESP32)
#define HARDCODED_CONFIG_LOCALBTN_PIN 0
#else
#error "Unsupported target: BOOT button GPIO not defined"
#endif
#endif #endif
// Global state // Global state

View File

@ -24,15 +24,6 @@ static void on_mode_change()
animation_set_mode((animation_mode_t)current_animation_mode); animation_set_mode((animation_mode_t)current_animation_mode);
} }
void control_set_animation_mode(uint8_t mode)
{
if (mode >= ANIM_MODE_COUNT)
{
mode = 0;
}
on_mode_change(mode);
}
uint8_t control_get_animation_mode(void) uint8_t control_get_animation_mode(void)
{ {
return current_animation_mode; return current_animation_mode;
@ -58,7 +49,7 @@ esp_err_t control_init(void)
// Initialize LED strips // Initialize LED strips
ret = led_init(current_config.led_pin_strip_a, current_config.led_pin_strip_b, ret = led_init(current_config.led_pin_strip_a, current_config.led_pin_strip_b,
current_config.led_count_strip_a, current_config.led_count_strip_a); current_config.led_count_strip_a, current_config.led_count_strip_b);
if (ret != ESP_OK) if (ret != ESP_OK)
{ {
ESP_LOGE(TAG, "LED init failed: %s", esp_err_to_name(ret)); ESP_LOGE(TAG, "LED init failed: %s", esp_err_to_name(ret));

View File

@ -18,12 +18,6 @@
*/ */
esp_err_t control_init(void); esp_err_t control_init(void);
/**
* @brief Set animation mode manually
* @param mode Animation mode (0-13)
*/
void control_set_animation_mode(uint8_t mode);
/** /**
* @brief Get current animation mode * @brief Get current animation mode
* @return Current mode (0-13) * @return Current mode (0-13)

View File

@ -194,7 +194,13 @@ static esp_err_t init_strip(led_strip_t *strip, int8_t pin, uint16_t num_leds)
rmt_tx_channel_config_t tx_chan_config = { rmt_tx_channel_config_t tx_chan_config = {
.clk_src = RMT_CLK_SRC_DEFAULT, .clk_src = RMT_CLK_SRC_DEFAULT,
.gpio_num = pin, .gpio_num = pin,
#if defined(CONFIG_IDF_TARGET_ESP32C3)
.mem_block_symbols = 48,
#elif defined(CONFIG_IDF_TARGET_ESP32)
.mem_block_symbols = 64, .mem_block_symbols = 64,
#else
#error "Unsupported target: rmt block symbols undefined"
#endif
.resolution_hz = 80000000, // 80MHz .resolution_hz = 80000000, // 80MHz
.trans_queue_depth = 4, .trans_queue_depth = 4,
}; };
@ -321,7 +327,10 @@ static void show_strip(led_strip_t *strip)
// Convert RGB to GRB for WS2812B // Convert RGB to GRB for WS2812B
uint8_t *grb_data = malloc(strip->num_leds * 3); uint8_t *grb_data = malloc(strip->num_leds * 3);
if (!grb_data) if (!grb_data)
{
ESP_LOGE(TAG, "Failed to allocate GRB buffer");
return; return;
}
for (uint16_t i = 0; i < strip->num_leds; i++) for (uint16_t i = 0; i < strip->num_leds; i++)
{ {
@ -334,7 +343,21 @@ static void show_strip(led_strip_t *strip)
.loop_count = 0, .loop_count = 0,
}; };
rmt_transmit(strip->rmt_channel, strip->encoder, grb_data, strip->num_leds * 3, &tx_config); esp_err_t ret = rmt_transmit(strip->rmt_channel, strip->encoder, grb_data, strip->num_leds * 3, &tx_config);
if (ret != ESP_OK)
{
ESP_LOGE(TAG, "RMT transmit failed: %s", esp_err_to_name(ret));
free(grb_data);
return;
}
// Wait for transmission to complete before freeing buffer
ret = rmt_tx_wait_all_done(strip->rmt_channel, pdMS_TO_TICKS(100));
if (ret != ESP_OK)
{
ESP_LOGW(TAG, "RMT wait timeout");
}
free(grb_data); free(grb_data);
} }

View File

@ -76,6 +76,8 @@ void app_main(void)
} }
} }
animation_set_mode((animation_mode_t)control_get_animation_mode());
ESP_LOGI(TAG, "System initialized successfully"); ESP_LOGI(TAG, "System initialized successfully");
// Main loop - just monitor system status // Main loop - just monitor system status
@ -84,6 +86,6 @@ void app_main(void)
vTaskDelay(pdMS_TO_TICKS(5000)); vTaskDelay(pdMS_TO_TICKS(5000));
// Periodic status logging // Periodic status logging
ESP_LOGI(TAG, "Status - Mode: %d", control_get_animation_mode()); ESP_LOGI(TAG, "Animation Mode set to: %s", animation_get_mode_name(control_get_animation_mode()));
} }
} }

1011
sdkconfig

File diff suppressed because it is too large Load Diff