Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LEDs: add rainbow effects #11

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
58 changes: 47 additions & 11 deletions src/leds.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#define W(c) ((uint8_t) ((c) >> 24))
#define RGB(r, g, b) ((r) << 16 | (g) << 8 | (b))
#define RGBW(r, g, b, w) ((w) << 24 | (r) << 16 | (g) << 8 | (b))
#define TAU (2.0 * M_PI)

static const uint32_t colors[] = {
0x00000000, // BLACK
Expand Down Expand Up @@ -99,18 +100,21 @@ static uint32_t color_blend(uint32_t color1, uint32_t color2, float blend) {
return RGBW(r, g, b, w);
}

// Borrowed from WLED
// This function is an approximation of `sqrtf(sinf(x) * 0.5 + 0.5)`
inline static float taylor_series(float zero_to_tau) {
float x = (-0.5 * zero_to_tau) + 2.4;
float x3 = x * x * x;
float x5 = x3 * x * x;
float r = fabs(x - (x3 / 6.0) + (x5 / 120.0));
return fminf(r, 1.0f);
}

static uint32_t color_wheel(uint8_t pos) {
pos = 255 - pos;
if (pos < 85) {
return ((uint32_t) (255 - pos * 3) << 16) | ((uint32_t) 0 << 8) | (pos * 3);
} else if (pos < 170) {
pos -= 85;
return ((uint32_t) 0 << 16) | ((uint32_t) (pos * 3) << 8) | (255 - pos * 3);
} else {
pos -= 170;
return ((uint32_t) (pos * 3) << 16) | ((uint32_t) (255 - pos * 3) << 8) | 0;
}
float norm = (float) pos / 255.0;
float r = taylor_series((norm + 0.0 / 3.0) * TAU);
float b = taylor_series((norm + 1.0 / 3.0) * TAU);
float g = taylor_series((norm + 2.0 / 3.0) * TAU);
return ((uint8_t) (r * 255) << 16) | ((uint8_t) (g * 255) << 8) | (uint8_t) (b * 255);
}

static void sattolo_shuffle(uint32_t seed, uint8_t *array, uint8_t length) {
Expand Down Expand Up @@ -308,6 +312,32 @@ 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 void anim_rgb_fade(Leds *leds, const LedStrip *strip, float time) {
strip_set_color(
leds,
strip,
color_wheel((uint8_t) floorf(fmodf(time, 4.0f) * 255.0f)),
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 +360,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_rgb_fade(leds, strip, time);
break;
}
}

Expand Down
Loading