Future Electronics
/
sequana-rgb-led-example
Example program to blink RGB LEDs on Sequana board in a rotating pattern.
Revision 2:a83100cd9c9a, committed 2019-03-04
- Comitter:
- lru
- Date:
- Mon Mar 04 14:15:06 2019 +0000
- Parent:
- 1:6a23b9606443
- Commit message:
- Updated color selection algorithm
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
diff -r 6a23b9606443 -r a83100cd9c9a main.cpp --- a/main.cpp Mon Mar 04 14:09:22 2019 +0000 +++ b/main.cpp Mon Mar 04 14:15:06 2019 +0000 @@ -24,6 +24,7 @@ BD2808 leds; +// Return new color value by dimming the current color to x% BGR24_color_t dim(BGR24_color_t color, uint8_t percent) { BGR24_color_t new_color; @@ -37,56 +38,73 @@ #define sat(x) (uint8_t)((x) > 255? 255 : (x) < 0? 0 : (x)) +// This function generates color sequence. Each call to this function +// returns the next color in a sequence. +// Color sequence generation algorithm is such, that it provides +// smooth color swipe, keeping intensity roughly the same. BGR24_color_t gen_color() { - const uint8_t step = 20; + const uint8_t step = 40; const uint8_t max = 200; - static uint32_t i = 0; - static uint32_t j = 0; + static uint32_t phase = 0; static int32_t r = max; static int32_t g = max; static int32_t b = 0; - static uint8_t pull = 0; + static int32_t base_level = 6; - if (++j == 6) - { - j = 0; - if ( i < 10) - { - b += step; - r -= step; - } - else if (i < 20) - { - r += step; - g -= step; - } - else if (i < 30) - { - g += step; - b -= step; - } +#define step_up(x) do { if ((x += step) > max) x = max; } while(0) +#define step_down(x, v) do { x -= step; if (x < v) x = v;} while (0) - if (++i >= 30) { - i = 0; - } - - if (i == 0) { - if ((pull += 20) > 180) { - pull = 0; + switch (phase) { + case 0: + // swiping from reddish into blueish + step_down(r, 0); + g = base_level; + step_up(b); + if (r == 0) phase++; + break; + case 1: + // swiping from blueish into greenish to level off blue + r = 0; + step_up(g); + step_down(b, base_level); + if (b == base_level) phase++; + break; + case 2: + // swiping from greenish into reddish + step_up(r); + step_down(g, 0); + b = base_level; + if (g == 0) phase++; + break; + case 3: + // swiping from reddish into blueish to level off red + step_down(r, base_level); + g = 0; + step_up(b); + if (r == base_level) phase++; + break; + case 4: + // swiping from blueish into greenish + r = base_level; + step_up(g); + step_down(b, 0); + if (b == 0) phase++; + break; + case 5: + // swiping from greenish into reddish to level off green + step_up(r); + step_down(g, base_level); + b = 0; + if (g == base_level) { + phase = 0; + base_level *= 2; + if (base_level > 200) { + base_level = 6; + } + g = base_level; } - g = max - pull; - r = max ;//+ pull/2; - b = pull / 2; - } else if (i == 10) { - b = max - pull; - r = pull/2; - g = max ;//+ pull/2; - } else if (i == 20) { - r = max - pull; - g = pull / 2; - b = max ;//+ pull/2; - } + break; } return BGR24_color_t(sat(b), sat(g), sat(r)); @@ -95,29 +113,44 @@ #define NUM_LEDS_LIGHTING 3 +// Keeps indexes of LEDs that should be on in the next step. uint32_t led_index[NUM_LEDS_LIGHTING] = {0, 1, 2}; +// Current color. BGR24_color_t current_col[NUM_LEDS_LIGHTING]; // main() runs in its own thread in the OS int main() { + int color_step = 0; leds.set_dma_usage(DMA_USAGE_ALWAYS); while (true) { + // This defines phase relationship between rotating pattern + // and color change. + // As there are 8 steps for the whole circle (8 LEDs) + // value of 6 means the color changes every 3/4 of rotation. + if (++color_step == 6) { + color_step = 0; + current_col[2] = gen_color(); + current_col[1] = dim(current_col[2], 50); + current_col[0] = dim(current_col[2], 10); + } + + // Set up lighting pattern for current step. for (int i = 0; i < NUM_LEDS_LIGHTING; ++i) { leds.set_color(led_index[i], current_col[i]); } leds.refresh(); wait_ms(50); + // Turn off set LEDs, so we have a dark frame buffer again. + // Must be done after delay, as with DMA refresh() operation + // only starts LEDs updating from the frame buffer. leds.set_color(led_index[0], BGR24_color_t(0,0,0)); + // Update lighting LED indexes for the next step. for (int i = 0; i < NUM_LEDS_LIGHTING; ++i) { if (++led_index[i] == 8) led_index[i] = 0; } - current_col[2] = gen_color(); - current_col[1] = dim(current_col[2], 50); - current_col[0] = dim(current_col[2], 15); } } -