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;
117 if (this->reverse_) {
125 size_t next_color_index = (this->at_color_ + 1) % this->colors_.size();
127 const Color next_esp_color =
Color(next_color.
r, next_color.
g, next_color.
b, next_color.
w);
128 uint8_t gradient = 255 * ((float) this->leds_added_ / color.
num_leds);
129 esp_color = esp_color.
gradient(next_esp_color, gradient);
131 if (this->reverse_) {
136 if (++this->leds_added_ >= color.
num_leds) {
137 this->leds_added_ = 0;
138 this->at_color_ = (this->at_color_ + 1) % this->colors_.size();
151 std::vector<AddressableColorWipeEffectColor>
colors_;
153 uint32_t last_add_{0};
154 uint32_t add_led_interval_{};
155 size_t leds_added_{0};
165 const uint32_t now =
millis();
166 if (now - this->last_move_ < this->move_interval_)
171 if (this->at_led_ == it.
size() - this->scan_width_)
172 this->direction_ =
false;
175 if (this->at_led_ == 0)
176 this->direction_ =
true;
178 this->last_move_ = now;
181 for (uint32_t i = 0; i < this->scan_width_; i++) {
182 it[this->at_led_ + i] = current_color;
189 uint32_t move_interval_{};
190 uint32_t scan_width_{1};
191 uint32_t last_move_{0};
193 bool direction_{
true};
200 const uint32_t now =
millis();
202 if (now - this->last_progress_ > this->progress_interval_) {
203 const uint32_t pos_add32 = (now - this->last_progress_) / this->progress_interval_;
205 this->last_progress_ += pos_add32 * this->progress_interval_;
207 for (
auto view : addressable) {
208 if (view.get_effect_data() != 0) {
209 const uint8_t sine = half_sin8(view.get_effect_data());
210 view = current_color * sine;
211 const uint8_t new_pos = view.get_effect_data() + pos_add;
212 if (new_pos < view.get_effect_data()) {
213 view.set_effect_data(0);
215 view.set_effect_data(new_pos);
223 if (addressable[pos].get_effect_data() != 0)
225 addressable[pos].set_effect_data(1);
227 addressable.schedule_show();
233 float twinkle_probability_{0.05f};
234 uint32_t progress_interval_{4};
235 uint32_t last_progress_{0};
242 const uint32_t now =
millis();
244 if (now - this->last_progress_ > this->progress_interval_) {
245 pos_add = (now - this->last_progress_) / this->progress_interval_;
246 this->last_progress_ = now;
248 uint8_t subsine = ((8 * (now - this->last_progress_)) / this->progress_interval_) & 0b111;
249 for (
auto view : it) {
250 if (view.get_effect_data() != 0) {
251 const uint8_t
x = (view.get_effect_data() >> 3) & 0b11111;
252 const uint8_t color = view.get_effect_data() & 0b111;
253 const uint16_t sine = half_sin8((x << 3) | subsine);
255 view = current_color * sine;
257 view =
Color(((color >> 2) & 1) * sine, ((color >> 1) & 1) * sine, ((color >> 0) & 1) * sine);
259 const uint8_t new_x = x + pos_add;
260 if (new_x > 0b11111) {
261 view.set_effect_data(0);
263 view.set_effect_data((new_x << 3) | color);
266 view =
Color(0, 0, 0, 0);
271 if (it[pos].get_effect_data() != 0)
274 it[pos].set_effect_data(0b1000 | color);
282 float twinkle_probability_{};
283 uint32_t progress_interval_{};
284 uint32_t last_progress_{0};
295 const uint32_t now =
millis();
296 if (now - this->last_update_ < this->update_interval_)
298 this->last_update_ = now;
300 const uint8_t fade_out_mult = 255u - this->fade_out_rate_;
301 for (
auto view : it) {
302 Color target = view.get() * fade_out_mult;
307 int last = it.size() - 1;
308 it[0].set(it[0].
get() + (it[1].
get() * 128));
309 for (
int i = 1; i < last; i++) {
310 it[i] = (it[i - 1].get() * 64) + it[i].
get() + (it[i + 1].get() * 64);
312 it[last] = it[last].get() + (it[last - 1].get() * 128);
315 if (this->use_random_color_) {
318 it[pos] = current_color;
329 uint8_t fade_out_rate_{};
330 uint32_t update_interval_{};
331 uint32_t last_update_{0};
332 float spark_probability_{};
333 bool use_random_color_{};
340 const uint32_t now =
millis();
341 const uint8_t intensity = this->intensity_;
342 const uint8_t inv_intensity = 255 - intensity;
343 if (now - this->last_update_ < this->update_interval_)
346 this->last_update_ = now;
348 for (
auto var : it) {
349 rng_state = (rng_state * 0x9E3779B9) + 0x9E37;
350 const uint8_t flicker = (rng_state & 0xFF) % intensity;
352 var = var.get() * (255 - flicker);
355 var = (var.get() * inv_intensity) + (current_color * intensity);
360 void set_intensity(
float intensity) { this->intensity_ = to_uint8_scale(intensity); }
363 uint32_t update_interval_{16};
364 uint32_t last_update_{0};
365 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)
Implementation of SPI Controller mode.
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.