Procházet zdrojové kódy

added Atm_fade_ws2812

Machine for pixel segment management, based on Atm_fade
Etienne Landon před 10 měsíci
rodič
revize
21b6fabef7
3 změnil soubory, kde provedl 372 přidání a 2 odebrání
  1. 3 2
      Atm_AccelStepper.cpp
  2. 297 0
      Atm_fade_WS2812.cpp
  3. 72 0
      Atm_fade_WS2812.hpp

+ 3 - 2
Atm_AccelStepper.cpp

@@ -1,4 +1,5 @@
-// #ifdef AccelStepper_h
+#ifdef AccelStepper_h
+
 #include "Atm_AccelStepper.h"
 
 /* Add optional parameters for the state machine to begin()
@@ -767,4 +768,4 @@ Atm_AccelStepper& Atm_AccelStepper::trace( Stream & stream ) {
   return *this;
 }
 
-// #endif
+#endif

+ 297 - 0
Atm_fade_WS2812.cpp

@@ -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

+ 72 - 0
Atm_fade_WS2812.hpp

@@ -0,0 +1,72 @@
+#pragma once
+
+#ifndef ATM_FADE_WS2812_H_
+#define ATM_FADE_WS2812_H_
+
+#include <Automaton.h>
+#include "FastLED.h"
+
+class Atm_fade_WS2812 : public Machine {
+ public:
+  enum { IDLE, ON, START, STARTU, UP, STARTD, DOWN, REPEAT, DONE, OSTARTU, OUP, OSTARTD, ODOWN };
+  enum { 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 };
+  enum { EVT_START = EVT_BLINK };
+
+  Atm_fade_WS2812( CRGB *_leds, int _num_leds, int _offset_leds) ;
+  Atm_fade_WS2812& begin();
+  Atm_fade_WS2812& trace( Stream& stream );
+  Atm_fade_WS2812& blink( uint32_t duration, uint32_t pause_duration, uint16_t repeat_count = ATM_COUNTER_OFF );
+  Atm_fade_WS2812& blink( uint32_t duration );
+  Atm_fade_WS2812& blink( void );
+  Atm_fade_WS2812& pause( uint32_t duration );
+  Atm_fade_WS2812& fade( int fade_length);
+  Atm_fade_WS2812& fade( int fade_length, bool fade_light, int fade_chase);
+  Atm_fade_WS2812& repeat( uint16_t repeat );
+  Atm_fade_WS2812& on( void );
+  Atm_fade_WS2812& off( void );
+  Atm_fade_WS2812& toggle( void );
+  Atm_fade_WS2812& toggleBlink( void );
+  Atm_fade_WS2812& start( void );
+  Atm_fade_WS2812& onFinish( Machine& machine, int event = 0 );
+  Atm_fade_WS2812& onFinish( atm_cb_push_t callback, int idx = 0 );
+
+  Atm_fade_WS2812& setColor(int hue, int sat, int val);
+  Atm_fade_WS2812& replaceValues(bool replace); // if true replace the array, else just add values
+  Atm_fade_WS2812& updateRate(int new_update_rate); // change update rate
+  Atm_fade_WS2812& update();
+
+ private:
+  CRGB * leds;
+  int num_leds ;
+  int offset_leds ;
+  CHSV color ;
+  int FADE_STEPS = 254 ;
+  uint32_t fade_duration ; //last led to update
+  unsigned long fade_start_millis ;
+  uint32_t fade_ellapsed_millis ;
+  uint32_t fade_update_rate = 22 ;
+  bool _fade_light = true ;
+  bool _fade_chase = 0 ;
+  void update_leds(float fade_value) ;
+  bool _replace_array = true ;
+  bool update_flag = true; // for synchronised update
+
+  enum { ENT_REPEAT, ENT_OFF, ENT_ON, ENT_UP, ENT_DOWN, ENT_START, ENT_DONE };
+  
+  
+  // short pin;
+  uint16_t repeat_count;
+  atm_connector onfinish;
+  atm_timer_millis timer_fade, timer_on, timer_off, timer_update;
+  atm_counter counter_fade, counter_repeat;
+  int event( int id );
+  void action( int id );
+
+  protected:
+	// virtual void initLED();
+	// virtual void switchOn();
+	// virtual void switchOff();
+  // virtual void setBrightness(int value);
+};
+
+#endif