Skip to content

Commit

Permalink
LEDs: add felony effect
Browse files Browse the repository at this point in the history
This effect mimics the pattern of common emergency service vehicles.
Its colors are configurable, as well as its speed via Refloat settings.

In the case where the LED strip has an odd number of LEDs, the middle
LED is kept as solid black to ensure the effect is symmetrical.

Feature: Add the Felony LED effect.
  • Loading branch information
acheronfail committed Aug 14, 2024
1 parent c2cd04e commit fae1ac9
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 4 deletions.
3 changes: 2 additions & 1 deletion src/conf/datatypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ typedef enum {
LED_MODE_FADE,
LED_MODE_PULSE,
LED_MODE_STROBE,
LED_MODE_KNIGHT_RIDER
LED_MODE_KNIGHT_RIDER,
LED_MODE_FELONY,
} LedMode;

typedef enum {
Expand Down
5 changes: 5 additions & 0 deletions src/conf/settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2254,6 +2254,7 @@ p, li { white-space: pre-wrap; }
<enumNames>Pulse</enumNames>
<enumNames>Strobe</enumNames>
<enumNames>Knight Rider</enumNames>
<enumNames>Felony</enumNames>
</leds.front.mode>
<leds.front.brightness>
<longName>Front Brightness</longName>
Expand Down Expand Up @@ -2415,6 +2416,7 @@ p, li { white-space: pre-wrap; }
<enumNames>Pulse</enumNames>
<enumNames>Strobe</enumNames>
<enumNames>Knight Rider</enumNames>
<enumNames>Felony</enumNames>
</leds.rear.mode>
<leds.rear.brightness>
<longName>Rear Brightness</longName>
Expand Down Expand Up @@ -2576,6 +2578,7 @@ p, li { white-space: pre-wrap; }
<enumNames>Pulse</enumNames>
<enumNames>Strobe</enumNames>
<enumNames>Knight Rider</enumNames>
<enumNames>Felony</enumNames>
</leds.headlights.mode>
<leds.headlights.brightness>
<longName>Headlights Brightness</longName>
Expand Down Expand Up @@ -2739,6 +2742,7 @@ p, li { white-space: pre-wrap; }
<enumNames>Pulse</enumNames>
<enumNames>Strobe</enumNames>
<enumNames>Knight Rider</enumNames>
<enumNames>Felony</enumNames>
</leds.taillights.mode>
<leds.taillights.brightness>
<longName>Taillights Brightness</longName>
Expand Down Expand Up @@ -3030,6 +3034,7 @@ p, li { white-space: pre-wrap; }
<enumNames>Pulse</enumNames>
<enumNames>Strobe</enumNames>
<enumNames>Knight Rider</enumNames>
<enumNames>Felony</enumNames>
</leds.status_idle.mode>
<leds.status_idle.brightness>
<longName>Status Idle Brightness</longName>
Expand Down
57 changes: 54 additions & 3 deletions src/leds.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,14 +169,28 @@ static void led_set_color(
leds->led_data[led] = RGBW(r, g, b, w);
}

static void strip_set_color(
Leds *leds, const LedStrip *strip, uint32_t color, float brightness, float blend
static void strip_set_color_range(
Leds *leds,
const LedStrip *strip,
uint32_t color,
float brightness,
float blend,
uint8_t idx_start,
uint8_t idx_end
) {
for (uint8_t i = 0; i < strip->length; ++i) {
uint8_t start = idx_start < strip->length ? idx_start : 0;
uint8_t end = idx_end < strip->length ? idx_end : strip->length;
for (uint8_t i = start; i < end; ++i) {
led_set_color(leds, strip, i, color, brightness, blend);
}
}

static void strip_set_color(
Leds *leds, const LedStrip *strip, uint32_t color, float brightness, float blend
) {
strip_set_color_range(leds, strip, color, brightness, blend, 0, strip->length);
}

// Returns a cosine wave oscillating from 0 to 1, starting at 0, with a period of 2s.
static float cosine_progress(float time) {
uint32_t rounded = lroundf(time);
Expand Down Expand Up @@ -261,6 +275,40 @@ static void anim_knight_rider(Leds *leds, const LedStrip *strip, const LedBar *b
}
}

static void anim_felony(Leds *leds, const LedStrip *strip, const LedBar *bar, float time) {
uint32_t color_off = 0x00000000;

float state_duration = 0.05f;
float state_mod = fmodf(time, 3.0f * state_duration);

// also account for led strips with odd numbers of leds (leaving the middle one black)
uint8_t stop_idx = strip->length / 2;
uint8_t start_idx = strip->length / 2 + (strip->length % 2 * 2);
if (state_mod < state_duration) {
strip_set_color_range(
leds, strip, colors[bar->color1], strip->brightness, 1.0f, 0, stop_idx
);
strip_set_color_range(leds, strip, color_off, strip->brightness, 1.0f, stop_idx, start_idx);
strip_set_color_range(
leds, strip, color_off, strip->brightness, 1.0f, start_idx, strip->length
);
} else if (state_mod < 2.0f * state_duration) {
strip_set_color_range(leds, strip, color_off, strip->brightness, 1.0f, 0, stop_idx);
strip_set_color_range(leds, strip, color_off, strip->brightness, 1.0f, stop_idx, start_idx);
strip_set_color_range(
leds, strip, colors[bar->color2], strip->brightness, 1.0f, start_idx, strip->length
);
} else {
strip_set_color_range(
leds, strip, colors[bar->color2], strip->brightness, 1.0f, 0, stop_idx
);
strip_set_color_range(leds, strip, color_off, strip->brightness, 1.0f, stop_idx, start_idx);
strip_set_color_range(
leds, strip, colors[bar->color1], strip->brightness, 1.0f, start_idx, strip->length
);
}
}

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

Expand All @@ -280,6 +328,9 @@ static void led_strip_animate(Leds *leds, const LedStrip *strip, const LedBar *b
case LED_MODE_KNIGHT_RIDER:
anim_knight_rider(leds, strip, bar, time);
break;
case LED_MODE_FELONY:
anim_felony(leds, strip, bar, time);
break;
}
}

Expand Down

0 comments on commit fae1ac9

Please sign in to comment.