diff --git a/Inc/ws2812b.h b/Inc/ws2812b.h index f8541e4..59e9737 100644 --- a/Inc/ws2812b.h +++ b/Inc/ws2812b.h @@ -1,11 +1,11 @@ /* * ws2812b.h * - * The MIT License. - * Created on: 14.07.2017 - * Author: Mateusz Salamon - * www.msalamon.pl - * mateusz@msalamon.pl + * The MIT License. + * Created on: 14.07.2017 + * Author: Mateusz Salamon + * www.msalamon.pl + * mateusz@msalamon.pl */ #ifndef WS2812B_H_ @@ -36,17 +36,16 @@ typedef union __attribute__((packed, aligned(4))) ws2812b_color_u { } ws2812b_color; /* Function Prototypes */ -void WS2812B_Init(SPI_HandleTypeDef * spi_handler); -void WS2812B_SetDiodeColor(uint16_t diode_id, uint32_t color); -void WS2812B_SetDiodeColorStruct(uint16_t diode_id, ws2812b_color color); -void WS2812B_SetDiodeRGB(uint16_t diode_id, uint8_t r, uint8_t g, uint8_t b); -void WS2812B_SetDiodeRGBX(uint16_t diode_id, uint8_t r, uint8_t g, uint8_t b, uint8_t x); -void WS2812B_SetDiodeHSV(uint16_t diode_id, uint16_t hue, uint8_t sat, uint8_t brt); -uint32_t WS2812B_GetColor(uint16_t diode_id); -uint8_t* WS2812B_GetPixels(void); -void WS2812B_Refresh(); - -// color correction +void ws2812_init(SPI_HandleTypeDef *hspi); +void ws2812_set_led_color_val(uint16_t diode_id, uint32_t color); +void ws2812_set_led_color(uint16_t diode_id, ws2812b_color color); +void ws2812_set_led_rgb(uint16_t diode_id, uint8_t r, uint8_t g, uint8_t b); +void ws2812_set_led_rgbx(uint16_t diode_id, uint8_t r, uint8_t g, uint8_t b, uint8_t x); +void ws2812_set_led_hsv(uint16_t diode_id, uint16_t hue, uint8_t sat, uint8_t value); +uint32_t ws2812_get_color(uint16_t diode_id); +uint8_t *ws2812_get_pixels(); +void ws2812_refresh(); uint8_t sine8(uint8_t x); uint8_t gamma8(uint8_t x); + #endif /* WS2812B_H_ */ diff --git a/Inc/ws2812b_fx.h b/Inc/ws2812b_fx.h index 628253f..2d3e32d 100644 --- a/Inc/ws2812b_fx.h +++ b/Inc/ws2812b_fx.h @@ -1,110 +1,111 @@ /* * ws2812b_fx.h * - * Library based on Harm Aldick's Arduino library - * https://github.com/kitesurfer1404/WS2812FX + * Library based on Harm Aldick's Arduino library + * https://github.com/kitesurfer1404/WS2812FX * - * The MIT License. - * Created on: 20.10.2018 - * Author: Mateusz Salamon - * www.msalamon.pl - * mateusz@msalamon.pl + * The MIT License. + * Created on: 20.10.2018 + * Author: Mateusz Salamon + * www.msalamon.pl + * mateusz@msalamon.pl */ #ifndef WS2812B_FX_H_ #define WS2812B_FX_H_ -#define DEFAULT_COLOR 0x00F0000000 -#define NUM_COLORS 4 - -#define SPEED_MIN 10 -#define DEFAULT_SPEED 150 -#define SPEED_MAX 65535 - -#define MODE_COUNT 58 -#define DEFAULT_MODE 0 - -#define FADE_RATE 2 - -// some common colors -#define RED (uint32_t)0xFF0000 -#define GREEN (uint32_t)0x00FF00 -#define BLUE (uint32_t)0x0000FF -#define WHITE (uint32_t)0xFFFFFF -#define BLACK (uint32_t)0x000000 -#define YELLOW (uint32_t)0xFFFF00 -#define CYAN (uint32_t)0x00FFFF -#define MAGENTA (uint32_t)0xFF00FF -#define PURPLE (uint32_t)0x400080 -#define ORANGE (uint32_t)0xFF3000 -#define PINK (uint32_t)0xFF1493 - +/* Includes */ +#include + +/* Definitions */ +#define DEFAULT_COLOR (0x00F0000000) +#define NUM_COLORS (4) +#define SPEED_MIN (10) +#define DEFAULT_SPEED (150) +#define SPEED_MAX (65535) +#define MODE_COUNT (58) +#define DEFAULT_MODE (0) +#define FADE_RATE (2) +/* some common colors */ +#define RED (0xFF0000U) +#define GREEN (0x00FF00U) +#define BLUE (0x0000FFU) +#define WHITE (0xFFFFFFU) +#define BLACK (0x000000U) +#define YELLOW (0xFFFF00U) +#define CYAN (0x00FFFFU) +#define MAGENTA (0xFF00FFU) +#define PURPLE (0x400080U) +#define ORANGE (0xFF3000U) +#define PINK (0xFF1493U) + +/* Data Structures */ typedef enum { - FX_OK = 0, - FX_ERROR = 1 + FX_OK = 0, + FX_ERROR = 1 } FX_STATUS; - typedef enum { -FX_MODE_STATIC, -FX_MODE_WHITE_TO_COLOR, -FX_MODE_BLACK_TO_COLOR, -FX_MODE_BLINK, -FX_MODE_BLINK_RAINBOW, -FX_MODE_STROBE, -FX_MODE_STROBE_RAINBOW, -FX_MODE_BREATH, -FX_MODE_COLOR_WIPE, -FX_MODE_COLOR_WIPE_INV, -FX_MODE_COLOR_WIPE_REV, -FX_MODE_COLOR_WIPE_REV_INV, -FX_MODE_COLOR_WIPE_RANDOM, -FX_MODE_COLOR_SWEEP_RANDOM, -FX_MODE_RANDOM_COLOR, -FX_MODE_SINGLE_DYNAMIC, -FX_MODE_MULTI_DYNAMIC, -FX_MODE_RAINBOW, -FX_MODE_RAINBOW_CYCLE, -FX_MODE_FADE, -FX_MODE_SCAN, -FX_MODE_DUAL_SCAN, -FX_MODE_THEATER_CHASE, -FX_MODE_THEATER_CHASE_RAINBOW, -FX_MODE_RUNNING_LIGHTS, -FX_MODE_TWINKLE, -FX_MODE_TWINKLE_RANDOM, -FX_MODE_TWINKLE_FADE, -FX_MODE_TWINKLE_FADE_RANDOM, -FX_MODE_SPARKLE, -FX_MODE_FLASH_SPARKLE, -FX_MODE_HYPER_SPARKLE, -FX_MODE_MULTI_STROBE, -FX_MODE_CHASE_WHITE, -FX_MODE_CHASE_COLOR, -FX_MODE_CHASE_RANDOM, -FX_MODE_CHASE_RAINBOW, -FX_MODE_CHASE_FLASH, -FX_MODE_CHASE_FLASH_RANDOM, -FX_MODE_CHASE_RAINBOW_WHITE, -FX_MODE_CHASE_BLACKOUT, -FX_MODE_CHASE_BLACKOUT_RAINBOW, -FX_MODE_RUNNING_COLOR, -FX_MODE_RUNNING_RED_BLUE, -FX_MODE_RUNNING_RANDOM, -FX_MODE_LARSON_SCANNER, -FX_MODE_COMET, -FX_MODE_FIREWORKS, -FX_MODE_FIREWORKS_RANDOM, -FX_MODE_MERRY_CHRISTMAS, -FX_MODE_FIRE_FLICKER, -FX_MODE_FIRE_FLICKER_SOFT, -FX_MODE_FIRE_FLICKER_INTENSE, -FX_MODE_CIRCUS_COMBUSTUS, -FX_MODE_HALLOWEEN, -FX_MODE_BICOLOR_CHASE, -FX_MODE_TRICOLOR_CHASE, -FX_MODE_ICU, + FX_MODE_STATIC, + FX_MODE_WHITE_TO_COLOR, + FX_MODE_BLACK_TO_COLOR, + FX_MODE_BLINK, + FX_MODE_BLINK_RAINBOW, + FX_MODE_STROBE, + FX_MODE_STROBE_RAINBOW, + FX_MODE_BREATH, + FX_MODE_COLOR_WIPE, + FX_MODE_COLOR_WIPE_INV, + FX_MODE_COLOR_WIPE_REV, + FX_MODE_COLOR_WIPE_REV_INV, + FX_MODE_COLOR_WIPE_RANDOM, + FX_MODE_COLOR_SWEEP_RANDOM, + FX_MODE_RANDOM_COLOR, + FX_MODE_SINGLE_DYNAMIC, + FX_MODE_MULTI_DYNAMIC, + FX_MODE_RAINBOW, + FX_MODE_RAINBOW_CYCLE, + FX_MODE_FADE, + FX_MODE_SCAN, + FX_MODE_DUAL_SCAN, + FX_MODE_THEATER_CHASE, + FX_MODE_THEATER_CHASE_RAINBOW, + FX_MODE_RUNNING_LIGHTS, + FX_MODE_TWINKLE, + FX_MODE_TWINKLE_RANDOM, + FX_MODE_TWINKLE_FADE, + FX_MODE_TWINKLE_FADE_RANDOM, + FX_MODE_SPARKLE, + FX_MODE_FLASH_SPARKLE, + FX_MODE_HYPER_SPARKLE, + FX_MODE_MULTI_STROBE, + FX_MODE_CHASE_WHITE, + FX_MODE_CHASE_COLOR, + FX_MODE_CHASE_RANDOM, + FX_MODE_CHASE_RAINBOW, + FX_MODE_CHASE_FLASH, + FX_MODE_CHASE_FLASH_RANDOM, + FX_MODE_CHASE_RAINBOW_WHITE, + FX_MODE_CHASE_BLACKOUT, + FX_MODE_CHASE_BLACKOUT_RAINBOW, + FX_MODE_RUNNING_COLOR, + FX_MODE_RUNNING_RED_BLUE, + FX_MODE_RUNNING_RANDOM, + FX_MODE_LARSON_SCANNER, + FX_MODE_COMET, + FX_MODE_FIREWORKS, + FX_MODE_FIREWORKS_RANDOM, + FX_MODE_MERRY_CHRISTMAS, + FX_MODE_FIRE_FLICKER, + FX_MODE_FIRE_FLICKER_SOFT, + FX_MODE_FIRE_FLICKER_INTENSE, + FX_MODE_CIRCUS_COMBUSTUS, + FX_MODE_HALLOWEEN, + FX_MODE_BICOLOR_CHASE, + FX_MODE_TRICOLOR_CHASE, + FX_MODE_ICU } fx_mode; +/* Function Prototypes */ FX_STATUS WS2812BFX_Init(uint16_t Segments); FX_STATUS WS2812BFX_SegmentIncrease(void); FX_STATUS WS2812BFX_SegmentDecrease(void); diff --git a/Src/ws2812b.c b/Src/ws2812b.c index 690e0e8..748246e 100644 --- a/Src/ws2812b.c +++ b/Src/ws2812b.c @@ -1,11 +1,11 @@ /* * ws2812b.c * - * The MIT License. - * Created on: 14.07.2017 - * Author: Mateusz Salamon - * www.msalamon.pl - * mateusz@msalamon.pl + * The MIT License. + * Created on: 14.07.2017 + * Author: Mateusz Salamon + * www.msalamon.pl + * mateusz@msalamon.pl */ /* Includes */ @@ -23,12 +23,12 @@ #define BUFFER_SIZE (WORD_SIZE * 2) /* Macros */ -#define return_if_fail(cond) if(!(cond)) { return; } -#define return_val_if_fail(cond, val) if(!(cond)) { return (val); } -#define return_null_if_fail(cond) return_val_if_fail((cond), NULL) +#define ws2812_return_if_fail(cond) if(!(cond)) { return; } +#define ws2812_return_val_if_fail(cond, val) if(!(cond)) { return (val); } +#define ws2812_return_null_if_fail(cond) ws2812_return_val_if_fail((cond), NULL) /* Private Constants */ -static const uint8_t _sineTable[256] = { +static const uint8_t sine_lut8[256] = { 128,131,134,137,140,143,146,149,152,155,158,162,165,167,170,173, 176,179,182,185,188,190,193,196,198,201,203,206,208,211,213,215, 218,220,222,224,226,228,230,232,234,235,237,238,240,241,243,244, @@ -46,7 +46,7 @@ static const uint8_t _sineTable[256] = { 37, 40, 42, 44, 47, 49, 52, 54, 57, 59, 62, 65, 67, 70, 73, 76, 79, 82, 85, 88, 90, 93, 97,100,103,106,109,112,115,118,121,124}; -static const uint8_t _gammaTable[256] = { +static const uint8_t gamma_lut8[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, @@ -70,114 +70,104 @@ ws2812b_color ws2812b_array[WS2812B_LEDS]; /* Private Global Variables */ static uint8_t buffer[BUFFER_SIZE]; -static uint16_t CurrentLed; -static uint8_t ResetSignal; +static uint16_t curr_led; +static uint8_t reset_sig; -void WS2812B_Init(SPI_HandleTypeDef * spi_handler) +/* Function Definitions */ +void ws2812_init(SPI_HandleTypeDef *hspi) { - hspi_ws2812b = spi_handler; + hspi_ws2812b = hspi; } -void WS2812B_SetDiodeColor(uint16_t diode_id, uint32_t color) +void ws2812_set_led_color_val(uint16_t diode_id, uint32_t color) { - return_if_fail(diode_id < WS2812B_LEDS); + ws2812_return_if_fail(diode_id < WS2812B_LEDS); ws2812b_array[diode_id].u32 = color; } -void WS2812B_SetDiodeColorStruct(uint16_t diode_id, ws2812b_color color) +void ws2812_set_led_color(uint16_t diode_id, ws2812b_color color) { - return_if_fail(diode_id < WS2812B_LEDS); + ws2812_return_if_fail(diode_id < WS2812B_LEDS); ws2812b_array[diode_id] = color; } -void WS2812B_SetDiodeRGB(uint16_t diode_id, uint8_t r, uint8_t g, uint8_t b) +void ws2812_set_led_rgb(uint16_t diode_id, uint8_t r, uint8_t g, uint8_t b) { - return_if_fail(diode_id < WS2812B_LEDS); + ws2812_return_if_fail(diode_id < WS2812B_LEDS); ws2812b_array[diode_id].rgb.red = r; ws2812b_array[diode_id].rgb.green = g; ws2812b_array[diode_id].rgb.blue = b; } -void WS2812B_SetDiodeRGBX(uint16_t diode_id, uint8_t r, uint8_t g, uint8_t b, uint8_t x) +void ws2812_set_led_rgbx(uint16_t diode_id, uint8_t r, uint8_t g, uint8_t b, uint8_t x) { - return_if_fail(diode_id < WS2812B_LEDS); + ws2812_return_if_fail(diode_id < WS2812B_LEDS); ws2812b_array[diode_id].rgbx.red = r; ws2812b_array[diode_id].rgbx.green = g; ws2812b_array[diode_id].rgbx.blue = b; ws2812b_array[diode_id].rgbx.x = x; } -uint32_t WS2812B_GetColor(uint16_t diode_id) -{ - return_val_if_fail(diode_id < WS2812B_LEDS, 0); - - return ws2812b_array[diode_id].u32; -} - -uint8_t* WS2812B_GetPixels(void) -{ - return (uint8_t*)ws2812b_array; -} -// -// Set diode with HSV model -// -// Hue 0-359 -// Saturation 0-255 -// Birghtness(Value) 0-255 -// -void WS2812B_SetDiodeHSV(uint16_t diode_id, uint16_t hue, uint8_t sat, uint8_t brt) +/* + * Set diode with HSV model + * + * Hue 0-359 + * Saturation 0-255 + * Value 0-255 + */ +void ws2812_set_led_hsv(uint16_t diode_id, uint16_t hue, uint8_t sat, uint8_t value) { uint16_t sector, fract, p, q, t; - return_if_fail(diode_id < WS2812B_LEDS); + ws2812_return_if_fail(diode_id < WS2812B_LEDS); if(sat == 0) { - ws2812b_array[diode_id].rgb.red = brt; - ws2812b_array[diode_id].rgb.green = brt; - ws2812b_array[diode_id].rgb.blue = brt; + ws2812b_array[diode_id].rgb.red = value; + ws2812b_array[diode_id].rgb.green = value; + ws2812b_array[diode_id].rgb.blue = value; } else { if(hue >= 360) hue = 359; - sector = hue / 60; // Sector 0 to 5 + sector = hue / 60; /* hexcone HSV model -- 6 sectors */ fract = hue % 60; - p = (brt * (255 - sat)) / 256; - q = (brt * (255 - (sat * fract) / 60)) / 256; - t = (brt * (255 - (sat * (59 - fract)) / 60)) / 256; + p = (value * (255 - sat)) / 256; + q = (value * (255 - (sat * fract) / 60)) / 256; + t = (value * (255 - (sat * (59 - fract)) / 60)) / 256; switch(sector) { case 0: - ws2812b_array[diode_id].rgb.red = brt; + ws2812b_array[diode_id].rgb.red = value; ws2812b_array[diode_id].rgb.green = (uint8_t)t; ws2812b_array[diode_id].rgb.blue = (uint8_t)p; break; case 1: ws2812b_array[diode_id].rgb.red = (uint8_t)q; - ws2812b_array[diode_id].rgb.green = brt; + ws2812b_array[diode_id].rgb.green = value; ws2812b_array[diode_id].rgb.blue = (uint8_t)p; break; case 2: ws2812b_array[diode_id].rgb.red = (uint8_t)p; - ws2812b_array[diode_id].rgb.green = brt; + ws2812b_array[diode_id].rgb.green = value; ws2812b_array[diode_id].rgb.blue = (uint8_t)t; break; case 3: ws2812b_array[diode_id].rgb.red = (uint8_t)p; ws2812b_array[diode_id].rgb.green = (uint8_t)q; - ws2812b_array[diode_id].rgb.blue = brt; + ws2812b_array[diode_id].rgb.blue = value; break; case 4: ws2812b_array[diode_id].rgb.red = (uint8_t)t; ws2812b_array[diode_id].rgb.green = (uint8_t)p; - ws2812b_array[diode_id].rgb.blue = brt; + ws2812b_array[diode_id].rgb.blue = value; break; case 5: default: - ws2812b_array[diode_id].rgb.red = brt; + ws2812b_array[diode_id].rgb.red = value; ws2812b_array[diode_id].rgb.green = (uint8_t)p; ws2812b_array[diode_id].rgb.blue = (uint8_t)q; break; @@ -185,10 +175,22 @@ void WS2812B_SetDiodeHSV(uint16_t diode_id, uint16_t hue, uint8_t sat, uint8_t b } } -void WS2812B_Refresh() +uint32_t ws2812_get_color(uint16_t diode_id) +{ + ws2812_return_val_if_fail(diode_id < WS2812B_LEDS, 0); + + return ws2812b_array[diode_id].u32; +} + +uint8_t *ws2812_get_pixels() +{ + return (uint8_t*)ws2812b_array; +} + +void ws2812_refresh() { - CurrentLed = 0; - ResetSignal = 0; + curr_led = 0; + reset_sig = 0; for(uint8_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = 0x00; @@ -196,21 +198,32 @@ void WS2812B_Refresh() while(HAL_DMA_STATE_READY != HAL_DMA_GetState(hspi_ws2812b->hdmatx)); } +uint8_t sine8(uint8_t x) +{ + return sine_lut8[x]; +} + +uint8_t gamma8(uint8_t x) +{ + return gamma_lut8[x]; +} + +/* Private Function Definitions */ void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi) { if(hspi == hspi_ws2812b) { - if(!ResetSignal) + if(!reset_sig) { for(uint8_t k = 0; k < WORD_SIZE; k++) { buffer[k] = 0x00; } - ResetSignal = 1; // End reset signal + reset_sig = 1; /* End reset signal */ } - else // LEDs Odd 1,3,5,7... + else /* Odd LEDs 1, 3, 5, ... */ { - if(CurrentLed > WS2812B_LEDS) + if(curr_led > WS2812B_LEDS) { HAL_SPI_DMAStop(hspi_ws2812b); } @@ -219,13 +232,13 @@ void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi) uint8_t i = 0; for(int8_t j = WORD_SIZE - 1; j >= 0; j--) { - if((ws2812b_array[CurrentLed].u32 & (1 << j)) == 0) + if((ws2812b_array[curr_led].u32 & (1 << j)) == 0) buffer[i] = ZERO; else buffer[i] = ONE; i++; } - CurrentLed++; + curr_led++; } } } @@ -235,34 +248,24 @@ void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) { if(hspi == hspi_ws2812b) { - if(CurrentLed > WS2812B_LEDS) + if(curr_led > WS2812B_LEDS) { HAL_SPI_DMAStop(hspi_ws2812b); } else { - // Even LEDs 0,2,0 + /* Even LEDs 0, 2, 4, ... */ uint8_t i = WORD_SIZE; for(int8_t j = WORD_SIZE - 1; j >= 0; j--) { - if((ws2812b_array[CurrentLed].u32 & (1 << j)) == 0) + if((ws2812b_array[curr_led].u32 & (1 << j)) == 0) buffer[i] = ZERO; else buffer[i] = ONE; i++; } - CurrentLed++; + curr_led++; } } } - -uint8_t sine8(uint8_t x) -{ - return _sineTable[x]; -} - -uint8_t gamma8(uint8_t x) -{ - return _gammaTable[x]; -} diff --git a/Src/ws2812b_fx.c b/Src/ws2812b_fx.c index 7691850..6012067 100644 --- a/Src/ws2812b_fx.c +++ b/Src/ws2812b_fx.c @@ -1,59 +1,91 @@ /* * ws2812b_fx.c * - * Library based on Harm Aldick's Arduino library - * https://github.com/kitesurfer1404/WS2812FX + * Library based on Harm Aldick's Arduino library + * https://github.com/kitesurfer1404/WS2812FX * - * The MIT License. - * Created on: 20.10.2018 - * Author: Mateusz Salamon - * www.msalamon.pl - * mateusz@msalamon.pl + * The MIT License. + * Created on: 20.10.2018 + * Author: Mateusz Salamon + * www.msalamon.pl + * mateusz@msalamon.pl */ + +/* Includes */ #include "main.h" #include - #include "ws2812b.h" #include "ws2812b_fx.h" -#define MIN(a,b) (((a)<(b))?(a):(b)) -#define MAX(a,b) (((a)<(b))?(b):(a)) - -#define SEGMENT_LENGTH (Ws28b12b_Segments[mActualSegment].IdStop - Ws28b12b_Segments[mActualSegment].IdStart + 1) -#define IS_REVERSE Ws28b12b_Segments[mActualSegment].Reverse - -uint8_t mRunning; -uint8_t mTriggered; -uint8_t mActualSegment; - -uint16_t mSegments; - -uint32_t mColor[NUM_COLORS]; -ws2812b_color mColor_w[NUM_COLORS]; +/* Definitions */ +#define SEGMENT_LENGTH (Ws28b12b_Segments[mActualSegment].IdStop - Ws28b12b_Segments[mActualSegment].IdStart + 1) +#define IS_REVERSE (Ws28b12b_Segments[mActualSegment].Reverse) + +/* Macros */ +#define ws2812fx_return_if_fail(cond) if(!(cond)) { return; } +#define ws2812fx_return_val_if_fail(cond, val) if(!(cond)) { return (val); } +#define ws2812fx_return_null_if_fail(cond) ws2812_return_val_if_fail((cond), NULL) +/* MIN() and MAX() */ +#ifdef __GNUC__ +# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) +/* prevent double evaluation */ +# define MIN(a,b) \ + __extension__({ __auto_type _a = (a); \ + __auto_type _b = (b); \ + _a < _b ? _a : _b; }) +# define MAX(a,b) \ + __extension__({ __auto_type _a = (a); \ + __auto_type _b = (b); \ + _a > _b ? _a : _b; }) +# else +/* typesafety but double evaluation is possible */ +# define MIN(a,b) \ + __extension__({ __typeof__ (a) _a = (a); \ + __typeof__ (b) _b = (b); \ + _a < _b ? _a : _b; }) +# define MAX(a,b) \ + __extension__({ __typeof__ (a) _a = (a); \ + __typeof__ (b) _b = (b); \ + _a > _b ? _a : _b; }) +# endif +#else +/* no typesafety and double evaluation is possible */ +# define MIN(a,b) ((a) < (b) ? (a) : (b)) +# define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +uint8_t mRunning; +uint8_t mTriggered; +uint8_t mActualSegment; + +uint16_t mSegments; + +uint32_t mColor[NUM_COLORS]; +ws2812b_color mColor_w[NUM_COLORS]; typedef struct ws2812bfx_s { - volatile uint32_t ModeDelay; // Segment SW timer counter + volatile uint32_t ModeDelay; /* Segment SW timer counter */ - uint16_t IdStart; // Start segment point - uint16_t IdStop; // End segment point + uint16_t IdStart; /* Start segment point */ + uint16_t IdStop; /* End segment point */ - uint8_t Running : 1; // Is sector running - uint8_t ActualMode; // Sector mode setting - uint8_t Reverse : 1; // Is reverted mode - uint32_t CounterModeCall; // Numbers of calls - uint32_t CounterModeStep; // Call step + uint8_t Running : 1; /* Is sector running */ + uint8_t ActualMode; /* Sector mode setting */ + uint8_t Reverse : 1; /* Is reverted mode */ + uint32_t CounterModeCall; /* Numbers of calls */ + uint32_t CounterModeStep; /* Call step */ - uint16_t Speed; // Segment speed + uint16_t Speed; /* Segment speed */ - uint32_t ModeColor[NUM_COLORS]; // Mode color 32 bit representation - ws2812b_color ModeColor_w[NUM_COLORS]; // Mode color struct representation + uint32_t ModeColor[NUM_COLORS]; /* Mode color 32 bit representation */ + ws2812b_color ModeColor_w[NUM_COLORS]; /* Mode color struct representation */ - uint8_t AuxParam; // Computing variable - uint16_t AuxParam16b; // Computing variable - uint8_t Cycle : 1; // Cycle variable + uint8_t AuxParam; /* Computing variable */ + uint16_t AuxParam16b; /* Computing variable */ + uint8_t Cycle : 1; /* Cycle variable */ - void (*mModeCallback)(void); // Sector mode callback + void (*mModeCallback)(void); /* Sector mode callback */ } ws2812bfx_s; ws2812bfx_s *Ws28b12b_Segments = NULL; @@ -63,9 +95,9 @@ void (*mModeCallback)(void); /* * - * MODES + * MODES * - * */ + */ void strip_off(void), mode_static(void), @@ -145,68 +177,62 @@ void (*mMode[MODE_COUNT])(void) = mode_color_wipe_random, mode_color_sweep_random, mode_random_color, - mode_single_dynamic, - mode_multi_dynamic, - mode_rainbow, - mode_rainbow_cycle, - mode_fade, - mode_scan, - mode_dual_scan, - mode_theater_chase, - mode_theater_chase_rainbow, - mode_running_lights, - mode_twinkle, - mode_twinkle_random, + mode_single_dynamic, + mode_multi_dynamic, + mode_rainbow, + mode_rainbow_cycle, + mode_fade, + mode_scan, + mode_dual_scan, + mode_theater_chase, + mode_theater_chase_rainbow, + mode_running_lights, + mode_twinkle, + mode_twinkle_random, mode_twinkle_fade, mode_twinkle_fade_random, - mode_sparkle, - mode_flash_sparkle, - mode_hyper_sparkle, + mode_sparkle, + mode_flash_sparkle, + mode_hyper_sparkle, mode_multi_strobe, - mode_chase_white, - mode_chase_color, - mode_chase_random, - mode_chase_rainbow, - mode_chase_flash, - mode_chase_flash_random, - mode_chase_rainbow_white, - mode_chase_blackout, - mode_chase_blackout_rainbow, - mode_running_color, - mode_running_red_blue, - mode_running_random, - mode_larson_scanner, - mode_comet, - mode_fireworks, - mode_fireworks_random, - mode_merry_christmas, - mode_fire_flicker, - mode_fire_flicker_soft, - mode_fire_flicker_intense, - mode_circus_combustus, - mode_halloween, - mode_bicolor_chase, - mode_tricolor_chase, - mode_icu + mode_chase_white, + mode_chase_color, + mode_chase_random, + mode_chase_rainbow, + mode_chase_flash, + mode_chase_flash_random, + mode_chase_rainbow_white, + mode_chase_blackout, + mode_chase_blackout_rainbow, + mode_running_color, + mode_running_red_blue, + mode_running_random, + mode_larson_scanner, + mode_comet, + mode_fireworks, + mode_fireworks_random, + mode_merry_christmas, + mode_fire_flicker, + mode_fire_flicker_soft, + mode_fire_flicker_intense, + mode_circus_combustus, + mode_halloween, + mode_bicolor_chase, + mode_tricolor_chase, + mode_icu }; FX_STATUS WS2812BFX_Init(uint16_t Segments) { - if(Segments == 0) return FX_ERROR; - if(Segments > (WS2812B_LEDS / 2)) - { - if(Segments > WS2812B_LEDS) - { - return FX_ERROR; - } - } - uint16_t div = 0; ws2812bfx_s *SegmentsTmp = NULL; - SegmentsTmp = calloc(Segments, sizeof(ws2812bfx_s)); // Assign the space for new segments + ws2812fx_return_val_if_fail(Segments, FX_ERROR); + ws2812fx_return_val_if_fail(Segments < WS2812B_LEDS, FX_ERROR); + + SegmentsTmp = calloc(Segments, sizeof(ws2812bfx_s)); /* Assign the space for new segments */ - if(SegmentsTmp == NULL) return FX_ERROR; // If assigning failed + ws2812fx_return_val_if_fail(SegmentsTmp, FX_ERROR); /* If assigning failed */ if(Ws28b12b_Segments == NULL) { @@ -224,7 +250,7 @@ FX_STATUS WS2812BFX_Init(uint16_t Segments) div++; } } - else // Ws28b12b_Segments was before initialized + else /* Ws28b12b_Segments was before initialized */ { for(uint16_t i = 0; i < (Segments>mSegments?mSegments:Segments); i++) { @@ -253,11 +279,11 @@ FX_STATUS WS2812BFX_Init(uint16_t Segments) SegmentsTmp[i].mModeCallback = Ws28b12b_Segments[i].mModeCallback; } - if(Segments > mSegments) // Add new Segment + if(Segments > mSegments) /* Add new Segment */ { SegmentsTmp[Segments - 1].Speed = DEFAULT_SPEED; SegmentsTmp[Segments - 1].ActualMode = DEFAULT_MODE; - SegmentsTmp[Segments - 1].Running = 0; // Sany new segment is stopped by default + SegmentsTmp[Segments - 1].Running = 0; /* any new segment is stopped by default */ SegmentsTmp[Segments - 1].IdStart = div; div += ((WS2812B_LEDS + 1) / Segments) - 1; @@ -267,7 +293,7 @@ FX_STATUS WS2812BFX_Init(uint16_t Segments) mSegments = Segments; } - free(Ws28b12b_Segments); // Free previous array if reinit + free(Ws28b12b_Segments); /* Free previous array if reinit */ Ws28b12b_Segments = SegmentsTmp; return FX_OK; } @@ -281,8 +307,8 @@ FX_STATUS WS2812BFX_SegmentIncrease(void) { if(mSegments < (WS2812B_LEDS - 1)) { - WS2812BFX_Init(mSegments + 1); - return FX_OK; + WS2812BFX_Init(mSegments + 1); + return FX_OK; } return FX_ERROR; } @@ -292,7 +318,7 @@ FX_STATUS WS2812BFX_SegmentDecrease(void) if(mSegments > 1) { WS2812BFX_Init(mSegments - 1); - return FX_OK; + return FX_OK; } return FX_ERROR; } @@ -306,32 +332,32 @@ void WS2812BFX_SysTickCallback(void) void WS2812BFX_Callback() { static uint8_t trig = 0;; - if(mRunning || mTriggered) - { - for(uint16_t i = 0; i < mSegments; i++) - { - if(Ws28b12b_Segments[i].ModeDelay == 0) - { - if(Ws28b12b_Segments[i].Running) - { - mActualSegment = i; - Ws28b12b_Segments[i].mModeCallback(); - Ws28b12b_Segments[i].CounterModeCall++; - trig = 1; - } - } - } - if(trig) - { - WS2812B_Refresh(); - trig = 0; - } - } + if(mRunning || mTriggered) + { + for(uint16_t i = 0; i < mSegments; i++) + { + if(Ws28b12b_Segments[i].ModeDelay == 0) + { + if(Ws28b12b_Segments[i].Running) + { + mActualSegment = i; + Ws28b12b_Segments[i].mModeCallback(); + Ws28b12b_Segments[i].CounterModeCall++; + trig = 1; + } + } + } + if(trig) + { + ws2812_refresh(); + trig = 0; + } + } } FX_STATUS WS2812BFX_SetMode(uint16_t Segment, fx_mode Mode) { - if(Segment >= mSegments) return FX_ERROR; + ws2812fx_return_val_if_fail(Segment < mSegments, FX_ERROR); Ws28b12b_Segments[Segment].CounterModeCall = 0; Ws28b12b_Segments[Segment].CounterModeStep = 0; Ws28b12b_Segments[Segment].ActualMode = Mode; @@ -346,14 +372,14 @@ FX_STATUS WS2812BFX_SetMode(uint16_t Segment, fx_mode Mode) FX_STATUS WS2812BFX_GetMode(uint16_t Segment, fx_mode *Mode) { - if(Segment >= mSegments) return FX_ERROR; + ws2812fx_return_val_if_fail(Segment < mSegments, FX_ERROR); *Mode = Ws28b12b_Segments[Segment].ActualMode; return FX_OK; } FX_STATUS WS2812BFX_NextMode(uint16_t Segment) { - if(Segment >= mSegments) return FX_ERROR; + ws2812fx_return_val_if_fail(Segment < mSegments, FX_ERROR); Ws28b12b_Segments[Segment].CounterModeCall = 0; Ws28b12b_Segments[Segment].CounterModeStep = 0; Ws28b12b_Segments[Segment].ActualMode++; @@ -364,7 +390,7 @@ FX_STATUS WS2812BFX_NextMode(uint16_t Segment) FX_STATUS WS2812BFX_PrevMode(uint16_t Segment) { - if(Segment >= mSegments) return FX_ERROR; + ws2812fx_return_val_if_fail(Segment < mSegments, FX_ERROR); Ws28b12b_Segments[Segment].CounterModeCall = 0; Ws28b12b_Segments[Segment].CounterModeStep = 0; Ws28b12b_Segments[Segment].ActualMode--; @@ -375,8 +401,8 @@ FX_STATUS WS2812BFX_PrevMode(uint16_t Segment) FX_STATUS WS2812BFX_SetReverse(uint16_t Segment, uint8_t Reverse) { - if(Segment >= mSegments) return FX_ERROR; - WS2812BFX_SetAll(Segment, BLACK); // Set all 'old' segment black + ws2812fx_return_val_if_fail(Segment < mSegments, FX_ERROR); + WS2812BFX_SetAll(Segment, BLACK); /* Set all 'old' segment black */ if(Reverse > 1) Reverse = 1; @@ -386,15 +412,15 @@ FX_STATUS WS2812BFX_SetReverse(uint16_t Segment, uint8_t Reverse) FX_STATUS WS2812BFX_GetReverse(uint16_t Segment, uint8_t *Reverse) { - if(Segment >= mSegments) return FX_ERROR; + ws2812fx_return_val_if_fail(Segment < mSegments, FX_ERROR); *Reverse = Ws28b12b_Segments[Segment].Reverse; return FX_OK; } FX_STATUS WS2812BFX_SegmentIncreaseStart(uint16_t Segment) { - if(Segment >= mSegments) return FX_ERROR; - WS2812BFX_SetAll(Segment, BLACK); // Set all 'old' segment black + ws2812fx_return_val_if_fail(Segment < mSegments, FX_ERROR); + WS2812BFX_SetAll(Segment, BLACK); /* Set all 'old' segment black */ if((Ws28b12b_Segments[Segment].IdStop - Ws28b12b_Segments[Segment].IdStart) > 0) { @@ -405,8 +431,8 @@ FX_STATUS WS2812BFX_SegmentIncreaseStart(uint16_t Segment) FX_STATUS WS2812BFX_SegmentDecreaseStart(uint16_t Segment) { - if(Segment >= mSegments) return FX_ERROR; - WS2812BFX_SetAll(Segment, BLACK); // Set all 'old' segment black + ws2812fx_return_val_if_fail(Segment < mSegments, FX_ERROR); + WS2812BFX_SetAll(Segment, BLACK); /* Set all 'old' segment black */ if(Segment > 0) { @@ -415,7 +441,7 @@ FX_STATUS WS2812BFX_SegmentDecreaseStart(uint16_t Segment) Ws28b12b_Segments[Segment].IdStart--; } } - else // Segment == 0 + else /* Segment == 0 */ { if(0 < Ws28b12b_Segments[Segment].IdStart) { @@ -427,8 +453,8 @@ FX_STATUS WS2812BFX_SegmentDecreaseStart(uint16_t Segment) FX_STATUS WS2812BFX_SegmentIncreaseEnd(uint16_t Segment) { - if(Segment >= mSegments) return FX_ERROR; - WS2812BFX_SetAll(Segment, BLACK); // Set all 'old' segment black + ws2812fx_return_val_if_fail(Segment < mSegments, FX_ERROR); + WS2812BFX_SetAll(Segment, BLACK); /* Set all 'old' segment black */ if(Segment < (mSegments - 1)) { @@ -438,7 +464,7 @@ FX_STATUS WS2812BFX_SegmentIncreaseEnd(uint16_t Segment) } } - else // last Segment + else /* last Segment */ { if(Ws28b12b_Segments[Segment].IdStop < (WS2812B_LEDS - 1)) { @@ -451,8 +477,8 @@ FX_STATUS WS2812BFX_SegmentIncreaseEnd(uint16_t Segment) FX_STATUS WS2812BFX_SegmentDecreaseEnd(uint16_t Segment) { - if(Segment >= mSegments) return FX_ERROR; - WS2812BFX_SetAll(Segment, BLACK); // Set all 'old' segment black + ws2812fx_return_val_if_fail(Segment < mSegments, FX_ERROR); + WS2812BFX_SetAll(Segment, BLACK); /* Set all 'old' segment black */ if((Ws28b12b_Segments[Segment].IdStop - Ws28b12b_Segments[Segment].IdStart) > 0) { @@ -463,12 +489,12 @@ FX_STATUS WS2812BFX_SegmentDecreaseEnd(uint16_t Segment) FX_STATUS WS2812BFX_SetSegmentSize(uint16_t Segment, uint16_t Start, uint16_t Stop) { - if(Segment >= mSegments) return FX_ERROR; + ws2812fx_return_val_if_fail(Segment < mSegments, FX_ERROR); if(Start >= (WS2812B_LEDS - 1)) return FX_ERROR; if(Stop >= (WS2812B_LEDS - 1)) return FX_ERROR; if(Start > Stop) return FX_ERROR; - WS2812BFX_SetAll(Segment, BLACK); // Set all 'old' segment black + WS2812BFX_SetAll(Segment, BLACK); /* Set all 'old' segment black */ Ws28b12b_Segments[Segment].IdStart = Start; Ws28b12b_Segments[Segment].IdStop = Stop; @@ -477,7 +503,7 @@ FX_STATUS WS2812BFX_SetSegmentSize(uint16_t Segment, uint16_t Start, uint16_t St FX_STATUS WS2812BFX_GetSegmentSize(uint16_t Segment, uint16_t *Start, uint16_t *Stop) { - if(Segment >= mSegments) return FX_ERROR; + ws2812fx_return_val_if_fail(Segment < mSegments, FX_ERROR); *Start = Ws28b12b_Segments[Segment].IdStart; *Stop = Ws28b12b_Segments[Segment].IdStop; return FX_OK; @@ -485,7 +511,7 @@ FX_STATUS WS2812BFX_GetSegmentSize(uint16_t Segment, uint16_t *Start, uint16_t * FX_STATUS WS2812BFX_Start(uint16_t Segment) { - if(Segment >= mSegments) return FX_ERROR; + ws2812fx_return_val_if_fail(Segment < mSegments, FX_ERROR); Ws28b12b_Segments[Segment].CounterModeCall = 0; Ws28b12b_Segments[Segment].CounterModeStep = 0; Ws28b12b_Segments[Segment].ModeDelay = 0; @@ -507,17 +533,16 @@ uint8_t WS2812BFX_IsAnyRunning(void) FX_STATUS WS2812BFX_Stop(uint16_t Segment) { - if(Segment >= mSegments) return FX_ERROR; + ws2812fx_return_val_if_fail(Segment < mSegments, FX_ERROR); Ws28b12b_Segments[Segment].Running = 0; if(!WS2812BFX_IsAnyRunning()) mRunning = 0; return FX_OK; -// strip_off(); } FX_STATUS WS2812BFX_IsRunning(uint16_t Segment, uint8_t *Running) { - if(Segment >= mSegments) return FX_ERROR; + ws2812fx_return_val_if_fail(Segment < mSegments, FX_ERROR); *Running = Ws28b12b_Segments[Segment].Running; return FX_OK; } @@ -548,59 +573,60 @@ FX_STATUS WS2812BFX_GetColorRGB(uint8_t id, uint8_t *r, uint8_t *g, uint8_t *b) void WS2812BFX_RGBtoHSV(uint8_t r, uint8_t g, uint8_t b, uint16_t *h, uint8_t *s, uint8_t *v) { - uint16_t min, max, delta; - int16_t h_tmp = *h; - - min = r < g ? r : g; - min = min < b ? min : b; - - max = r > g ? r : g; - max = max > b ? max : b; - - *v = max; // v - delta = max - min; - if (delta < 1) - { - *s = 0; - *h = 0; // undefined, maybe nan? - return; - } - if( max > 0 ) - { // NOTE: if Max is == 0, this divide would cause a crash - *s = (((delta * 100) / max) * 255) / 100; // s - } - else - { - // if max is 0, then r = g = b = 0 - // s = 0, h is undefined - *s = 0; - *h = 0; // its now undefined - return; - } - - if( r == max ) - { - h_tmp = (( g - b )*100) / delta; // between yellow & magenta - // *100 to avoid fracts - } - else - { + uint16_t min, max, delta; + int16_t h_tmp = *h; + + min = r < g ? r : g; + min = min < b ? min : b; + + max = r > g ? r : g; + max = max > b ? max : b; + + *v = max; /* v */ + delta = max - min; + if (delta < 1) + { + *s = 0; + *h = 0; /* undefined, maybe nan? */ + return; + } + if( max > 0 ) + { /* NOTE: if Max is == 0, this divide would cause a crash */ + *s = (((delta * 100) / max) * 255) / 100; /* s */ + } + else + { + /* + * if max is 0, then r = g = b = 0 + * s = 0, h is undefined + */ + *s = 0; + *h = 0; /* its now undefined */ + return; + } + + if( r == max ) + { + h_tmp = (( g - b )*100) / delta; /* between yellow & magenta *100 to avoid fracts */ + } + else + { if( g == max ) { - h_tmp = 720 + (( b - r )*100) / delta; // between cyan & yellow + h_tmp = 720 + (( b - r )*100) / delta; /* between cyan & yellow */ } else { - h_tmp = 1440 + (( r - g )*100) / delta; // between magenta & cyan + h_tmp = 1440 + (( r - g )*100) / delta; /* between magenta & cyan */ } - } - h_tmp *= 60; // Degrees - h_tmp /= 100; // Back from fracts + } + h_tmp *= 60; /* Degrees */ + h_tmp /= 100; /* Back from fracts */ - if( h_tmp < 0.0 ) - h_tmp += 360; + if( h_tmp < 0.0 ) + h_tmp += 360; - *h = h_tmp; + *h = h_tmp; } void WS2812BFX_HSVtoRGB(uint16_t h, uint8_t s, uint8_t v, uint8_t *r, uint8_t *g, uint8_t *b) @@ -618,7 +644,7 @@ void WS2812BFX_HSVtoRGB(uint16_t h, uint8_t s, uint8_t v, uint8_t *r, uint8_t *g { if(h >= 360) h = 359; - Sector = h / 60; // Sector 0 to 5 + Sector = h / 60; /* hexcone HSV model -- 6 sectors */ Fracts = h % 60; p = (v * (255 - s)) / 256; q = (v * (255 - (s * Fracts)/60)) / 256; @@ -652,7 +678,8 @@ void WS2812BFX_HSVtoRGB(uint16_t h, uint8_t s, uint8_t v, uint8_t *r, uint8_t *g *g = (uint8_t)p; *b = v; break; - default: // case 5: + case 5: + default: *r = v; *g = (uint8_t)p; *b = (uint8_t)q; @@ -661,13 +688,13 @@ void WS2812BFX_HSVtoRGB(uint16_t h, uint8_t s, uint8_t v, uint8_t *r, uint8_t *g } } -// -// Set color with HSV model -// -// Hue 0-359 -// Saturation 0-255 -// Value 0-255 -// +/* + * Set color with HSV model + * + * Hue 0-359 + * Saturation 0-255 + * Value 0-255 + */ void WS2812BFX_SetColorHSV(uint8_t id, uint16_t h, uint8_t s, uint8_t v) { WS2812BFX_HSVtoRGB(h, s, v, &mColor_w[id].rgb.red, &mColor_w[id].rgb.green, &mColor_w[id].rgb.blue); @@ -682,27 +709,27 @@ void WS2812BFX_SetColor(uint8_t id, uint32_t c) FX_STATUS WS2812BFX_SetAll(uint16_t Segment, uint32_t c) { - if(Segment >= mSegments) return FX_ERROR; + ws2812fx_return_val_if_fail(Segment < mSegments, FX_ERROR); for(uint16_t i = 0; i < (Ws28b12b_Segments[Segment].IdStop - Ws28b12b_Segments[Segment].IdStart + 1); i++) { - WS2812B_SetDiodeColor(Ws28b12b_Segments[Segment].IdStart + i, c); + ws2812_set_led_color_val(Ws28b12b_Segments[Segment].IdStart + i, c); } return FX_OK; } FX_STATUS WS2812BFX_SetAllRGB(uint16_t Segment, uint8_t r, uint8_t g, uint8_t b) { - if(Segment >= mSegments) return FX_ERROR; + ws2812fx_return_val_if_fail(Segment < mSegments, FX_ERROR); for(uint16_t i = 0; i < SEGMENT_LENGTH; i++) { - WS2812B_SetDiodeRGB(Ws28b12b_Segments[Segment].IdStart + i, r, g, b); + ws2812_set_led_rgb(Ws28b12b_Segments[Segment].IdStart + i, r, g, b); } return FX_OK; } FX_STATUS WS2812BFX_SetSpeed(uint16_t Segment, uint16_t Speed) { - if(Segment >= mSegments) return FX_ERROR; + ws2812fx_return_val_if_fail(Segment < mSegments, FX_ERROR); if(Speed < SPEED_MIN) Speed = SPEED_MIN; if(Speed > SPEED_MAX) Speed = SPEED_MAX; @@ -712,7 +739,7 @@ FX_STATUS WS2812BFX_SetSpeed(uint16_t Segment, uint16_t Speed) FX_STATUS WS2812BFX_GetSpeed(uint16_t Segment, uint16_t *Speed) { - if(Segment >= mSegments) return FX_ERROR; + ws2812fx_return_val_if_fail(Segment < mSegments, FX_ERROR); *Speed = Ws28b12b_Segments[Segment].Speed; return FX_OK; } @@ -727,11 +754,9 @@ FX_STATUS WS2812BFX_DecreaseSpeed(uint16_t Segment, uint16_t Speed) return WS2812BFX_SetSpeed(Segment, Ws28b12b_Segments[mActualSegment].Speed - Speed); } -// -// -// COLOR EFECTS FUNCTIONS -// -// +/** + ** COLOR EFECTS FUNCTIONS + **/ /* * Turns everything off. @@ -740,9 +765,9 @@ void strip_off() { for(uint16_t i = 0; i < WS2812B_LEDS; i++) { - WS2812B_SetDiodeRGB(i, 0, 0, 0); + ws2812_set_led_rgb(i, 0, 0, 0); } - WS2812B_Refresh(); + ws2812_refresh(); } /* @@ -751,78 +776,80 @@ void strip_off() * Inspired by the Adafruit examples. */ 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); - } + 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); + } } /* * Returns a new, random wheel index with a minimum distance of 42 from pos. */ uint8_t get_random_wheel_index(uint8_t pos) { - uint8_t r = 0; - uint8_t x = 0; - uint8_t y = 0; - uint8_t d = 0; - - while(d < 42) { - r = rand()%256; - x = abs(pos - r); - y = 255 - x; - d = MIN(x, y); - } + uint8_t r = 0; + uint8_t x = 0; + uint8_t y = 0; + uint8_t d = 0; + + while(d < 42) { + r = rand()%256; + x = abs(pos - r); + y = 255 - x; + d = MIN(x, y); + } - return r; + return r; } /* * fade out function */ void fade_out() { - static const uint8_t rateMapH[] = {0, 1, 1, 1, 2, 3, 4, 6}; - static const uint8_t rateMapL[] = {0, 2, 3, 8, 8, 8, 8, 8}; - - uint8_t rate = FADE_RATE; - uint8_t rateH = rateMapH[rate]; - uint8_t rateL = rateMapL[rate]; - - uint32_t color = Ws28b12b_Segments[mActualSegment].ModeColor[1]; // target color - - int r2 = (color >> 16) & 0xff; - int g2 = (color >> 8) & 0xff; - int b2 = color & 0xff; - - for(uint16_t i=Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) { - - color = WS2812B_GetColor(i); - if(rate == 0) { // old fade-to-black algorithm - WS2812B_SetDiodeColor(i, (color >> 1) & 0x7F7F7F7F); - } else { // new fade-to-color algorithm - int r1 = (color >> 16) & 0xff; - int g1 = (color >> 8) & 0xff; - int b1 = color & 0xff; - - // calculate the color differences between the current and target colors - int rdelta = r2 - r1; - int gdelta = g2 - g1; - int bdelta = b2 - b1; - - // if the current and target colors are almost the same, jump right to the target color, - // otherwise calculate an intermediate color. (fixes rounding issues) - rdelta = abs(rdelta) < 3 ? rdelta : (rdelta >> rateH) + (rdelta >> rateL); - gdelta = abs(gdelta) < 3 ? gdelta : (gdelta >> rateH) + (gdelta >> rateL); - bdelta = abs(bdelta) < 3 ? bdelta : (bdelta >> rateH) + (bdelta >> rateL); - - WS2812B_SetDiodeRGB(i, r1 + rdelta, g1 + gdelta, b1 + bdelta); - } - } + static const uint8_t rateMapH[] = {0, 1, 1, 1, 2, 3, 4, 6}; + static const uint8_t rateMapL[] = {0, 2, 3, 8, 8, 8, 8, 8}; + + uint8_t rate = FADE_RATE; + uint8_t rateH = rateMapH[rate]; + uint8_t rateL = rateMapL[rate]; + + uint32_t color = Ws28b12b_Segments[mActualSegment].ModeColor[1]; /* target color */ + + int r2 = (color >> 16) & 0xff; + int g2 = (color >> 8) & 0xff; + int b2 = color & 0xff; + + for(uint16_t i=Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) { + + color = ws2812_get_color(i); + if(rate == 0) { /* old fade-to-black algorithm */ + ws2812_set_led_color_val(i, (color >> 1) & 0x7F7F7F7F); + } else { /* new fade-to-color algorithm */ + int r1 = (color >> 16) & 0xff; + int g1 = (color >> 8) & 0xff; + int b1 = color & 0xff; + + /* calculate the color differences between the current and target colors */ + int rdelta = r2 - r1; + int gdelta = g2 - g1; + int bdelta = b2 - b1; + + /* + * If the current and target colors are almost the same, jump right to the target color, + * otherwise calculate an intermediate color. (fixes rounding issues) + */ + rdelta = abs(rdelta) < 3 ? rdelta : (rdelta >> rateH) + (rdelta >> rateL); + gdelta = abs(gdelta) < 3 ? gdelta : (gdelta >> rateH) + (gdelta >> rateL); + bdelta = abs(bdelta) < 3 ? bdelta : (bdelta >> rateH) + (bdelta >> rateL); + + ws2812_set_led_rgb(i, r1 + rdelta, g1 + gdelta, b1 + bdelta); + } + } } /* @@ -830,25 +857,25 @@ void fade_out() { */ uint32_t color_blend(uint32_t color1, uint32_t color2, uint8_t blend) { - if(blend == 0) return color1; - if(blend == 255) return color2; + if(blend == 0) return color1; + if(blend == 255) return color2; - int w1 = (color1 >> 24) & 0xff; - int r1 = (color1 >> 16) & 0xff; - int g1 = (color1 >> 8) & 0xff; - int b1 = color1 & 0xff; + int w1 = (color1 >> 24) & 0xff; + int r1 = (color1 >> 16) & 0xff; + int g1 = (color1 >> 8) & 0xff; + int b1 = color1 & 0xff; - int w2 = (color2 >> 24) & 0xff; - int r2 = (color2 >> 16) & 0xff; - int g2 = (color2 >> 8) & 0xff; - int b2 = color2 & 0xff; + int w2 = (color2 >> 24) & 0xff; + int r2 = (color2 >> 16) & 0xff; + int g2 = (color2 >> 8) & 0xff; + int b2 = color2 & 0xff; - uint32_t w3 = ((w2 * blend) + (w1 * (255 - blend))) / 256; - uint32_t r3 = ((r2 * blend) + (r1 * (255 - blend))) / 256; - uint32_t g3 = ((g2 * blend) + (g1 * (255 - blend))) / 256; - uint32_t b3 = ((b2 * blend) + (b1 * (255 - blend))) / 256; + uint32_t w3 = ((w2 * blend) + (w1 * (255 - blend))) / 256; + uint32_t r3 = ((r2 * blend) + (r1 * (255 - blend))) / 256; + uint32_t g3 = ((g2 * blend) + (g1 * (255 - blend))) / 256; + uint32_t b3 = ((b2 * blend) + (b1 * (255 - blend))) / 256; - return ((w3 << 24) | (r3 << 16) | (g3 << 8) | (b3)); + return ((w3 << 24) | (r3 << 16) | (g3 << 8) | (b3)); } /* @@ -857,18 +884,16 @@ uint32_t color_blend(uint32_t color1, uint32_t color2, uint8_t blend) void mode_static(void) { - for(uint16_t i = Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) { - WS2812B_SetDiodeColorStruct(i, Ws28b12b_Segments[mActualSegment].ModeColor_w[0]); - } - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + for(uint16_t i = Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) { + ws2812_set_led_color(i, Ws28b12b_Segments[mActualSegment].ModeColor_w[0]); + } + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; } -// -// from: 0 - black to color, 1 - white to color -// +/* from: 0 - black to color, 1 - white to color */ void to_color(uint8_t from) { - // HSV Saturatioin modifing + /* HSV Saturatioin modifying */ uint16_t h; uint8_t s, v, r, g, b; @@ -927,9 +952,7 @@ void mode_black_to_color(void) to_color(0); } -// -// Blink helper function -// +/* Blink helper function */ void blink(uint32_t color1, uint32_t color2, uint8_t strobe) { uint32_t color = ((Ws28b12b_Segments[mActualSegment].CounterModeCall & 1) == 0) ? color1 : color2; @@ -971,14 +994,14 @@ void mode_breath(void) if(lum > 255) lum = 511 - lum; uint16_t delay; - if(lum == 15) delay = 970; // 970 pause before each breath - else if(lum <= 25) delay = 38; // 19 - else if(lum <= 50) delay = 36; // 18 - else if(lum <= 75) delay = 28; // 14 - else if(lum <= 100) delay = 20; // 10 - else if(lum <= 125) delay = 14; // 7 - else if(lum <= 150) delay = 11; // 5 - else delay = 10; // 4 + if(lum == 15) delay = 970; /* 970 pause before each breath */ + else if(lum <= 25) delay = 38; /* 19 */ + else if(lum <= 50) delay = 36; /* 18 */ + else if(lum <= 75) delay = 28; /* 14 */ + else if(lum <= 100) delay = 20; /* 10 */ + else if(lum <= 125) delay = 14; /* 7 */ + else if(lum <= 150) delay = 11; /* 5 */ + else delay = 10; /* 4 */ uint8_t r = Ws28b12b_Segments[mActualSegment].ModeColor_w[0].rgb.red * lum / 256; uint8_t g = Ws28b12b_Segments[mActualSegment].ModeColor_w[0].rgb.green * lum / 256; @@ -997,33 +1020,33 @@ void mode_breath(void) */ void color_wipe(uint32_t color1, uint32_t color2, uint8_t rev) { - if(Ws28b12b_Segments[mActualSegment].CounterModeStep < SEGMENT_LENGTH) - { - uint32_t led_offset = Ws28b12b_Segments[mActualSegment].CounterModeStep; - if(rev) - { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStop - led_offset, color1); - } - else - { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + led_offset, color1); - } - } + if(Ws28b12b_Segments[mActualSegment].CounterModeStep < SEGMENT_LENGTH) + { + uint32_t led_offset = Ws28b12b_Segments[mActualSegment].CounterModeStep; + if(rev) + { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStop - led_offset, color1); + } + else + { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + led_offset, color1); + } + } else { - uint32_t led_offset = Ws28b12b_Segments[mActualSegment].CounterModeStep - SEGMENT_LENGTH; - if(rev) - { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStop - led_offset, color2); - } - else - { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + led_offset, color2); - } + uint32_t led_offset = Ws28b12b_Segments[mActualSegment].CounterModeStep - SEGMENT_LENGTH; + if(rev) + { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStop - led_offset, color2); + } + else + { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + led_offset, color2); + } - } - Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) % (SEGMENT_LENGTH * 2); - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + } + Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) % (SEGMENT_LENGTH * 2); + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; } /* @@ -1053,12 +1076,12 @@ void mode_color_wipe_random(void) { if(Ws28b12b_Segments[mActualSegment].CounterModeStep % SEGMENT_LENGTH == 0) { - Ws28b12b_Segments[mActualSegment].AuxParam = get_random_wheel_index(Ws28b12b_Segments[mActualSegment].AuxParam); + Ws28b12b_Segments[mActualSegment].AuxParam = get_random_wheel_index(Ws28b12b_Segments[mActualSegment].AuxParam); } uint32_t color = color_wheel(Ws28b12b_Segments[mActualSegment].AuxParam); color_wipe(color, color, 0); - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; } /* @@ -1066,12 +1089,12 @@ void mode_color_wipe_random(void) */ void mode_color_sweep_random(void) { - if(Ws28b12b_Segments[mActualSegment].CounterModeStep % SEGMENT_LENGTH == 0) - { // aux_param will store our random color wheel index - Ws28b12b_Segments[mActualSegment].AuxParam = get_random_wheel_index(Ws28b12b_Segments[mActualSegment].AuxParam); - } - uint32_t color = color_wheel(Ws28b12b_Segments[mActualSegment].AuxParam); - color_wipe(color, color, 1); + if(Ws28b12b_Segments[mActualSegment].CounterModeStep % SEGMENT_LENGTH == 0) + { /* aux_param will store our random color wheel index */ + Ws28b12b_Segments[mActualSegment].AuxParam = get_random_wheel_index(Ws28b12b_Segments[mActualSegment].AuxParam); + } + uint32_t color = color_wheel(Ws28b12b_Segments[mActualSegment].AuxParam); + color_wipe(color, color, 1); } /* @@ -1080,9 +1103,9 @@ void mode_color_sweep_random(void) */ void mode_random_color(void) { - Ws28b12b_Segments[mActualSegment].AuxParam = get_random_wheel_index(Ws28b12b_Segments[mActualSegment].AuxParam); // aux_param will store our random color wheel index + Ws28b12b_Segments[mActualSegment].AuxParam = get_random_wheel_index(Ws28b12b_Segments[mActualSegment].AuxParam); /* aux_param will store our random color wheel index */ WS2812BFX_SetAll(mActualSegment, color_wheel(Ws28b12b_Segments[mActualSegment].AuxParam)); - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; } /* @@ -1095,12 +1118,12 @@ void mode_single_dynamic(void) { for(uint16_t i = Ws28b12b_Segments[mActualSegment].IdStop; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) { - WS2812B_SetDiodeColor(i, color_wheel(rand()%256)); + ws2812_set_led_color_val(i, color_wheel(rand()%256)); } } - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + rand() % SEGMENT_LENGTH, color_wheel(rand()%256)); - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + rand() % SEGMENT_LENGTH, color_wheel(rand()%256)); + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; } @@ -1112,9 +1135,9 @@ void mode_multi_dynamic(void) { for(uint16_t i = Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) { - WS2812B_SetDiodeColor(i, color_wheel(rand()%256)); + ws2812_set_led_color_val(i, color_wheel(rand()%256)); } - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; } /* @@ -1122,14 +1145,14 @@ void mode_multi_dynamic(void) */ void mode_rainbow(void) { - uint32_t color = color_wheel(Ws28b12b_Segments[mActualSegment].CounterModeStep); - for(uint16_t i = Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) - { - WS2812B_SetDiodeColor(i, color); - } + uint32_t color = color_wheel(Ws28b12b_Segments[mActualSegment].CounterModeStep); + for(uint16_t i = Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) + { + ws2812_set_led_color_val(i, color); + } - Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) & 0xFF; - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) & 0xFF; + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; } @@ -1138,14 +1161,14 @@ void mode_rainbow(void) */ void mode_rainbow_cycle(void) { - for(uint16_t i=0; i < SEGMENT_LENGTH; i++) - { - uint32_t color = color_wheel(((i * 256 / SEGMENT_LENGTH) + Ws28b12b_Segments[mActualSegment].CounterModeStep) & 0xFF); - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + i, color); - } + for(uint16_t i=0; i < SEGMENT_LENGTH; i++) + { + uint32_t color = color_wheel(((i * 256 / SEGMENT_LENGTH) + Ws28b12b_Segments[mActualSegment].CounterModeStep) & 0xFF); + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + i, color); + } - Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) & 0xFF; - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) & 0xFF; + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; } @@ -1153,18 +1176,18 @@ void mode_rainbow_cycle(void) * Fades the LEDs between two colors */ void mode_fade(void) { - int lum = Ws28b12b_Segments[mActualSegment].CounterModeStep; - if(lum > 255) lum = 511 - lum; // lum = 0 -> 255 -> 0 + int lum = Ws28b12b_Segments[mActualSegment].CounterModeStep; + if(lum > 255) lum = 511 - lum; /* lum = 0 -> 255 -> 0 */ - uint32_t color = color_blend(Ws28b12b_Segments[mActualSegment].ModeColor[0], Ws28b12b_Segments[mActualSegment].ModeColor[1], lum); + uint32_t color = color_blend(Ws28b12b_Segments[mActualSegment].ModeColor[0], Ws28b12b_Segments[mActualSegment].ModeColor[1], lum); - for(uint16_t i=Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) { - WS2812B_SetDiodeColor(i, color); - } + for(uint16_t i=Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) { + ws2812_set_led_color_val(i, color); + } - Ws28b12b_Segments[mActualSegment].CounterModeStep += 4; - if(Ws28b12b_Segments[mActualSegment].CounterModeStep > 511) Ws28b12b_Segments[mActualSegment].CounterModeStep = 0; - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + Ws28b12b_Segments[mActualSegment].CounterModeStep += 4; + if(Ws28b12b_Segments[mActualSegment].CounterModeStep > 511) Ws28b12b_Segments[mActualSegment].CounterModeStep = 0; + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; } @@ -1172,26 +1195,26 @@ void mode_fade(void) { * Runs a single pixel back and forth. */ void mode_scan(void) { - if(Ws28b12b_Segments[mActualSegment].CounterModeStep > (SEGMENT_LENGTH * 2) - 3) { - Ws28b12b_Segments[mActualSegment].CounterModeStep = 0; - } + if(Ws28b12b_Segments[mActualSegment].CounterModeStep > (SEGMENT_LENGTH * 2) - 3) { + Ws28b12b_Segments[mActualSegment].CounterModeStep = 0; + } - for(uint16_t i = Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) { - WS2812B_SetDiodeColor(i, Ws28b12b_Segments[mActualSegment].ModeColor[1]); - } + for(uint16_t i = Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) { + ws2812_set_led_color_val(i, Ws28b12b_Segments[mActualSegment].ModeColor[1]); + } - int led_offset = Ws28b12b_Segments[mActualSegment].CounterModeStep - (SEGMENT_LENGTH - 1); - led_offset = abs(led_offset); + int led_offset = Ws28b12b_Segments[mActualSegment].CounterModeStep - (SEGMENT_LENGTH - 1); + led_offset = abs(led_offset); - if(IS_REVERSE) { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStop - led_offset, Ws28b12b_Segments[mActualSegment].ModeColor[0]); - } else { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + led_offset, Ws28b12b_Segments[mActualSegment].ModeColor[0]); - } + if(IS_REVERSE) { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStop - led_offset, Ws28b12b_Segments[mActualSegment].ModeColor[0]); + } else { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + led_offset, Ws28b12b_Segments[mActualSegment].ModeColor[0]); + } - Ws28b12b_Segments[mActualSegment].CounterModeStep++; - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + Ws28b12b_Segments[mActualSegment].CounterModeStep++; + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; } @@ -1199,24 +1222,24 @@ void mode_scan(void) { * Runs two pixel back and forth in opposite directions. */ void mode_dual_scan(void) { - if(Ws28b12b_Segments[mActualSegment].CounterModeStep > (SEGMENT_LENGTH * 2) - 3) - { - Ws28b12b_Segments[mActualSegment].CounterModeStep = 0; - } + if(Ws28b12b_Segments[mActualSegment].CounterModeStep > (SEGMENT_LENGTH * 2) - 3) + { + Ws28b12b_Segments[mActualSegment].CounterModeStep = 0; + } - for(uint16_t i=Ws28b12b_Segments[mActualSegment].IdStart; i > 16) & 0xFF); - uint8_t g = ((Ws28b12b_Segments[mActualSegment].ModeColor[0] >> 8) & 0xFF); - uint8_t b = (Ws28b12b_Segments[mActualSegment].ModeColor[0] & 0xFF); - - uint8_t sineIncr = MAX(1, (256 / WS2812B_LEDS)); - for(uint16_t i=0; i < SEGMENT_LENGTH; i++) { - int lum = (int)sine8(((i + Ws28b12b_Segments[mActualSegment].CounterModeStep) * sineIncr)); - if(IS_REVERSE) { - WS2812B_SetDiodeRGB(Ws28b12b_Segments[mActualSegment].IdStart + i, (r * lum) / 256, (g * lum) / 256, (b * lum) / 256); - } else { - WS2812B_SetDiodeRGB(Ws28b12b_Segments[mActualSegment].IdStop - i, (r * lum) / 256, (g * lum) / 256, (b * lum) / 256); - } - } - Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) % 256; - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + uint8_t r = ((Ws28b12b_Segments[mActualSegment].ModeColor[0] >> 16) & 0xFF); + uint8_t g = ((Ws28b12b_Segments[mActualSegment].ModeColor[0] >> 8) & 0xFF); + uint8_t b = (Ws28b12b_Segments[mActualSegment].ModeColor[0] & 0xFF); + + uint8_t sineIncr = MAX(1, (256 / WS2812B_LEDS)); + for(uint16_t i=0; i < SEGMENT_LENGTH; i++) { + int lum = (int)sine8(((i + Ws28b12b_Segments[mActualSegment].CounterModeStep) * sineIncr)); + if(IS_REVERSE) { + ws2812_set_led_rgb(Ws28b12b_Segments[mActualSegment].IdStart + i, (r * lum) / 256, (g * lum) / 256, (b * lum) / 256); + } else { + ws2812_set_led_rgb(Ws28b12b_Segments[mActualSegment].IdStop - i, (r * lum) / 256, (g * lum) / 256, (b * lum) / 256); + } + } + Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) % 256; + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; } @@ -1293,21 +1316,21 @@ void mode_running_lights(void) { */ void twinkle(uint32_t color1, uint32_t color2) { - if(Ws28b12b_Segments[mActualSegment].CounterModeStep == 0) - { - for(uint16_t i=Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) - { - WS2812B_SetDiodeColor(i, color2); - } - uint16_t min_leds = MAX(1, WS2812B_LEDS / 5); // make sure, at least one LED is on - uint16_t max_leds = MAX(1, WS2812B_LEDS / 2); // make sure, at least one LED is on - Ws28b12b_Segments[mActualSegment].CounterModeStep = rand() % (max_leds + 1 - min_leds) + min_leds; - } + if(Ws28b12b_Segments[mActualSegment].CounterModeStep == 0) + { + for(uint16_t i=Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) + { + ws2812_set_led_color_val(i, color2); + } + uint16_t min_leds = MAX(1, WS2812B_LEDS / 5); /* make sure, at least one LED is on */ + uint16_t max_leds = MAX(1, WS2812B_LEDS / 2); /* make sure, at least one LED is on */ + Ws28b12b_Segments[mActualSegment].CounterModeStep = rand() % (max_leds + 1 - min_leds) + min_leds; + } - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + rand() % SEGMENT_LENGTH, color1); + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + rand() % SEGMENT_LENGTH, color1); - Ws28b12b_Segments[mActualSegment].CounterModeStep--; - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + Ws28b12b_Segments[mActualSegment].CounterModeStep--; + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; } /* @@ -1316,7 +1339,7 @@ void twinkle(uint32_t color1, uint32_t color2) */ void mode_twinkle(void) { - return twinkle(Ws28b12b_Segments[mActualSegment].ModeColor[0], Ws28b12b_Segments[mActualSegment].ModeColor[1]); + return twinkle(Ws28b12b_Segments[mActualSegment].ModeColor[0], Ws28b12b_Segments[mActualSegment].ModeColor[1]); } /* @@ -1325,7 +1348,7 @@ void mode_twinkle(void) */ void mode_twinkle_random(void) { - return twinkle(color_wheel(rand() % 256), Ws28b12b_Segments[mActualSegment].ModeColor[1]); + return twinkle(color_wheel(rand() % 256), Ws28b12b_Segments[mActualSegment].ModeColor[1]); } /* @@ -1333,13 +1356,13 @@ void mode_twinkle_random(void) */ void twinkle_fade(uint32_t color) { - fade_out(); + fade_out(); - if((rand() %3) == 0) - { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + rand() % SEGMENT_LENGTH, color); - } - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + if((rand() %3) == 0) + { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + rand() % SEGMENT_LENGTH, color); + } + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; } @@ -1348,7 +1371,7 @@ void twinkle_fade(uint32_t color) */ void mode_twinkle_fade(void) { - twinkle_fade(Ws28b12b_Segments[mActualSegment].ModeColor[0]); + twinkle_fade(Ws28b12b_Segments[mActualSegment].ModeColor[0]); } @@ -1357,7 +1380,7 @@ void mode_twinkle_fade(void) */ void mode_twinkle_fade_random(void) { - twinkle_fade(color_wheel(rand() % 256)); + twinkle_fade(color_wheel(rand() % 256)); } /* @@ -1366,10 +1389,10 @@ void mode_twinkle_fade_random(void) */ void mode_sparkle(void) { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + Ws28b12b_Segments[mActualSegment].AuxParam16b, Ws28b12b_Segments[mActualSegment].ModeColor[1]); - Ws28b12b_Segments[mActualSegment].AuxParam16b = rand() % SEGMENT_LENGTH; // aux_param3 stores the random led index - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + Ws28b12b_Segments[mActualSegment].AuxParam16b, Ws28b12b_Segments[mActualSegment].ModeColor[0]); - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + Ws28b12b_Segments[mActualSegment].AuxParam16b, Ws28b12b_Segments[mActualSegment].ModeColor[1]); + Ws28b12b_Segments[mActualSegment].AuxParam16b = rand() % SEGMENT_LENGTH; /* aux_param3 stores the random led index */ + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + Ws28b12b_Segments[mActualSegment].AuxParam16b, Ws28b12b_Segments[mActualSegment].ModeColor[0]); + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; } @@ -1379,23 +1402,23 @@ void mode_sparkle(void) */ void mode_flash_sparkle(void) { - if(Ws28b12b_Segments[mActualSegment].CounterModeCall == 0) - { - for(uint16_t i=Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) - { - WS2812B_SetDiodeColor(i, Ws28b12b_Segments[mActualSegment].ModeColor[0]); - } - } + if(Ws28b12b_Segments[mActualSegment].CounterModeCall == 0) + { + for(uint16_t i=Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) + { + ws2812_set_led_color_val(i, Ws28b12b_Segments[mActualSegment].ModeColor[0]); + } + } - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + Ws28b12b_Segments[mActualSegment].AuxParam16b, Ws28b12b_Segments[mActualSegment].ModeColor[0]); + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + Ws28b12b_Segments[mActualSegment].AuxParam16b, Ws28b12b_Segments[mActualSegment].ModeColor[0]); - if(rand() % 5 == 0) - { - Ws28b12b_Segments[mActualSegment].AuxParam16b = rand() % SEGMENT_LENGTH; // aux_param3 stores the random led index - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + Ws28b12b_Segments[mActualSegment].AuxParam16b, WHITE); - Ws28b12b_Segments[mActualSegment].ModeDelay = 20; - } - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + if(rand() % 5 == 0) + { + Ws28b12b_Segments[mActualSegment].AuxParam16b = rand() % SEGMENT_LENGTH; /* aux_param3 stores the random led index */ + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + Ws28b12b_Segments[mActualSegment].AuxParam16b, WHITE); + Ws28b12b_Segments[mActualSegment].ModeDelay = 20; + } + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; } @@ -1405,20 +1428,20 @@ void mode_flash_sparkle(void) */ void mode_hyper_sparkle(void) { - for(uint16_t i=Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) - { - WS2812B_SetDiodeColor(i, Ws28b12b_Segments[mActualSegment].ModeColor[0]); - } + for(uint16_t i=Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) + { + ws2812_set_led_color_val(i, Ws28b12b_Segments[mActualSegment].ModeColor[0]); + } - if(rand() % 5 < 2) - { - for(uint16_t i=0; i < MAX(1, SEGMENT_LENGTH/3); i++) - { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + rand() % SEGMENT_LENGTH, WHITE); - } - Ws28b12b_Segments[mActualSegment].ModeDelay = 20; - } - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + if(rand() % 5 < 2) + { + for(uint16_t i=0; i < MAX(1, SEGMENT_LENGTH/3); i++) + { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + rand() % SEGMENT_LENGTH, WHITE); + } + Ws28b12b_Segments[mActualSegment].ModeDelay = 20; + } + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; } /* @@ -1426,30 +1449,30 @@ void mode_hyper_sparkle(void) */ void mode_multi_strobe(void) { - for(uint16_t i=Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) - { - WS2812B_SetDiodeColor(i, BLACK); - } - - uint16_t delay = 200 + ((9 - (Ws28b12b_Segments[mActualSegment].Speed % 10)) * 100); - uint16_t count = 2 * ((Ws28b12b_Segments[mActualSegment].Speed / 100) + 1); - if(Ws28b12b_Segments[mActualSegment].CounterModeStep < count) - { - if((Ws28b12b_Segments[mActualSegment].CounterModeStep & 1) == 0) - { - for(uint16_t i=Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) - { - WS2812B_SetDiodeColor(i, Ws28b12b_Segments[mActualSegment].ModeColor[0]); - } - delay = 20; - } - else - { - delay = 50; - } - } - Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) % (count + 1); - Ws28b12b_Segments[mActualSegment].ModeDelay = delay; + for(uint16_t i=Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) + { + ws2812_set_led_color_val(i, BLACK); + } + + uint16_t delay = 200 + ((9 - (Ws28b12b_Segments[mActualSegment].Speed % 10)) * 100); + uint16_t count = 2 * ((Ws28b12b_Segments[mActualSegment].Speed / 100) + 1); + if(Ws28b12b_Segments[mActualSegment].CounterModeStep < count) + { + if((Ws28b12b_Segments[mActualSegment].CounterModeStep & 1) == 0) + { + for(uint16_t i=Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) + { + ws2812_set_led_color_val(i, Ws28b12b_Segments[mActualSegment].ModeColor[0]); + } + delay = 20; + } + else + { + delay = 50; + } + } + Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) % (count + 1); + Ws28b12b_Segments[mActualSegment].ModeDelay = delay; } /* @@ -1459,24 +1482,24 @@ void mode_multi_strobe(void) */ void chase(uint32_t color1, uint32_t color2, uint32_t color3) { - uint16_t a = Ws28b12b_Segments[mActualSegment].CounterModeStep; - uint16_t b = (a + 1) % SEGMENT_LENGTH; - uint16_t c = (b + 1) % SEGMENT_LENGTH; - if(IS_REVERSE) { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStop - a, color1); - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStop - b, color2); - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStop - c, color3); - } else { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + a, color1); - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + b, color2); - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + c, color3); - } + uint16_t a = Ws28b12b_Segments[mActualSegment].CounterModeStep; + uint16_t b = (a + 1) % SEGMENT_LENGTH; + uint16_t c = (b + 1) % SEGMENT_LENGTH; + if(IS_REVERSE) { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStop - a, color1); + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStop - b, color2); + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStop - c, color3); + } else { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + a, color1); + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + b, color2); + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + c, color3); + } - if(b == 0) Ws28b12b_Segments[mActualSegment].Cycle = 1; - else Ws28b12b_Segments[mActualSegment].Cycle = 0; + if(b == 0) Ws28b12b_Segments[mActualSegment].Cycle = 1; + else Ws28b12b_Segments[mActualSegment].Cycle = 0; - Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) % WS2812B_LEDS; - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) % WS2812B_LEDS; + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; } @@ -1485,7 +1508,7 @@ void chase(uint32_t color1, uint32_t color2, uint32_t color3) */ void mode_bicolor_chase(void) { - return chase(Ws28b12b_Segments[mActualSegment].ModeColor[0], Ws28b12b_Segments[mActualSegment].ModeColor[1], Ws28b12b_Segments[mActualSegment].ModeColor[2]); + return chase(Ws28b12b_Segments[mActualSegment].ModeColor[0], Ws28b12b_Segments[mActualSegment].ModeColor[1], Ws28b12b_Segments[mActualSegment].ModeColor[2]); } @@ -1494,7 +1517,7 @@ void mode_bicolor_chase(void) */ void mode_chase_color(void) { - return chase(Ws28b12b_Segments[mActualSegment].ModeColor[0], WHITE, WHITE); + return chase(Ws28b12b_Segments[mActualSegment].ModeColor[0], WHITE, WHITE); } @@ -1503,7 +1526,7 @@ void mode_chase_color(void) */ void mode_chase_blackout(void) { - return chase(Ws28b12b_Segments[mActualSegment].ModeColor[0], BLACK, BLACK); + return chase(Ws28b12b_Segments[mActualSegment].ModeColor[0], BLACK, BLACK); } @@ -1512,7 +1535,7 @@ void mode_chase_blackout(void) */ void mode_chase_white(void) { - return chase(WHITE, Ws28b12b_Segments[mActualSegment].ModeColor[0], Ws28b12b_Segments[mActualSegment].ModeColor[0]); + return chase(WHITE, Ws28b12b_Segments[mActualSegment].ModeColor[0], Ws28b12b_Segments[mActualSegment].ModeColor[0]); } @@ -1521,11 +1544,11 @@ void mode_chase_white(void) */ void mode_chase_random(void) { - if(Ws28b12b_Segments[mActualSegment].CounterModeStep == 0) - { - Ws28b12b_Segments[mActualSegment].AuxParam = get_random_wheel_index(Ws28b12b_Segments[mActualSegment].AuxParam); - } - return chase(color_wheel(Ws28b12b_Segments[mActualSegment].AuxParam), WHITE, WHITE); + if(Ws28b12b_Segments[mActualSegment].CounterModeStep == 0) + { + Ws28b12b_Segments[mActualSegment].AuxParam = get_random_wheel_index(Ws28b12b_Segments[mActualSegment].AuxParam); + } + return chase(color_wheel(Ws28b12b_Segments[mActualSegment].AuxParam), WHITE, WHITE); } @@ -1534,12 +1557,12 @@ void mode_chase_random(void) */ void mode_chase_rainbow_white(void) { - uint16_t n = Ws28b12b_Segments[mActualSegment].CounterModeStep; - uint16_t m = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) % WS2812B_LEDS; - uint32_t color2 = color_wheel(((n * 256 / SEGMENT_LENGTH) + (Ws28b12b_Segments[mActualSegment].CounterModeCall & 0xFF)) & 0xFF); - uint32_t color3 = color_wheel(((m * 256 / SEGMENT_LENGTH) + (Ws28b12b_Segments[mActualSegment].CounterModeCall & 0xFF)) & 0xFF); + uint16_t n = Ws28b12b_Segments[mActualSegment].CounterModeStep; + uint16_t m = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) % WS2812B_LEDS; + uint32_t color2 = color_wheel(((n * 256 / SEGMENT_LENGTH) + (Ws28b12b_Segments[mActualSegment].CounterModeCall & 0xFF)) & 0xFF); + uint32_t color3 = color_wheel(((m * 256 / SEGMENT_LENGTH) + (Ws28b12b_Segments[mActualSegment].CounterModeCall & 0xFF)) & 0xFF); - return chase(WHITE, color2, color3); + return chase(WHITE, color2, color3); } @@ -1548,11 +1571,11 @@ void mode_chase_rainbow_white(void) */ void mode_chase_rainbow(void) { - uint8_t color_sep = 256 / SEGMENT_LENGTH; - uint8_t color_index = Ws28b12b_Segments[mActualSegment].CounterModeCall & 0xFF; - uint32_t color = color_wheel(((Ws28b12b_Segments[mActualSegment].CounterModeStep * color_sep) + color_index) & 0xFF); + uint8_t color_sep = 256 / SEGMENT_LENGTH; + uint8_t color_index = Ws28b12b_Segments[mActualSegment].CounterModeCall & 0xFF; + uint32_t color = color_wheel(((Ws28b12b_Segments[mActualSegment].CounterModeStep * color_sep) + color_index) & 0xFF); - return chase(color, WHITE, WHITE); + return chase(color, WHITE, WHITE); } @@ -1561,11 +1584,11 @@ void mode_chase_rainbow(void) */ void mode_chase_blackout_rainbow(void) { - uint8_t color_sep = 256 / SEGMENT_LENGTH; - uint8_t color_index = Ws28b12b_Segments[mActualSegment].CounterModeCall & 0xFF; - uint32_t color = color_wheel(((Ws28b12b_Segments[mActualSegment].CounterModeStep * color_sep) + color_index) & 0xFF); + uint8_t color_sep = 256 / SEGMENT_LENGTH; + uint8_t color_index = Ws28b12b_Segments[mActualSegment].CounterModeCall & 0xFF; + uint32_t color = color_wheel(((Ws28b12b_Segments[mActualSegment].CounterModeStep * color_sep) + color_index) & 0xFF); - return chase(color, 0, 0); + return chase(color, 0, 0); } /* @@ -1573,43 +1596,43 @@ void mode_chase_blackout_rainbow(void) */ void mode_chase_flash(void) { - const static uint8_t flash_count = 4; - uint8_t flash_step = Ws28b12b_Segments[mActualSegment].CounterModeCall % ((flash_count * 2) + 1); - - for(uint16_t i=Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) - { - WS2812B_SetDiodeColor(i, Ws28b12b_Segments[mActualSegment].ModeColor[0]); - } - - uint16_t delay = Ws28b12b_Segments[mActualSegment].Speed; - if(flash_step < (flash_count * 2)) - { - if(flash_step % 2 == 0) - { - uint16_t n = Ws28b12b_Segments[mActualSegment].CounterModeStep; - uint16_t m = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) % SEGMENT_LENGTH; - if(IS_REVERSE) - { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStop - n, WHITE); - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStop - m, WHITE); - } - else - { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + n, WHITE); - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + m, WHITE); - } - delay = 20; - } - else - { - delay = 30; - } - } - else - { - Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) % SEGMENT_LENGTH; - } - Ws28b12b_Segments[mActualSegment].ModeDelay = delay; + const static uint8_t flash_count = 4; + uint8_t flash_step = Ws28b12b_Segments[mActualSegment].CounterModeCall % ((flash_count * 2) + 1); + + for(uint16_t i=Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) + { + ws2812_set_led_color_val(i, Ws28b12b_Segments[mActualSegment].ModeColor[0]); + } + + uint16_t delay = Ws28b12b_Segments[mActualSegment].Speed; + if(flash_step < (flash_count * 2)) + { + if(flash_step % 2 == 0) + { + uint16_t n = Ws28b12b_Segments[mActualSegment].CounterModeStep; + uint16_t m = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) % SEGMENT_LENGTH; + if(IS_REVERSE) + { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStop - n, WHITE); + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStop - m, WHITE); + } + else + { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + n, WHITE); + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + m, WHITE); + } + delay = 20; + } + else + { + delay = 30; + } + } + else + { + Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) % SEGMENT_LENGTH; + } + Ws28b12b_Segments[mActualSegment].ModeDelay = delay; } @@ -1618,42 +1641,42 @@ void mode_chase_flash(void) */ void mode_chase_flash_random(void) { - const static uint8_t flash_count = 4; - uint8_t flash_step = Ws28b12b_Segments[mActualSegment].CounterModeCall % ((flash_count * 2) + 1); - - for(uint16_t i=0; i < Ws28b12b_Segments[mActualSegment].CounterModeStep; i++) - { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + i, color_wheel(Ws28b12b_Segments[mActualSegment].AuxParam)); - } - - uint16_t delay = Ws28b12b_Segments[mActualSegment].Speed; - if(flash_step < (flash_count * 2)) - { - uint16_t n = Ws28b12b_Segments[mActualSegment].CounterModeStep; - uint16_t m = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) % SEGMENT_LENGTH; - if(flash_step % 2 == 0) - { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + n, WHITE); - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + m, WHITE); - delay = 20; - } - else - { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + n, color_wheel(Ws28b12b_Segments[mActualSegment].AuxParam)); - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + m, BLACK); - delay = 30; - } - } - else - { - Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) % SEGMENT_LENGTH; - - if(Ws28b12b_Segments[mActualSegment].CounterModeStep == 0) - { - Ws28b12b_Segments[mActualSegment].AuxParam = get_random_wheel_index(Ws28b12b_Segments[mActualSegment].AuxParam); - } - } - Ws28b12b_Segments[mActualSegment].ModeDelay = delay; + const static uint8_t flash_count = 4; + uint8_t flash_step = Ws28b12b_Segments[mActualSegment].CounterModeCall % ((flash_count * 2) + 1); + + for(uint16_t i=0; i < Ws28b12b_Segments[mActualSegment].CounterModeStep; i++) + { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + i, color_wheel(Ws28b12b_Segments[mActualSegment].AuxParam)); + } + + uint16_t delay = Ws28b12b_Segments[mActualSegment].Speed; + if(flash_step < (flash_count * 2)) + { + uint16_t n = Ws28b12b_Segments[mActualSegment].CounterModeStep; + uint16_t m = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) % SEGMENT_LENGTH; + if(flash_step % 2 == 0) + { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + n, WHITE); + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + m, WHITE); + delay = 20; + } + else + { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + n, color_wheel(Ws28b12b_Segments[mActualSegment].AuxParam)); + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + m, BLACK); + delay = 30; + } + } + else + { + Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) % SEGMENT_LENGTH; + + if(Ws28b12b_Segments[mActualSegment].CounterModeStep == 0) + { + Ws28b12b_Segments[mActualSegment].AuxParam = get_random_wheel_index(Ws28b12b_Segments[mActualSegment].AuxParam); + } + } + Ws28b12b_Segments[mActualSegment].ModeDelay = delay; } @@ -1662,26 +1685,26 @@ void mode_chase_flash_random(void) */ void running(uint32_t color1, uint32_t color2) { - for(uint16_t i=0; i < SEGMENT_LENGTH; i++) - { - if((i + Ws28b12b_Segments[mActualSegment].CounterModeStep) % 4 < 2) - { - if(IS_REVERSE) { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + i, color1); - } else { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStop - i, color1); - } - } else { - if(IS_REVERSE) { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + i, color1); - } else { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStop - i, color2); - } - } - } - - Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) & 0x3; - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + for(uint16_t i=0; i < SEGMENT_LENGTH; i++) + { + if((i + Ws28b12b_Segments[mActualSegment].CounterModeStep) % 4 < 2) + { + if(IS_REVERSE) { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + i, color1); + } else { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStop - i, color1); + } + } else { + if(IS_REVERSE) { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + i, color1); + } else { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStop - i, color2); + } + } + } + + Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) & 0x3; + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; } /* @@ -1689,7 +1712,7 @@ void running(uint32_t color1, uint32_t color2) */ void mode_running_color(void) { - return running(Ws28b12b_Segments[mActualSegment].ModeColor[0], WHITE); + return running(Ws28b12b_Segments[mActualSegment].ModeColor[0], WHITE); } @@ -1698,7 +1721,7 @@ void mode_running_color(void) */ void mode_running_red_blue(void) { - return running(RED, BLUE); + return running(RED, BLUE); } @@ -1707,7 +1730,7 @@ void mode_running_red_blue(void) */ void mode_merry_christmas(void) { - return running(RED, GREEN); + return running(RED, GREEN); } /* @@ -1715,33 +1738,33 @@ void mode_merry_christmas(void) */ void mode_halloween(void) { - return running(PURPLE, ORANGE); + return running(PURPLE, ORANGE); } /* * Random colored pixels running. */ void mode_running_random(void) { - for(uint16_t i=SEGMENT_LENGTH-1; i > 0; i--) { - if(IS_REVERSE) { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStop - i, WS2812B_GetColor(Ws28b12b_Segments[mActualSegment].IdStop - i + 1)); - } else { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + i, WS2812B_GetColor(Ws28b12b_Segments[mActualSegment].IdStart + i - 1)); - } - } + for(uint16_t i=SEGMENT_LENGTH-1; i > 0; i--) { + if(IS_REVERSE) { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStop - i, ws2812_get_color(Ws28b12b_Segments[mActualSegment].IdStop - i + 1)); + } else { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + i, ws2812_get_color(Ws28b12b_Segments[mActualSegment].IdStart + i - 1)); + } + } - if(Ws28b12b_Segments[mActualSegment].CounterModeStep == 0) - { - Ws28b12b_Segments[mActualSegment].AuxParam = get_random_wheel_index(Ws28b12b_Segments[mActualSegment].AuxParam); - if(IS_REVERSE) { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStop, color_wheel(Ws28b12b_Segments[mActualSegment].AuxParam)); - } else { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart, color_wheel(Ws28b12b_Segments[mActualSegment].AuxParam)); - } - } + if(Ws28b12b_Segments[mActualSegment].CounterModeStep == 0) + { + Ws28b12b_Segments[mActualSegment].AuxParam = get_random_wheel_index(Ws28b12b_Segments[mActualSegment].AuxParam); + if(IS_REVERSE) { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStop, color_wheel(Ws28b12b_Segments[mActualSegment].AuxParam)); + } else { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart, color_wheel(Ws28b12b_Segments[mActualSegment].AuxParam)); + } + } - Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep == 0) ? 1 : 0; - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep == 0) ? 1 : 0; + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; } @@ -1749,30 +1772,30 @@ void mode_running_random(void) { * K.I.T.T. */ void mode_larson_scanner(void) { - fade_out(); + fade_out(); - if(Ws28b12b_Segments[mActualSegment].CounterModeStep < SEGMENT_LENGTH) - { - if(IS_REVERSE) { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStop - Ws28b12b_Segments[mActualSegment].CounterModeStep, Ws28b12b_Segments[mActualSegment].ModeColor[0]); - } else { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + Ws28b12b_Segments[mActualSegment].CounterModeStep, Ws28b12b_Segments[mActualSegment].ModeColor[0]); - } - } - else - { - if(IS_REVERSE) { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStop - ((SEGMENT_LENGTH * 2) - Ws28b12b_Segments[mActualSegment].CounterModeStep) + 2, Ws28b12b_Segments[mActualSegment].ModeColor[0]); - } else { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + ((SEGMENT_LENGTH * 2) - Ws28b12b_Segments[mActualSegment].CounterModeStep) - 2, Ws28b12b_Segments[mActualSegment].ModeColor[0]); - } - } + if(Ws28b12b_Segments[mActualSegment].CounterModeStep < SEGMENT_LENGTH) + { + if(IS_REVERSE) { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStop - Ws28b12b_Segments[mActualSegment].CounterModeStep, Ws28b12b_Segments[mActualSegment].ModeColor[0]); + } else { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + Ws28b12b_Segments[mActualSegment].CounterModeStep, Ws28b12b_Segments[mActualSegment].ModeColor[0]); + } + } + else + { + if(IS_REVERSE) { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStop - ((SEGMENT_LENGTH * 2) - Ws28b12b_Segments[mActualSegment].CounterModeStep) + 2, Ws28b12b_Segments[mActualSegment].ModeColor[0]); + } else { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + ((SEGMENT_LENGTH * 2) - Ws28b12b_Segments[mActualSegment].CounterModeStep) - 2, Ws28b12b_Segments[mActualSegment].ModeColor[0]); + } + } - if(Ws28b12b_Segments[mActualSegment].CounterModeStep % SEGMENT_LENGTH == 0) Ws28b12b_Segments[mActualSegment].Cycle = 1; - else Ws28b12b_Segments[mActualSegment].Cycle = 1; + if(Ws28b12b_Segments[mActualSegment].CounterModeStep % SEGMENT_LENGTH == 0) Ws28b12b_Segments[mActualSegment].Cycle = 1; + else Ws28b12b_Segments[mActualSegment].Cycle = 1; - Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) % ((SEGMENT_LENGTH * 2) - 2); - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) % ((SEGMENT_LENGTH * 2) - 2); + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; } @@ -1780,16 +1803,16 @@ void mode_larson_scanner(void) { * Firing comets from one end. */ void mode_comet(void) { - fade_out(); + fade_out(); - if(IS_REVERSE) { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStop - Ws28b12b_Segments[mActualSegment].CounterModeStep, Ws28b12b_Segments[mActualSegment].ModeColor[0]); - } else { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + Ws28b12b_Segments[mActualSegment].CounterModeStep, Ws28b12b_Segments[mActualSegment].ModeColor[0]); - } + if(IS_REVERSE) { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStop - Ws28b12b_Segments[mActualSegment].CounterModeStep, Ws28b12b_Segments[mActualSegment].ModeColor[0]); + } else { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + Ws28b12b_Segments[mActualSegment].CounterModeStep, Ws28b12b_Segments[mActualSegment].ModeColor[0]); + } - Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) % SEGMENT_LENGTH; - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + Ws28b12b_Segments[mActualSegment].CounterModeStep = (Ws28b12b_Segments[mActualSegment].CounterModeStep + 1) % SEGMENT_LENGTH; + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; } @@ -1797,50 +1820,38 @@ void mode_comet(void) { * Fireworks function. */ void fireworks(uint32_t color) { - fade_out(); + fade_out(); -//// set brightness(i) = brightness(i-1)/4 + brightness(i) + brightness(i+1)/4 -/* -// the old way, so many calls to the pokey getPixelColor() function made this super slow - for(uint16_t i=0 + 1; i > 2) & 0x3F3F3F3F; - uint32_t thisLed = Adafruit_NeoPixel::getPixelColor(i); - uint32_t nextLed = (Adafruit_NeoPixel::getPixelColor(i+1) >> 2) & 0x3F3F3F3F; - WS2812B_SetDiodeColor(i, prevLed + thisLed + nextLed); - } -*/ + uint8_t *pixels = ws2812_get_pixels(); + uint8_t pixelsPerLed = 3; + uint16_t startPixel = Ws28b12b_Segments[mActualSegment].IdStart * pixelsPerLed + pixelsPerLed; + uint16_t stopPixel = Ws28b12b_Segments[mActualSegment].IdStop * pixelsPerLed ; + for(uint16_t i=startPixel; i > 2) + + pixels[i] + + (pixels[i + pixelsPerLed] >> 2); + pixels[i] = tmpPixel > 255 ? 255 : tmpPixel; + } -// the new way, manipulate the Adafruit_NeoPixels pixels[] array directly, about 5x faster - uint8_t *pixels = WS2812B_GetPixels(); - uint8_t pixelsPerLed = 3; - uint16_t startPixel = Ws28b12b_Segments[mActualSegment].IdStart * pixelsPerLed + pixelsPerLed; - uint16_t stopPixel = Ws28b12b_Segments[mActualSegment].IdStop * pixelsPerLed ; - for(uint16_t i=startPixel; i > 2) + - pixels[i] + - (pixels[i + pixelsPerLed] >> 2); - pixels[i] = tmpPixel > 255 ? 255 : tmpPixel; - } - - if(!mTriggered) - { - for(uint16_t i=0; i> 16) & 0xFF; - uint8_t g = (Ws28b12b_Segments[mActualSegment].ModeColor[0] >> 8) & 0xFF; - uint8_t b = (Ws28b12b_Segments[mActualSegment].ModeColor[0] & 0xFF); - uint8_t lum = MAX(r, MAX(g, b)) / rev_intensity; - for(uint16_t i=Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) - { - int flicker = rand()%lum; - WS2812B_SetDiodeRGB(i, MAX(r - flicker, 0), MAX(g - flicker, 0), MAX(b - flicker, 0)); - } - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + uint8_t r = (Ws28b12b_Segments[mActualSegment].ModeColor[0] >> 16) & 0xFF; + uint8_t g = (Ws28b12b_Segments[mActualSegment].ModeColor[0] >> 8) & 0xFF; + uint8_t b = (Ws28b12b_Segments[mActualSegment].ModeColor[0] & 0xFF); + uint8_t lum = MAX(r, MAX(g, b)) / rev_intensity; + for(uint16_t i=Ws28b12b_Segments[mActualSegment].IdStart; i <= Ws28b12b_Segments[mActualSegment].IdStop; i++) + { + int flicker = rand()%lum; + ws2812_set_led_rgb(i, MAX(r - flicker, 0), MAX(g - flicker, 0), MAX(b - flicker, 0)); + } + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; } /* @@ -1882,7 +1893,7 @@ void fire_flicker(int rev_intensity) */ void mode_fire_flicker(void) { - return fire_flicker(3); + return fire_flicker(3); } /* @@ -1890,7 +1901,7 @@ void mode_fire_flicker(void) */ void mode_fire_flicker_soft(void) { - return fire_flicker(6); + return fire_flicker(6); } /* @@ -1898,7 +1909,7 @@ void mode_fire_flicker_soft(void) */ void mode_fire_flicker_intense(void) { - return fire_flicker(1.7); + return fire_flicker(1.7); } @@ -1907,24 +1918,24 @@ void mode_fire_flicker_intense(void) */ void tricolor_chase(uint32_t color1, uint32_t color2, uint32_t color3) { - uint16_t index = Ws28b12b_Segments[mActualSegment].CounterModeStep % 6; - for(uint16_t i=0; i < SEGMENT_LENGTH; i++, index++) - { - if(index > 5) index = 0; + uint16_t index = Ws28b12b_Segments[mActualSegment].CounterModeStep % 6; + for(uint16_t i=0; i < SEGMENT_LENGTH; i++, index++) + { + if(index > 5) index = 0; - uint32_t color = color3; - if(index < 2) color = color1; - else if(index < 4) color = color2; + uint32_t color = color3; + if(index < 2) color = color1; + else if(index < 4) color = color2; - if(IS_REVERSE) { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + i, color); - } else { - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStop - i, color); - } - } + if(IS_REVERSE) { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + i, color); + } else { + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStop - i, color); + } + } - Ws28b12b_Segments[mActualSegment].CounterModeStep++; - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + Ws28b12b_Segments[mActualSegment].CounterModeStep++; + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; } @@ -1933,7 +1944,7 @@ void tricolor_chase(uint32_t color1, uint32_t color2, uint32_t color3) */ void mode_tricolor_chase(void) { - return tricolor_chase(Ws28b12b_Segments[mActualSegment].ModeColor[0], Ws28b12b_Segments[mActualSegment].ModeColor[1], Ws28b12b_Segments[mActualSegment].ModeColor[2]); + return tricolor_chase(Ws28b12b_Segments[mActualSegment].ModeColor[0], Ws28b12b_Segments[mActualSegment].ModeColor[1], Ws28b12b_Segments[mActualSegment].ModeColor[2]); } @@ -1942,7 +1953,7 @@ void mode_tricolor_chase(void) */ void mode_circus_combustus(void) { - return tricolor_chase(RED, WHITE, BLACK); + return tricolor_chase(RED, WHITE, BLACK); } /* @@ -1950,38 +1961,38 @@ void mode_circus_combustus(void) */ void mode_icu(void) { - uint16_t dest = Ws28b12b_Segments[mActualSegment].CounterModeStep & 0xFFFF; - - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + dest, Ws28b12b_Segments[mActualSegment].ModeColor[0]); - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + dest + WS2812B_LEDS/2, Ws28b12b_Segments[mActualSegment].ModeColor[0]); - - if(Ws28b12b_Segments[mActualSegment].AuxParam16b == dest) - { // pause between eye movements - if(rand()%6 == 0) - { // blink once in a while - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + dest, BLACK); - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + dest + SEGMENT_LENGTH/2, BLACK); - Ws28b12b_Segments[mActualSegment].ModeDelay = 200; - } - Ws28b12b_Segments[mActualSegment].AuxParam16b = rand() %(SEGMENT_LENGTH/2); - Ws28b12b_Segments[mActualSegment].ModeDelay = 1000 + rand() %2000; - } - - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + dest, BLACK); - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + dest + SEGMENT_LENGTH/2, BLACK); - - if(Ws28b12b_Segments[mActualSegment].AuxParam16b > Ws28b12b_Segments[mActualSegment].CounterModeStep) - { - Ws28b12b_Segments[mActualSegment].CounterModeStep++; - dest++; - } else if (Ws28b12b_Segments[mActualSegment].AuxParam16b < Ws28b12b_Segments[mActualSegment].CounterModeStep) - { - Ws28b12b_Segments[mActualSegment].CounterModeStep--; - dest--; - } - - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + dest, Ws28b12b_Segments[mActualSegment].ModeColor[0]); - WS2812B_SetDiodeColor(Ws28b12b_Segments[mActualSegment].IdStart + dest + SEGMENT_LENGTH/2, Ws28b12b_Segments[mActualSegment].ModeColor[0]); - - Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; + uint16_t dest = Ws28b12b_Segments[mActualSegment].CounterModeStep & 0xFFFF; + + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + dest, Ws28b12b_Segments[mActualSegment].ModeColor[0]); + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + dest + WS2812B_LEDS/2, Ws28b12b_Segments[mActualSegment].ModeColor[0]); + + if(Ws28b12b_Segments[mActualSegment].AuxParam16b == dest) + { /* pause between eye movements */ + if(rand()%6 == 0) + { /* blink once in a while */ + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + dest, BLACK); + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + dest + SEGMENT_LENGTH/2, BLACK); + Ws28b12b_Segments[mActualSegment].ModeDelay = 200; + } + Ws28b12b_Segments[mActualSegment].AuxParam16b = rand() %(SEGMENT_LENGTH/2); + Ws28b12b_Segments[mActualSegment].ModeDelay = 1000 + rand() %2000; + } + + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + dest, BLACK); + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + dest + SEGMENT_LENGTH/2, BLACK); + + if(Ws28b12b_Segments[mActualSegment].AuxParam16b > Ws28b12b_Segments[mActualSegment].CounterModeStep) + { + Ws28b12b_Segments[mActualSegment].CounterModeStep++; + dest++; + } else if (Ws28b12b_Segments[mActualSegment].AuxParam16b < Ws28b12b_Segments[mActualSegment].CounterModeStep) + { + Ws28b12b_Segments[mActualSegment].CounterModeStep--; + dest--; + } + + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + dest, Ws28b12b_Segments[mActualSegment].ModeColor[0]); + ws2812_set_led_color_val(Ws28b12b_Segments[mActualSegment].IdStart + dest + SEGMENT_LENGTH/2, Ws28b12b_Segments[mActualSegment].ModeColor[0]); + + Ws28b12b_Segments[mActualSegment].ModeDelay = Ws28b12b_Segments[mActualSegment].Speed; }