2017-09-18 17:06:46 +01:00
/*
2018-01-05 11:26:19 +00:00
xplg_ws2812 . ino - ws2812 led string support for Sonoff - Tasmota
2017-09-18 17:06:46 +01:00
2019-01-01 12:55:01 +00:00
Copyright ( C ) 2019 Heiko Krupp and Theo Arends
2017-09-18 17:06:46 +01:00
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# ifdef USE_WS2812
/*********************************************************************************************\
2017-11-11 15:02:18 +00:00
* WS2812 RGB / RGBW Leds using NeopixelBus library
2017-09-18 17:06:46 +01:00
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include <NeoPixelBus.h>
2018-03-17 14:22:29 +00:00
# if (USE_WS2812_CTYPE == NEO_GRB)
2019-02-26 08:08:11 +00:00
typedef NeoGrbFeature selectedNeoFeatureType ;
2018-03-17 14:22:29 +00:00
# elif (USE_WS2812_CTYPE == NEO_BRG)
2019-02-26 08:08:11 +00:00
typedef NeoBrgFeature selectedNeoFeatureType ;
2018-03-17 14:22:29 +00:00
# elif (USE_WS2812_CTYPE == NEO_RBG)
2019-02-26 08:08:11 +00:00
typedef NeoRbgFeature selectedNeoFeatureType ;
2018-03-17 14:22:29 +00:00
# elif (USE_WS2812_CTYPE == NEO_RGBW)
2019-02-26 08:08:11 +00:00
typedef NeoRgbwFeature selectedNeoFeatureType ;
2018-03-17 14:22:29 +00:00
# elif (USE_WS2812_CTYPE == NEO_GRBW)
2019-02-26 08:08:11 +00:00
typedef NeoGrbwFeature selectedNeoFeatureType ;
2017-11-11 15:02:18 +00:00
# else // USE_WS2812_CTYPE
2019-02-26 08:08:11 +00:00
typedef NeoRgbFeature selectedNeoFeatureType ;
2017-09-18 17:06:46 +01:00
# endif // USE_WS2812_CTYPE
2019-02-26 08:08:11 +00:00
# ifdef USE_WS2812_DMA
typedef Neo800KbpsMethod selectedNeoSpeedType ;
2017-11-11 15:02:18 +00:00
# else // USE_WS2812_DMA
2019-02-26 08:08:11 +00:00
typedef NeoEsp8266BitBang800KbpsMethod selectedNeoSpeedType ;
2017-09-18 17:06:46 +01:00
# endif // USE_WS2812_DMA
2019-03-26 17:26:50 +00:00
NeoPixelBus < selectedNeoFeatureType , selectedNeoSpeedType > * strip = nullptr ;
2017-09-18 17:06:46 +01:00
2017-10-18 17:22:34 +01:00
struct WsColor {
2017-09-18 17:06:46 +01:00
uint8_t red , green , blue ;
} ;
struct ColorScheme {
2017-10-18 17:22:34 +01:00
WsColor * colors ;
2017-09-18 17:06:46 +01:00
uint8_t count ;
} ;
2017-11-11 11:33:30 +00:00
WsColor kIncandescent [ 2 ] = { 255 , 140 , 20 , 0 , 0 , 0 } ;
WsColor kRgb [ 3 ] = { 255 , 0 , 0 , 0 , 255 , 0 , 0 , 0 , 255 } ;
WsColor kChristmas [ 2 ] = { 255 , 0 , 0 , 0 , 255 , 0 } ;
WsColor kHanukkah [ 2 ] = { 0 , 0 , 255 , 255 , 255 , 255 } ;
WsColor kwanzaa [ 3 ] = { 255 , 0 , 0 , 0 , 0 , 0 , 0 , 255 , 0 } ;
WsColor kRainbow [ 7 ] = { 255 , 0 , 0 , 255 , 128 , 0 , 255 , 255 , 0 , 0 , 255 , 0 , 0 , 0 , 255 , 128 , 0 , 255 , 255 , 0 , 255 } ;
WsColor kFire [ 3 ] = { 255 , 0 , 0 , 255 , 102 , 0 , 255 , 192 , 0 } ;
2017-12-29 13:55:39 +00:00
ColorScheme kSchemes [ WS2812_SCHEMES ] = {
2017-10-18 17:22:34 +01:00
kIncandescent , 2 ,
kRgb , 3 ,
kChristmas , 2 ,
kHanukkah , 2 ,
2017-09-18 17:06:46 +01:00
kwanzaa , 3 ,
2017-10-18 17:22:34 +01:00
kRainbow , 7 ,
kFire , 3 } ;
2017-09-18 17:06:46 +01:00
2017-10-18 17:22:34 +01:00
uint8_t kWidth [ 5 ] = {
2017-09-18 17:06:46 +01:00
1 , // Small
2 , // Medium
4 , // Large
8 , // Largest
255 } ; // All
2018-11-20 14:53:56 +00:00
uint8_t kWsRepeat [ 5 ] = {
2017-09-18 17:06:46 +01:00
8 , // Small
6 , // Medium
4 , // Large
2 , // Largest
1 } ; // All
2017-10-18 17:22:34 +01:00
uint8_t ws_show_next = 1 ;
2018-06-16 14:23:11 +01:00
bool ws_suspend_update = false ;
2017-09-18 17:06:46 +01:00
/********************************************************************************************/
2018-11-14 13:32:09 +00:00
void Ws2812StripShow ( void )
2017-09-18 17:06:46 +01:00
{
2018-03-17 14:22:29 +00:00
# if (USE_WS2812_CTYPE > NEO_3LED)
2017-11-11 15:02:18 +00:00
RgbwColor c ;
# else
2017-09-18 17:06:46 +01:00
RgbColor c ;
2017-11-11 15:02:18 +00:00
# endif
2017-09-18 17:06:46 +01:00
2017-10-26 15:33:33 +01:00
if ( Settings . light_correction ) {
for ( uint16_t i = 0 ; i < Settings . light_pixels ; i + + ) {
2017-09-18 17:06:46 +01:00
c = strip - > GetPixelColor ( i ) ;
2019-04-30 22:03:08 +01:00
c . R = ledGamma ( c . R ) ;
c . G = ledGamma ( c . G ) ;
c . B = ledGamma ( c . B ) ;
2018-03-17 14:22:29 +00:00
# if (USE_WS2812_CTYPE > NEO_3LED)
2019-04-30 22:03:08 +01:00
c . W = ledGamma ( c . W ) ;
2017-11-11 15:02:18 +00:00
# endif
strip - > SetPixelColor ( i , c ) ;
2017-09-18 17:06:46 +01:00
}
}
strip - > Show ( ) ;
}
int mod ( int a , int b )
{
int ret = a % b ;
2018-03-10 16:58:54 +00:00
if ( ret < 0 ) ret + = b ;
2017-09-18 17:06:46 +01:00
return ret ;
}
2017-10-18 17:22:34 +01:00
2017-11-21 15:06:51 +00:00
void Ws2812UpdatePixelColor ( int position , struct WsColor hand_color , float offset )
2017-10-18 17:22:34 +01:00
{
2018-03-17 14:22:29 +00:00
# if (USE_WS2812_CTYPE > NEO_3LED)
2017-11-11 15:02:18 +00:00
RgbwColor color ;
# else
2017-10-18 17:22:34 +01:00
RgbColor color ;
2017-11-11 15:02:18 +00:00
# endif
2017-10-18 17:22:34 +01:00
2017-10-26 15:33:33 +01:00
uint16_t mod_position = mod ( position , ( int ) Settings . light_pixels ) ;
2017-10-18 17:22:34 +01:00
color = strip - > GetPixelColor ( mod_position ) ;
2017-10-26 15:33:33 +01:00
float dimmer = 100 / ( float ) Settings . light_dimmer ;
2018-07-14 11:10:13 +01:00
color . R = tmin ( color . R + ( ( hand_color . red / dimmer ) * offset ) , 255 ) ;
color . G = tmin ( color . G + ( ( hand_color . green / dimmer ) * offset ) , 255 ) ;
color . B = tmin ( color . B + ( ( hand_color . blue / dimmer ) * offset ) , 255 ) ;
2017-10-18 17:22:34 +01:00
strip - > SetPixelColor ( mod_position , color ) ;
}
2017-10-23 11:18:15 +01:00
void Ws2812UpdateHand ( int position , uint8_t index )
2017-10-18 17:22:34 +01:00
{
2018-03-10 16:58:54 +00:00
position = ( position + Settings . light_rotation ) % Settings . light_pixels ;
if ( Settings . flag . ws_clock_reverse ) position = Settings . light_pixels - position ;
2017-11-11 15:02:18 +00:00
WsColor hand_color = { Settings . ws_color [ index ] [ WS_RED ] , Settings . ws_color [ index ] [ WS_GREEN ] , Settings . ws_color [ index ] [ WS_BLUE ] } ;
2017-10-23 11:18:15 +01:00
2017-11-21 15:06:51 +00:00
Ws2812UpdatePixelColor ( position , hand_color , 1 ) ;
2018-03-10 16:58:54 +00:00
uint8_t range = 1 ;
if ( index < WS_MARKER ) range = ( ( Settings . ws_width [ index ] - 1 ) / 2 ) + 1 ;
2017-11-21 15:06:51 +00:00
for ( uint8_t h = 1 ; h < range ; h + + ) {
float offset = ( float ) ( range - h ) / ( float ) range ;
Ws2812UpdatePixelColor ( position - h , hand_color , offset ) ;
Ws2812UpdatePixelColor ( position + h , hand_color , offset ) ;
2017-10-18 17:22:34 +01:00
}
}
2018-11-14 13:32:09 +00:00
void Ws2812Clock ( void )
2017-09-18 17:06:46 +01:00
{
2017-10-18 17:22:34 +01:00
strip - > ClearTo ( 0 ) ; // Reset strip
2017-11-21 15:06:51 +00:00
int clksize = 60000 / ( int ) Settings . light_pixels ;
2018-03-10 16:58:54 +00:00
2017-11-21 15:06:51 +00:00
Ws2812UpdateHand ( ( RtcTime . second * 1000 ) / clksize , WS_SECOND ) ;
Ws2812UpdateHand ( ( RtcTime . minute * 1000 ) / clksize , WS_MINUTE ) ;
2019-02-12 14:28:45 +00:00
Ws2812UpdateHand ( ( ( ( RtcTime . hour % 12 ) * 5000 ) + ( ( RtcTime . minute * 1000 ) / 12 ) ) / clksize , WS_HOUR ) ;
2018-03-10 16:58:54 +00:00
if ( Settings . ws_color [ WS_MARKER ] [ WS_RED ] + Settings . ws_color [ WS_MARKER ] [ WS_GREEN ] + Settings . ws_color [ WS_MARKER ] [ WS_BLUE ] ) {
2019-01-28 13:08:33 +00:00
for ( uint8_t i = 0 ; i < 12 ; i + + ) {
2018-03-10 16:58:54 +00:00
Ws2812UpdateHand ( ( i * 5000 ) / clksize , WS_MARKER ) ;
}
}
2017-10-29 17:18:46 +00:00
2017-10-18 17:22:34 +01:00
Ws2812StripShow ( ) ;
2017-09-18 17:06:46 +01:00
}
2017-10-18 17:22:34 +01:00
void Ws2812GradientColor ( uint8_t schemenr , struct WsColor * mColor , uint16_t range , uint16_t gradRange , uint16_t i )
2017-09-18 17:06:46 +01:00
{
/*
* Compute the color of a pixel at position i using a gradient of the color scheme .
* This function is used internally by the gradient function .
*/
2017-10-18 17:22:34 +01:00
ColorScheme scheme = kSchemes [ schemenr ] ;
2017-09-18 17:06:46 +01:00
uint16_t curRange = i / range ;
uint16_t rangeIndex = i % range ;
uint16_t colorIndex = rangeIndex / gradRange ;
uint16_t start = colorIndex ;
uint16_t end = colorIndex + 1 ;
if ( curRange % 2 ! = 0 ) {
start = ( scheme . count - 1 ) - start ;
end = ( scheme . count - 1 ) - end ;
}
2017-10-26 15:33:33 +01:00
float dimmer = 100 / ( float ) Settings . light_dimmer ;
2017-10-18 17:22:34 +01:00
float fmyRed = ( float ) map ( rangeIndex % gradRange , 0 , gradRange , scheme . colors [ start ] . red , scheme . colors [ end ] . red ) / dimmer ;
float fmyGrn = ( float ) map ( rangeIndex % gradRange , 0 , gradRange , scheme . colors [ start ] . green , scheme . colors [ end ] . green ) / dimmer ;
float fmyBlu = ( float ) map ( rangeIndex % gradRange , 0 , gradRange , scheme . colors [ start ] . blue , scheme . colors [ end ] . blue ) / dimmer ;
2017-09-18 17:06:46 +01:00
mColor - > red = ( uint8_t ) fmyRed ;
mColor - > green = ( uint8_t ) fmyGrn ;
mColor - > blue = ( uint8_t ) fmyBlu ;
}
2017-10-18 17:22:34 +01:00
void Ws2812Gradient ( uint8_t schemenr )
2017-09-18 17:06:46 +01:00
{
/*
* This routine courtesy Tony DiCola ( Adafruit )
* Display a gradient of colors for the current color scheme .
* Repeat is the number of repetitions of the gradient ( pick a multiple of 2 for smooth looping of the gradient ) .
*/
2018-03-17 14:22:29 +00:00
# if (USE_WS2812_CTYPE > NEO_3LED)
2017-11-11 15:02:18 +00:00
RgbwColor c ;
c . W = 0 ;
# else
2017-09-18 17:06:46 +01:00
RgbColor c ;
2017-11-11 15:02:18 +00:00
# endif
2017-09-18 17:06:46 +01:00
2017-10-18 17:22:34 +01:00
ColorScheme scheme = kSchemes [ schemenr ] ;
2018-03-10 16:58:54 +00:00
if ( scheme . count < 2 ) return ;
2017-09-18 17:06:46 +01:00
2018-11-20 14:53:56 +00:00
uint8_t repeat = kWsRepeat [ Settings . light_width ] ; // number of scheme.count per ledcount
2017-10-26 15:33:33 +01:00
uint16_t range = ( uint16_t ) ceil ( ( float ) Settings . light_pixels / ( float ) repeat ) ;
2017-09-18 17:06:46 +01:00
uint16_t gradRange = ( uint16_t ) ceil ( ( float ) range / ( float ) ( scheme . count - 1 ) ) ;
2017-10-26 15:33:33 +01:00
uint16_t speed = ( ( Settings . light_speed * 2 ) - 1 ) * ( STATES / 10 ) ;
2017-10-25 13:27:30 +01:00
uint16_t offset = speed > 0 ? strip_timer_counter / speed : 0 ;
2017-09-18 17:06:46 +01:00
2017-10-18 17:22:34 +01:00
WsColor oldColor , currentColor ;
Ws2812GradientColor ( schemenr , & oldColor , range , gradRange , offset ) ;
2017-09-18 17:06:46 +01:00
currentColor = oldColor ;
2017-10-26 15:33:33 +01:00
for ( uint16_t i = 0 ; i < Settings . light_pixels ; i + + ) {
2018-11-20 14:53:56 +00:00
if ( kWsRepeat [ Settings . light_width ] > 1 ) {
2017-10-18 17:22:34 +01:00
Ws2812GradientColor ( schemenr , & currentColor , range , gradRange , i + offset ) ;
2017-09-18 17:06:46 +01:00
}
2017-10-26 15:33:33 +01:00
if ( Settings . light_speed > 0 ) {
2017-09-18 17:06:46 +01:00
// Blend old and current color based on time for smooth movement.
2017-10-25 13:27:30 +01:00
c . R = map ( strip_timer_counter % speed , 0 , speed , oldColor . red , currentColor . red ) ;
c . G = map ( strip_timer_counter % speed , 0 , speed , oldColor . green , currentColor . green ) ;
c . B = map ( strip_timer_counter % speed , 0 , speed , oldColor . blue , currentColor . blue ) ;
2017-09-18 17:06:46 +01:00
}
else {
// No animation, just use the current color.
c . R = currentColor . red ;
c . G = currentColor . green ;
c . B = currentColor . blue ;
}
strip - > SetPixelColor ( i , c ) ;
oldColor = currentColor ;
}
2017-10-18 17:22:34 +01:00
Ws2812StripShow ( ) ;
2017-09-18 17:06:46 +01:00
}
2017-10-18 17:22:34 +01:00
void Ws2812Bars ( uint8_t schemenr )
2017-09-18 17:06:46 +01:00
{
/*
* This routine courtesy Tony DiCola ( Adafruit )
* Display solid bars of color for the current color scheme .
* Width is the width of each bar in pixels / lights .
*/
2018-03-17 14:22:29 +00:00
# if (USE_WS2812_CTYPE > NEO_3LED)
2017-11-11 15:02:18 +00:00
RgbwColor c ;
c . W = 0 ;
# else
2017-09-18 17:06:46 +01:00
RgbColor c ;
2017-11-11 15:02:18 +00:00
# endif
2017-09-18 17:06:46 +01:00
uint16_t i ;
2017-10-18 17:22:34 +01:00
ColorScheme scheme = kSchemes [ schemenr ] ;
2017-09-18 17:06:46 +01:00
2017-10-26 15:33:33 +01:00
uint16_t maxSize = Settings . light_pixels / scheme . count ;
2018-03-10 16:58:54 +00:00
if ( kWidth [ Settings . light_width ] > maxSize ) maxSize = 0 ;
2017-09-18 17:06:46 +01:00
2017-10-26 15:33:33 +01:00
uint16_t speed = ( ( Settings . light_speed * 2 ) - 1 ) * ( STATES / 10 ) ;
2017-10-25 13:27:30 +01:00
uint8_t offset = speed > 0 ? strip_timer_counter / speed : 0 ;
2017-09-18 17:06:46 +01:00
2017-10-18 17:22:34 +01:00
WsColor mcolor [ scheme . count ] ;
2017-09-18 17:06:46 +01:00
memcpy ( mcolor , scheme . colors , sizeof ( mcolor ) ) ;
2017-10-26 15:33:33 +01:00
float dimmer = 100 / ( float ) Settings . light_dimmer ;
2017-09-18 17:06:46 +01:00
for ( i = 0 ; i < scheme . count ; i + + ) {
2017-10-18 17:22:34 +01:00
float fmyRed = ( float ) mcolor [ i ] . red / dimmer ;
float fmyGrn = ( float ) mcolor [ i ] . green / dimmer ;
float fmyBlu = ( float ) mcolor [ i ] . blue / dimmer ;
2017-09-18 17:06:46 +01:00
mcolor [ i ] . red = ( uint8_t ) fmyRed ;
mcolor [ i ] . green = ( uint8_t ) fmyGrn ;
mcolor [ i ] . blue = ( uint8_t ) fmyBlu ;
}
uint8_t colorIndex = offset % scheme . count ;
2017-10-26 15:33:33 +01:00
for ( i = 0 ; i < Settings . light_pixels ; i + + ) {
2018-03-10 16:58:54 +00:00
if ( maxSize ) colorIndex = ( ( i + offset ) % ( scheme . count * kWidth [ Settings . light_width ] ) ) / kWidth [ Settings . light_width ] ;
2017-09-18 17:06:46 +01:00
c . R = mcolor [ colorIndex ] . red ;
c . G = mcolor [ colorIndex ] . green ;
c . B = mcolor [ colorIndex ] . blue ;
strip - > SetPixelColor ( i , c ) ;
}
2017-10-18 17:22:34 +01:00
Ws2812StripShow ( ) ;
2017-09-18 17:06:46 +01:00
}
/*********************************************************************************************\
* Public
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2018-11-14 13:32:09 +00:00
void Ws2812Init ( void )
2017-09-18 17:06:46 +01:00
{
# ifdef USE_WS2812_DMA
2019-02-26 08:08:11 +00:00
strip = new NeoPixelBus < selectedNeoFeatureType , selectedNeoSpeedType > ( WS2812_MAX_LEDS ) ; // For Esp8266, the Pin is omitted and it uses GPIO3 due to DMA hardware use.
2017-09-18 17:06:46 +01:00
# else // USE_WS2812_DMA
2019-02-26 08:08:11 +00:00
strip = new NeoPixelBus < selectedNeoFeatureType , selectedNeoSpeedType > ( WS2812_MAX_LEDS , pin [ GPIO_WS2812 ] ) ;
2017-09-18 17:06:46 +01:00
# endif // USE_WS2812_DMA
strip - > Begin ( ) ;
2017-10-18 17:22:34 +01:00
Ws2812Clear ( ) ;
2017-09-18 17:06:46 +01:00
}
2018-11-14 13:32:09 +00:00
void Ws2812Clear ( void )
2017-09-18 17:06:46 +01:00
{
strip - > ClearTo ( 0 ) ;
strip - > Show ( ) ;
2017-10-18 17:22:34 +01:00
ws_show_next = 1 ;
2017-09-18 17:06:46 +01:00
}
2017-11-11 15:02:18 +00:00
void Ws2812SetColor ( uint16_t led , uint8_t red , uint8_t green , uint8_t blue , uint8_t white )
2017-09-18 17:06:46 +01:00
{
2018-03-17 14:22:29 +00:00
# if (USE_WS2812_CTYPE > NEO_3LED)
2017-11-11 15:02:18 +00:00
RgbwColor lcolor ;
lcolor . W = white ;
# else
2017-09-18 17:06:46 +01:00
RgbColor lcolor ;
2017-11-11 15:02:18 +00:00
# endif
2017-09-18 17:06:46 +01:00
lcolor . R = red ;
lcolor . G = green ;
lcolor . B = blue ;
if ( led ) {
strip - > SetPixelColor ( led - 1 , lcolor ) ; // Led 1 is strip Led 0 -> substract offset 1
} else {
// strip->ClearTo(lcolor); // Set WS2812_MAX_LEDS pixels
2017-10-26 15:33:33 +01:00
for ( uint16_t i = 0 ; i < Settings . light_pixels ; i + + ) {
2017-09-18 17:06:46 +01:00
strip - > SetPixelColor ( i , lcolor ) ;
}
}
2018-06-16 14:23:11 +01:00
if ( ! ws_suspend_update ) {
strip - > Show ( ) ;
ws_show_next = 1 ;
}
}
2018-11-14 13:32:09 +00:00
void Ws2812ForceSuspend ( void ) {
2018-06-16 14:23:11 +01:00
ws_suspend_update = true ;
}
2018-11-14 13:32:09 +00:00
void Ws2812ForceUpdate ( void ) {
2018-06-16 14:23:11 +01:00
ws_suspend_update = false ;
2017-09-18 17:06:46 +01:00
strip - > Show ( ) ;
2017-10-18 17:22:34 +01:00
ws_show_next = 1 ;
2017-09-18 17:06:46 +01:00
}
2017-10-18 17:22:34 +01:00
char * Ws2812GetColor ( uint16_t led , char * scolor )
2017-09-18 17:06:46 +01:00
{
2017-11-11 15:02:18 +00:00
uint8_t sl_ledcolor [ 4 ] ;
2017-09-18 17:06:46 +01:00
2018-03-17 14:22:29 +00:00
# if (USE_WS2812_CTYPE > NEO_3LED)
2017-11-11 15:02:18 +00:00
RgbwColor lcolor = strip - > GetPixelColor ( led - 1 ) ;
sl_ledcolor [ 3 ] = lcolor . W ;
# else
2017-09-18 17:06:46 +01:00
RgbColor lcolor = strip - > GetPixelColor ( led - 1 ) ;
2017-11-11 15:02:18 +00:00
# endif
2017-09-18 17:06:46 +01:00
sl_ledcolor [ 0 ] = lcolor . R ;
sl_ledcolor [ 1 ] = lcolor . G ;
sl_ledcolor [ 2 ] = lcolor . B ;
scolor [ 0 ] = ' \0 ' ;
2019-01-28 13:08:33 +00:00
for ( uint8_t i = 0 ; i < light_subtype ; i + + ) {
2017-10-23 11:18:15 +01:00
if ( Settings . flag . decimal_text ) {
snprintf_P ( scolor , 25 , PSTR ( " %s%s%d " ) , scolor , ( i > 0 ) ? " , " : " " , sl_ledcolor [ i ] ) ;
} else {
snprintf_P ( scolor , 25 , PSTR ( " %s%02X " ) , scolor , sl_ledcolor [ i ] ) ;
}
2017-09-18 17:06:46 +01:00
}
return scolor ;
}
2017-10-18 17:22:34 +01:00
void Ws2812ShowScheme ( uint8_t scheme )
2017-09-18 17:06:46 +01:00
{
switch ( scheme ) {
case 0 : // Clock
2018-08-26 16:32:49 +01:00
if ( ( 1 = = state_250mS ) | | ( ws_show_next ) ) {
2017-10-18 17:22:34 +01:00
Ws2812Clock ( ) ;
ws_show_next = 0 ;
2017-09-18 17:06:46 +01:00
}
break ;
default :
2017-10-26 15:33:33 +01:00
if ( 1 = = Settings . light_fade ) {
2017-10-18 17:22:34 +01:00
Ws2812Gradient ( scheme - 1 ) ;
2017-09-18 17:06:46 +01:00
} else {
2017-10-18 17:22:34 +01:00
Ws2812Bars ( scheme - 1 ) ;
2017-09-18 17:06:46 +01:00
}
2017-10-18 17:22:34 +01:00
ws_show_next = 1 ;
2017-09-18 17:06:46 +01:00
break ;
}
}
# endif // USE_WS2812