13 inline static int16_t sin16_c(uint16_t theta) {
14 static const uint16_t BASE[] = {0, 6393, 12539, 18204, 23170, 27245, 30273, 32137};
15 static const uint8_t SLOPE[] = {49, 48, 44, 38, 31, 23, 14, 4};
16 uint16_t offset = (theta & 0x3FFF) >> 3;
18 offset = 2047 - offset;
19 uint8_t section = offset / 256;
20 uint16_t b = BASE[section];
21 uint8_t
m = SLOPE[section];
22 uint8_t secoffset8 = uint8_t(offset) / 2;
23 uint16_t mx = m * secoffset8;
29 inline static uint8_t half_sin8(uint8_t v) {
return sin16_c(uint16_t(v) * 128u) >> 8; }
55 uint32_t update_interval)
57 void start()
override { this->initial_run_ =
true; }
59 const uint32_t now =
millis();
60 if (now - this->last_run_ >= this->update_interval_ || this->initial_run_) {
61 this->last_run_ = now;
62 this->f_(it, current_color, this->initial_run_);
63 this->initial_run_ =
false;
69 std::function<void(AddressableLight &, Color, bool initial_run)>
f_;
71 uint32_t last_run_{0};
82 uint16_t hue = (
millis() * this->speed_) % 0xFFFF;
83 const uint16_t add = 0xFFFF / this->width_;
92 void set_width(uint16_t width) { this->width_ = width; }
109 void set_colors(
const std::vector<AddressableColorWipeEffectColor> &colors) { this->colors_ = colors; }
113 const uint32_t now =
millis();
114 if (now - this->last_add_ < this->add_led_interval_)
116 this->last_add_ = now;
124 size_t next_color_index = (this->at_color_ + 1) % this->colors_.size();
126 const Color next_esp_color =
Color(next_color.
r, next_color.
g, next_color.
b, next_color.
w);
127 uint8_t gradient = 255 * ((float) this->leds_added_ / color.
num_leds);
128 esp_color = esp_color.
gradient(next_esp_color, gradient);
134 if (++this->leds_added_ >= color.
num_leds) {
135 this->leds_added_ = 0;
136 this->at_color_ = (this->at_color_ + 1) % this->colors_.size();
149 std::vector<AddressableColorWipeEffectColor>
colors_;
151 uint32_t last_add_{0};
152 uint32_t add_led_interval_{};
153 size_t leds_added_{0};
163 const uint32_t now =
millis();
164 if (now - this->last_move_ < this->move_interval_)
169 if (this->at_led_ == it.
size() - this->scan_width_)
170 this->direction_ =
false;
173 if (this->at_led_ == 0)
174 this->direction_ =
true;
176 this->last_move_ = now;
179 for (uint32_t i = 0; i < this->scan_width_; i++) {
180 it[this->at_led_ + i] = current_color;
187 uint32_t move_interval_{};
188 uint32_t scan_width_{1};
189 uint32_t last_move_{0};
191 bool direction_{
true};
198 const uint32_t now =
millis();
200 if (now - this->last_progress_ > this->progress_interval_) {
201 const uint32_t pos_add32 = (now - this->last_progress_) / this->progress_interval_;
203 this->last_progress_ += pos_add32 * this->progress_interval_;
205 for (
auto view : addressable) {
206 if (view.get_effect_data() != 0) {
207 const uint8_t sine = half_sin8(view.get_effect_data());
208 view = current_color * sine;
209 const uint8_t new_pos = view.get_effect_data() + pos_add;
210 if (new_pos < view.get_effect_data())
211 view.set_effect_data(0);
213 view.set_effect_data(new_pos);
220 if (addressable[pos].get_effect_data() != 0)
222 addressable[pos].set_effect_data(1);
224 addressable.schedule_show();
230 float twinkle_probability_{0.05f};
231 uint32_t progress_interval_{4};
232 uint32_t last_progress_{0};
239 const uint32_t now =
millis();
241 if (now - this->last_progress_ > this->progress_interval_) {
242 pos_add = (now - this->last_progress_) / this->progress_interval_;
243 this->last_progress_ = now;
245 uint8_t subsine = ((8 * (now - this->last_progress_)) / this->progress_interval_) & 0b111;
246 for (
auto view : it) {
247 if (view.get_effect_data() != 0) {
248 const uint8_t
x = (view.get_effect_data() >> 3) & 0b11111;
249 const uint8_t color = view.get_effect_data() & 0b111;
250 const uint16_t sine = half_sin8((x << 3) | subsine);
252 view = current_color * sine;
254 view =
Color(((color >> 2) & 1) * sine, ((color >> 1) & 1) * sine, ((color >> 0) & 1) * sine);
256 const uint8_t new_x = x + pos_add;
258 view.set_effect_data(0);
260 view.set_effect_data((new_x << 3) | color);
262 view =
Color(0, 0, 0, 0);
267 if (it[pos].get_effect_data() != 0)
270 it[pos].set_effect_data(0b1000 | color);
278 float twinkle_probability_{};
279 uint32_t progress_interval_{};
280 uint32_t last_progress_{0};
291 const uint32_t now =
millis();
292 if (now - this->last_update_ < this->update_interval_)
294 this->last_update_ = now;
296 const uint8_t fade_out_mult = 255u - this->fade_out_rate_;
297 for (
auto view : it) {
298 Color target = view.get() * fade_out_mult;
303 int last = it.size() - 1;
304 it[0].set(it[0].
get() + (it[1].
get() * 128));
305 for (
int i = 1; i < last; i++) {
306 it[i] = (it[i - 1].get() * 64) + it[i].
get() + (it[i + 1].get() * 64);
308 it[last] = it[last].get() + (it[last - 1].get() * 128);
311 if (this->use_random_color_) {
314 it[pos] = current_color;
325 uint8_t fade_out_rate_{};
326 uint32_t update_interval_{};
327 uint32_t last_update_{0};
328 float spark_probability_{};
329 bool use_random_color_{};
336 const uint32_t now =
millis();
337 const uint8_t intensity = this->intensity_;
338 const uint8_t inv_intensity = 255 - intensity;
339 if (now - this->last_update_ < this->update_interval_)
342 this->last_update_ = now;
344 for (
auto var : it) {
345 rng_state = (rng_state * 0x9E3779B9) + 0x9E37;
346 const uint8_t flicker = (rng_state & 0xFF) % intensity;
348 var = var.get() * (255 - flicker);
351 var = (var.get() * inv_intensity) + (current_color * intensity);
356 void set_intensity(
float intensity) { this->intensity_ = to_uint8_scale(intensity); }
359 uint32_t update_interval_{16};
360 uint32_t last_update_{0};
361 uint8_t intensity_{13};
void set_reverse(bool reverse)
void apply(AddressableLight &addressable, const Color ¤t_color) override
virtual void clear_effect_data()=0
void set_width(uint16_t width)
void set_fade_out_rate(uint8_t fade_out_rate)
void set_move_interval(uint32_t move_interval)
AddressableColorWipeEffect(const std::string &name)
AddressableFireworksEffect(const std::string &name)
void set_effect_active(bool effect_active)
uint32_t random_uint32()
Return a random 32-bit unsigned integer.
AddressableScanEffect(const std::string &name)
AddressableLight * get_addressable_() const
LightOutput * get_output() const
Get the light output associated with this object.
void set_progress_interval(uint32_t progress_interval)
void shift_left(int32_t amnt)
void set_update_interval(uint32_t update_interval)
AddressableTwinkleEffect(const std::string &name)
void set_use_random_color(bool random_color)
void set_spark_probability(float spark_probability)
uint32_t IRAM_ATTR HOT millis()
void set_scan_width(uint32_t scan_width)
static Color random_color()
void set_add_led_interval(uint32_t add_led_interval)
void apply(AddressableLight &it, const Color ¤t_color) override
AddressableLightEffect(const std::string &name)
AddressableFlickerEffect(const std::string &name)
AddressableRandomTwinkleEffect(const std::string &name)
void set_progress_interval(uint32_t progress_interval)
uint32_t update_interval_
void apply(AddressableLight &it, const Color ¤t_color) override
virtual int32_t size() const =0
Color gradient(const Color &to_color, uint8_t amnt)
void apply(AddressableLight &it, const Color ¤t_color) override
AddressableLambdaLightEffect(const std::string &name, std::function< void(AddressableLight &, Color, bool initial_run)> f, uint32_t update_interval)
void start_internal() override
void set_twinkle_probability(float twinkle_probability)
std::vector< AddressableColorWipeEffectColor > colors_
Color color_from_light_color_values(LightColorValues val)
Convert the color information from a LightColorValues object to a Color object (does not apply bright...
void set_colors(const std::vector< AddressableColorWipeEffectColor > &colors)
void set_intensity(float intensity)
void set_speed(uint32_t speed)
void set_twinkle_probability(float twinkle_probability)
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
LightColorValues remote_values
The remote color values reported to the frontend.
virtual void start()
Initialize this LightEffect. Will be called once after creation.
void set_update_interval(uint32_t update_interval)
void apply(AddressableLight &it, const Color ¤t_color) override
std::function< void(AddressableLight &, Color, bool initial_run)> f_
AddressableRainbowLightEffect(const std::string &name)
void shift_right(int32_t amnt)
void apply(AddressableLight &it, const Color ¤t_color) override
void apply(AddressableLight &it, const Color ¤t_color) override
void apply(AddressableLight &it, const Color ¤t_color) override
float random_float()
Return a random float between 0 and 1.