diff --git a/main/animation.c b/main/animation.c index 229bd4e..d544356 100644 --- a/main/animation.c +++ b/main/animation.c @@ -20,17 +20,22 @@ static animation_mode_t current_mode = ANIM_BLACK; static uint8_t global_hue = 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) { - uint32_t ms = esp_timer_get_time() / 1000; - uint32_t beat = (ms * bpm * 256) / 60000; - uint8_t beat8 = (beat >> 8) & 0xFF; + // Use uint64_t to prevent overflow + uint64_t us = esp_timer_get_time(); // Microseconds - // Sin approximation - float angle = (beat8 / 255.0f) * 2.0f * M_PI; + // Calculate beat phase (0-65535 repeating at BPM rate) + // 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); + // Map sin (-1 to +1) to output range (min_val to max_val) int16_t range = max_val - min_val; int16_t result = min_val + (int16_t)((sin_val + 1.0f) * range / 2.0f); @@ -94,7 +99,7 @@ static void anim_white(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_b = led_get_num_leds_b(); @@ -163,14 +168,14 @@ static void anim_sinelon(void) led_fade_to_black(20); 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}; rgb_t color = led_hsv_to_rgb(hsv); 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 { @@ -223,9 +228,9 @@ static void anim_navigation(void) // Side red (last 3 LEDs of strip A) if (num_leds_a >= 3) { - led_set_pixel_a(num_leds_a - 1, red); - led_set_pixel_a(num_leds_a - 2, red); - led_set_pixel_a(num_leds_a - 3, red); + led_set_pixel_a(num_leds_a - 1, red); + led_set_pixel_a(num_leds_a - 2, red); + led_set_pixel_a(num_leds_a - 3, red); } // Side green (last 3 LEDs of strip B) @@ -374,31 +379,31 @@ void animation_update(void) anim_white(); break; case ANIM_RAINBOW: - //anim_rainbow(); + // anim_rainbow(); break; case ANIM_RAINBOW_GLITTER: - //anim_rainbow_glitter(); + // anim_rainbow_glitter(); break; case ANIM_CONFETTI: - //anim_confetti(); + // anim_confetti(); break; case ANIM_SINELON: - //anim_sinelon(); + anim_sinelon(); break; case ANIM_BPM: - //anim_bpm(); + // anim_bpm(); break; case ANIM_NAVIGATION: anim_navigation(); break; case ANIM_CHASE: - //anim_chase(); + // anim_chase(); break; case ANIM_CHASE_RGB: - //anim_chase_rgb(); + // anim_chase_rgb(); break; case ANIM_RANDOM: - //anim_random(); + // anim_random(); break; default: anim_black();