|
@@ -0,0 +1,297 @@
|
|
|
+// #ifdef FASTLED_INTERNAL
|
|
|
+
|
|
|
+#include "Atm_fade_WS2812.hpp"
|
|
|
+
|
|
|
+Atm_fade_WS2812::Atm_fade_WS2812( CRGB *_leds, int _num_leds, int _offset_leds) : Machine()
|
|
|
+ {
|
|
|
+ num_leds = _num_leds ;
|
|
|
+ offset_leds = _offset_leds ;
|
|
|
+ leds = _leds + offset_leds ;
|
|
|
+
|
|
|
+ } ;
|
|
|
+
|
|
|
+
|
|
|
+Atm_fade_WS2812& Atm_fade_WS2812::begin( ) {
|
|
|
+ // clang-format off
|
|
|
+ const static state_t state_table[] PROGMEM = {
|
|
|
+ /* ON_ENTER ON_LOOP ON_EXIT EVT_CNT_FADE EVT_TM_FADE EVT_TM_ON EVT_TM_OFF EVT_CNT_RPT EVT_ON EVT_OFF EVT_BLINK EVT_TOGGLE EVT_TOGGLE_BLINK ELSE */
|
|
|
+ /* IDLE */ ENT_OFF, ATM_SLEEP, -1, -1, -1, -1, -1, -1,OSTARTU, IDLE, START, OSTARTU, START, -1, // LED off
|
|
|
+ /* ON */ ENT_ON, ATM_SLEEP, -1, -1, -1, -1, -1, -1, -1,OSTARTD, START, OSTARTD, OSTARTD, -1, // LED on
|
|
|
+ /* START */ ENT_OFF, -1, -1, -1, -1, -1, -1, -1,OSTARTU, IDLE, START, IDLE, IDLE, STARTU, // Start fading
|
|
|
+ /* STARTU */ ENT_START, -1, -1, -1, -1, -1, UP, -1,OSTARTU, IDLE, START, IDLE, IDLE, -1,
|
|
|
+ /* UP */ ENT_UP, -1, -1, STARTD, UP, -1, -1, -1,OSTARTU, IDLE, START, IDLE, IDLE, -1,
|
|
|
+ /* STARTD */ ENT_START, -1, -1, -1, -1, DOWN, -1, -1,OSTARTU, IDLE, START, IDLE, IDLE, -1,
|
|
|
+ /* DOWN */ ENT_DOWN, -1, -1, REPEAT, DOWN, -1, -1, -1,OSTARTU, IDLE, START, IDLE, IDLE, -1,
|
|
|
+ /* REPEAT */ ENT_REPEAT, -1, -1, -1, -1, -1, -1, DONE,OSTARTU, IDLE, START, IDLE, IDLE, STARTU,
|
|
|
+ /* DONE */ ENT_DONE, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, IDLE,
|
|
|
+ /* OSTARTU*/ ENT_START, -1, -1, -1, -1, -1, -1, -1, -1, IDLE, START, IDLE, IDLE, OUP,
|
|
|
+ /* OUP */ ENT_UP, -1, -1, ON, OUP, -1, -1, -1, -1, IDLE, START, IDLE, IDLE, -1,
|
|
|
+ /* OSTARTD*/ ENT_START, -1, -1, -1, -1, -1, -1, -1,OSTARTU, IDLE, START, IDLE, IDLE, ODOWN,
|
|
|
+ /* ODOWN */ ENT_DOWN, -1, -1, IDLE, ODOWN, -1, -1, -1,OSTARTU, IDLE, START, IDLE, IDLE, -1,
|
|
|
+
|
|
|
+ };
|
|
|
+ // clang-format on
|
|
|
+ Machine::begin( state_table, ELSE );
|
|
|
+
|
|
|
+ timer_fade.set( 0 ); // Number of ms per slope step (slope duration: rate * 32 ms)
|
|
|
+ timer_on.set( 500 ); // Plateau between slopes (in which led is fully on)
|
|
|
+ timer_off.set( 500 ); // Pause between slopes (in which led is fully off)
|
|
|
+ // counter_fade.set( SLOPE_SIZE );
|
|
|
+ // timer_update.setFromNow( this, fade_update_rate );
|
|
|
+
|
|
|
+ counter_fade.set( FADE_STEPS );
|
|
|
+ counter_repeat.set( ATM_COUNTER_OFF );
|
|
|
+ repeat_count = ATM_COUNTER_OFF;
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Atm_fade_WS2812& Atm_fade_WS2812::blink( uint32_t duration, uint32_t pause_duration, uint16_t repeat_count /* = ATM_COUNTER_OFF */ ) {
|
|
|
+ blink( duration ); // Time in which led is fully on
|
|
|
+ pause( pause_duration );
|
|
|
+ repeat( repeat_count );
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Atm_fade_WS2812& Atm_fade_WS2812::blink( uint32_t duration ) {
|
|
|
+ timer_on.set( duration ); // Plateau between slopes (in which led is fully on)
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Atm_fade_WS2812& Atm_fade_WS2812::blink( void ) {
|
|
|
+ trigger( EVT_BLINK );
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Atm_fade_WS2812& Atm_fade_WS2812::pause( uint32_t duration ) { // Pause between slopes (in which led is fully off)
|
|
|
+ timer_off.set( duration ? duration : 1 ); // Make sure off_timer is never 0 (work around)
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Atm_fade_WS2812& Atm_fade_WS2812::fade( int fade_length){
|
|
|
+ if(fade_length>=0){
|
|
|
+ fade_duration = fade_length ;
|
|
|
+ FADE_STEPS = fade_length / fade_update_rate ;
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ fade_duration = ATM_TIMER_OFF;
|
|
|
+ FADE_STEPS = 0;
|
|
|
+ }
|
|
|
+ timer_fade.set( fade_length >= 0 ? fade_update_rate : ATM_TIMER_OFF );
|
|
|
+
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Atm_fade_WS2812& Atm_fade_WS2812::fade( int fade_length, bool fade_light, int fade_chase ) {
|
|
|
+ //ws2812 version : fade_timer fixed at 25ms,
|
|
|
+ // number of steps calculated from fade_timer to keep states logic
|
|
|
+ //fade time is total fade time, using state_millis to check progression
|
|
|
+ fade(fade_length);
|
|
|
+ // Serial.printf("Fade duration %d, %d steps\n", fade_duration, FADE_STEPS);
|
|
|
+ _fade_light = fade_light ;
|
|
|
+ _fade_chase = fade_chase ;
|
|
|
+
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Atm_fade_WS2812& Atm_fade_WS2812::repeat( uint16_t repeat ) {
|
|
|
+ counter_repeat.set( repeat_count = repeat );
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+int Atm_fade_WS2812::event( int id ) {
|
|
|
+ switch ( id ) {
|
|
|
+ case EVT_TM_FADE:
|
|
|
+ return timer_fade.expired( this );
|
|
|
+ case EVT_TM_ON:
|
|
|
+ fade_start_millis = millis();
|
|
|
+ return timer_on.expired( this );
|
|
|
+ case EVT_TM_OFF:
|
|
|
+ fade_start_millis = millis();
|
|
|
+ return timer_off.expired( this );
|
|
|
+ case EVT_CNT_FADE:
|
|
|
+ return counter_fade.expired();
|
|
|
+ case EVT_CNT_RPT:
|
|
|
+ return counter_repeat.expired();
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+void Atm_fade_WS2812::action( int id ) {
|
|
|
+
|
|
|
+ switch ( id ) {
|
|
|
+
|
|
|
+ case ENT_ON:
|
|
|
+ update_leds(1) ;
|
|
|
+ return;
|
|
|
+ case ENT_REPEAT:
|
|
|
+ counter_repeat.decrement();
|
|
|
+ return;
|
|
|
+ case ENT_OFF:
|
|
|
+ counter_repeat.set( repeat_count );
|
|
|
+ fade_start_millis = millis();
|
|
|
+ update_leds(0);
|
|
|
+ return;
|
|
|
+ case ENT_START:
|
|
|
+ counter_fade.set( FADE_STEPS );
|
|
|
+ fade_start_millis = millis();
|
|
|
+ // Serial.printf("-----------------ENT_START %d \n", fade_start_millis);
|
|
|
+ return;
|
|
|
+ case ENT_UP:
|
|
|
+ fade_ellapsed_millis = millis() - fade_start_millis ;
|
|
|
+ // Serial.printf("ellapsed %f \n", (float)fade_ellapsed_millis/fade_duration);
|
|
|
+ update_leds((float)fade_ellapsed_millis/fade_duration);
|
|
|
+ counter_fade.decrement();
|
|
|
+ return;
|
|
|
+ case ENT_DOWN:
|
|
|
+ fade_ellapsed_millis = millis() - fade_start_millis ;
|
|
|
+ update_leds( 1-(float) fade_ellapsed_millis/fade_duration);
|
|
|
+ // value = slope[counter_fade.value] ;
|
|
|
+ // leds->fadeToBlackBy(255-value);
|
|
|
+ counter_fade.decrement();
|
|
|
+ return;
|
|
|
+ case ENT_DONE:
|
|
|
+ onfinish.push( 0 );
|
|
|
+ return;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+Atm_fade_WS2812& Atm_fade_WS2812::on( void ) {
|
|
|
+ trigger( EVT_ON );
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Atm_fade_WS2812& Atm_fade_WS2812::off( void ) {
|
|
|
+ trigger( EVT_OFF );
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Atm_fade_WS2812& Atm_fade_WS2812::toggle( void ) {
|
|
|
+ trigger( EVT_TOGGLE );
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Atm_fade_WS2812& Atm_fade_WS2812::toggleBlink( void ) {
|
|
|
+ trigger( EVT_TOGGLE_BLINK );
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Atm_fade_WS2812& Atm_fade_WS2812::start( void ) {
|
|
|
+ trigger( EVT_BLINK );
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Atm_fade_WS2812& Atm_fade_WS2812::onFinish( Machine& machine, int event /* = 0 */ ) {
|
|
|
+ onfinish.set( &machine, event );
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Atm_fade_WS2812& Atm_fade_WS2812::onFinish( atm_cb_push_t callback, int idx /* = 0 */ ) {
|
|
|
+ onfinish.set( callback, idx );
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Atm_fade_WS2812& Atm_fade_WS2812::setColor(int hue, int sat, int val) {
|
|
|
+ this->color.hue = hue ;
|
|
|
+ this->color.sat = sat ;
|
|
|
+ this->color.val = val ;
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Atm_fade_WS2812& Atm_fade_WS2812::replaceValues(bool replace){
|
|
|
+ _replace_array = replace ;
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Atm_fade_WS2812& Atm_fade_WS2812::updateRate(int new_update_rate){
|
|
|
+ // fade_update_rate = new_update_rate ;
|
|
|
+ // timer_update.set( fade_update_rate );
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Atm_fade_WS2812& Atm_fade_WS2812::update(){
|
|
|
+ update_flag = true ;
|
|
|
+ this->cycle() ;
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Atm_fade_WS2812& Atm_fade_WS2812::trace( Stream& stream ) {
|
|
|
+ setTrace( &stream, atm_serial_debug::trace,
|
|
|
+ "FADE\0EVT_CNT_FADE\0EVT_TM_FADE\0EVT_TM_ON\0EVT_TM_OFF\0EVT_CNT_RPT\0EVT_ON\0EVT_OFF\0EVT_BLINK\0EVT_TOGGLE\0EVT_TOGGLE_BLINK\0ELSE\0"
|
|
|
+ "IDLE\0ON\0START\0STARTU\0UP\0STARTD\0DOWN\0REPEAT\0DONE\0OSTARTU\0OUP\0OSTARTD\0ODOWN" );
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+void Atm_fade_WS2812::update_leds(float fade_value){
|
|
|
+
|
|
|
+ if(update_flag){
|
|
|
+ // Serial.println("loop");
|
|
|
+ int current_step = fade_value * FADE_STEPS ;
|
|
|
+
|
|
|
+ CHSV temp_led[this->num_leds] ;
|
|
|
+ int current_value = color.val;
|
|
|
+
|
|
|
+ if(_fade_light){ current_value *= fade_value ;}
|
|
|
+
|
|
|
+ current_value = constrain(current_value, 0, 255 ) ;
|
|
|
+ // Serial.println(current_value);
|
|
|
+ int chase_led = num_leds;
|
|
|
+ for(int led=0; led<num_leds; led++){
|
|
|
+ // Serial.println(led);
|
|
|
+ fade_value = _fade_chase ? fade_value : 1. ;
|
|
|
+ if(led<fade_value*num_leds){
|
|
|
+ temp_led[led].value = current_value ;
|
|
|
+ temp_led[led].saturation = color.saturation ;
|
|
|
+ temp_led[led].hue = color.hue ;
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ temp_led[led].value = 0 ;
|
|
|
+ temp_led[led].saturation = color.saturation ;
|
|
|
+ temp_led[led].hue = color.hue ;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(_replace_array){leds[led] = CRGB(temp_led[led]);}
|
|
|
+ if(!_replace_array){
|
|
|
+ //add or remove one step of color
|
|
|
+ // current_value = color.val / FADE_STEPS ;
|
|
|
+ // temp_led[led].value = current_value ;
|
|
|
+ // temp_led[led].saturation = color.saturation ;
|
|
|
+ // temp_led[led].hue = color.hue ;
|
|
|
+ if(update_flag){
|
|
|
+ CRGB rgb_step = CRGB(temp_led[led]);
|
|
|
+ if(this->state() == DOWN || this->state() == ODOWN) {
|
|
|
+ Serial.println("down");
|
|
|
+ leds[led].r = qsub8 (leds[led].r, rgb_step.r);
|
|
|
+ leds[led].g = qsub8 (leds[led].g, rgb_step.g);
|
|
|
+ leds[led].b = qsub8 (leds[led].b, rgb_step.b);
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ leds[led].r = qadd8 (leds[led].r, rgb_step.r);
|
|
|
+ leds[led].g = qadd8 (leds[led].g, rgb_step.g);
|
|
|
+ leds[led].b = qadd8 (leds[led].b, rgb_step.b);
|
|
|
+ }
|
|
|
+ // leds[led] = blend(leds[led], CRGB(temp_led[led]), 255);
|
|
|
+ }
|
|
|
+
|
|
|
+ // CRGB rgb_step = CRGB(temp_led[led]);
|
|
|
+ // Serial.println(this->state());
|
|
|
+ // if(this->state() == DOWN || this->state() == ODOWN) {
|
|
|
+ // Serial.println("down");
|
|
|
+ // leds[led].r = qsub8 (leds[led].r, rgb_step.r);
|
|
|
+ // leds[led].g = qsub8 (leds[led].g, rgb_step.g);
|
|
|
+ // leds[led].b = qsub8 (leds[led].b, rgb_step.b);
|
|
|
+ // }
|
|
|
+ // else{
|
|
|
+ // leds[led].r = qadd8 (leds[led].r, rgb_step.r);
|
|
|
+ // leds[led].g = qadd8 (leds[led].g, rgb_step.g);
|
|
|
+ // leds[led].b = qadd8 (leds[led].b, rgb_step.b);
|
|
|
+ // }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ update_flag=true ;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+// #endif
|