Skip to content

Commit

Permalink
LEDs: add rainbow effects
Browse files Browse the repository at this point in the history
Setting the headlights to Solid with white, and then setting the
taillights to Rainbow Cycle allows users to replicate the "Mullet"
effect from the Float package.

Using Rainbow Cycle on the front and the back replicates the "Rave"
effect from the Float package.

Rainbow Fade has also been added, which was inspired by the Float
package's "RGB Fade" effect.

Feature: Add the Rainbow Cycle and Rainbow Fade LED effects.
  • Loading branch information
acheronfail committed Aug 15, 2024
1 parent 5e73abf commit fae1b23
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/conf/datatypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ typedef enum {
LED_MODE_STROBE,
LED_MODE_KNIGHT_RIDER,
LED_MODE_FELONY,
LED_MODE_RAINBOW_CYCLE,
LED_MODE_RAINBOW_FADE,
} LedMode;

typedef enum {
Expand Down
10 changes: 10 additions & 0 deletions src/conf/settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2255,6 +2255,8 @@ p, li { white-space: pre-wrap; }
<enumNames>Strobe</enumNames>
<enumNames>Knight Rider</enumNames>
<enumNames>Felony</enumNames>
<enumNames>Rainbow Cycle</enumNames>
<enumNames>Rainbow Fade</enumNames>
</leds.front.mode>
<leds.front.brightness>
<longName>Front Brightness</longName>
Expand Down Expand Up @@ -2417,6 +2419,8 @@ p, li { white-space: pre-wrap; }
<enumNames>Strobe</enumNames>
<enumNames>Knight Rider</enumNames>
<enumNames>Felony</enumNames>
<enumNames>Rainbow Cycle</enumNames>
<enumNames>Rainbow Fade</enumNames>
</leds.rear.mode>
<leds.rear.brightness>
<longName>Rear Brightness</longName>
Expand Down Expand Up @@ -2579,6 +2583,8 @@ p, li { white-space: pre-wrap; }
<enumNames>Strobe</enumNames>
<enumNames>Knight Rider</enumNames>
<enumNames>Felony</enumNames>
<enumNames>Rainbow Cycle</enumNames>
<enumNames>Rainbow Fade</enumNames>
</leds.headlights.mode>
<leds.headlights.brightness>
<longName>Headlights Brightness</longName>
Expand Down Expand Up @@ -2743,6 +2749,8 @@ p, li { white-space: pre-wrap; }
<enumNames>Strobe</enumNames>
<enumNames>Knight Rider</enumNames>
<enumNames>Felony</enumNames>
<enumNames>Rainbow Cycle</enumNames>
<enumNames>Rainbow Fade</enumNames>
</leds.taillights.mode>
<leds.taillights.brightness>
<longName>Taillights Brightness</longName>
Expand Down Expand Up @@ -3035,6 +3043,8 @@ p, li { white-space: pre-wrap; }
<enumNames>Strobe</enumNames>
<enumNames>Knight Rider</enumNames>
<enumNames>Felony</enumNames>
<enumNames>Rainbow Cycle</enumNames>
<enumNames>Rainbow Fade</enumNames>
</leds.status_idle.mode>
<leds.status_idle.brightness>
<longName>Status Idle Brightness</longName>
Expand Down
62 changes: 62 additions & 0 deletions src/leds.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,62 @@ static void anim_felony(Leds *leds, const LedStrip *strip, const LedBar *bar, fl
}
}

static const uint32_t rainbow_cycle_colors[] = {
0x00FFFF00,
0x0000FF00,
0x0000FFFF,
0x000000FF,
0x00FF00FF,
0x00FF0000,
};
static const uint8_t rainbow_cycle_colors_len =
sizeof(rainbow_cycle_colors) / sizeof(rainbow_cycle_colors[0]);

static void anim_rainbow_cycle(Leds *leds, const LedStrip *strip, float time) {
uint8_t color_idx = (uint8_t) (time / 0.1f) % rainbow_cycle_colors_len;
strip_set_color(leds, strip, rainbow_cycle_colors[color_idx], strip->brightness, 1.0f);
}

static const uint32_t rainbow_fade_colors[] = {
0x00FF5000, // FLAME
0x00FF7800, // ORANGE
0x00FFA000, // YELLOW
0x0000FF00, // GREEN
0x0000FFFF, // CYAN
0x008000FF, // VIOLET
0x00FF70A0, // LAVENDER
};
static const uint8_t rainbow_fade_colors_len =
sizeof(rainbow_fade_colors) / sizeof(rainbow_fade_colors[0]);

static void anim_rainbow_fade(Leds *leds, const LedStrip *strip, float time) {
float phase = fmodf(time, (float) rainbow_fade_colors_len);
uint8_t curr_color_idx = (uint8_t) floorf(phase);
uint8_t next_color_idx = (curr_color_idx + 1) % rainbow_fade_colors_len;

// extract rbg components from current color
uint32_t curr_color = rainbow_fade_colors[curr_color_idx];
uint8_t r_curr = (curr_color >> 16) & 0xFF;
uint8_t g_curr = (curr_color >> 8) & 0xFF;
uint8_t b_curr = curr_color & 0xFF;

// extract rbg components from next color
uint32_t next_color = rainbow_fade_colors[next_color_idx];
uint8_t r_next = (next_color >> 16) & 0xFF;
uint8_t g_next = (next_color >> 8) & 0xFF;
uint8_t b_next = next_color & 0xFF;

// smoothly interpolate between the current and next color
float ratio = phase - curr_color_idx;
float smooth_ratio = (1.0f - cosf(ratio * M_PI)) / 2.0f;
uint8_t r = (uint8_t) ((1.0f - smooth_ratio) * r_curr + smooth_ratio * r_next);
uint8_t g = (uint8_t) ((1.0f - smooth_ratio) * g_curr + smooth_ratio * g_next);
uint8_t b = (uint8_t) ((1.0f - smooth_ratio) * b_curr + smooth_ratio * b_next);
uint32_t color = (r << 16) | (g << 8) | b;

strip_set_color(leds, strip, color, strip->brightness, 1.0f);
}

static void led_strip_animate(Leds *leds, const LedStrip *strip, const LedBar *bar, float time) {
time *= bar->speed;

Expand All @@ -330,6 +386,12 @@ static void led_strip_animate(Leds *leds, const LedStrip *strip, const LedBar *b
case LED_MODE_FELONY:
anim_felony(leds, strip, bar, time);
break;
case LED_MODE_RAINBOW_CYCLE:
anim_rainbow_cycle(leds, strip, time);
break;
case LED_MODE_RAINBOW_FADE:
anim_rainbow_fade(leds, strip, time);
break;
}
}

Expand Down

0 comments on commit fae1b23

Please sign in to comment.