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_) {
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; }
108 void set_colors(
const std::vector<AddressableColorWipeEffectColor> &colors) { this->colors_ = colors; }
112 const uint32_t now =
millis();
113 if (now - this->last_add_ < this->add_led_interval_)
115 this->last_add_ = now;
121 const Color esp_color =
Color(color.
r, color.
g, color.
b, color.
w);
126 if (++this->leds_added_ >= color.
num_leds) {
127 this->leds_added_ = 0;
128 this->at_color_ = (this->at_color_ + 1) % this->colors_.size();
141 std::vector<AddressableColorWipeEffectColor>
colors_;
143 uint32_t last_add_{0};
144 uint32_t add_led_interval_{};
145 size_t leds_added_{0};
155 const uint32_t now =
millis();
156 if (now - this->last_move_ < this->move_interval_)
161 if (this->at_led_ == it.
size() - this->scan_width_)
162 this->direction_ =
false;
165 if (this->at_led_ == 0)
166 this->direction_ =
true;
168 this->last_move_ = now;
171 for (uint32_t i = 0; i < this->scan_width_; i++) {
172 it[this->at_led_ + i] = current_color;
179 uint32_t move_interval_{};
180 uint32_t scan_width_{1};
181 uint32_t last_move_{0};
183 bool direction_{
true};
190 const uint32_t now =
millis();
192 if (now - this->last_progress_ > this->progress_interval_) {
193 const uint32_t pos_add32 = (now - this->last_progress_) / this->progress_interval_;
195 this->last_progress_ += pos_add32 * this->progress_interval_;
197 for (
auto view : addressable) {
198 if (view.get_effect_data() != 0) {
199 const uint8_t sine = half_sin8(view.get_effect_data());
200 view = current_color * sine;
201 const uint8_t new_pos = view.get_effect_data() + pos_add;
202 if (new_pos < view.get_effect_data())
203 view.set_effect_data(0);
205 view.set_effect_data(new_pos);
212 if (addressable[pos].get_effect_data() != 0)
214 addressable[pos].set_effect_data(1);
216 addressable.schedule_show();
222 float twinkle_probability_{0.05f};
223 uint32_t progress_interval_{4};
224 uint32_t last_progress_{0};
231 const uint32_t now =
millis();
233 if (now - this->last_progress_ > this->progress_interval_) {
234 pos_add = (now - this->last_progress_) / this->progress_interval_;
235 this->last_progress_ = now;
237 uint8_t subsine = ((8 * (now - this->last_progress_)) / this->progress_interval_) & 0b111;
238 for (
auto view : it) {
239 if (view.get_effect_data() != 0) {
240 const uint8_t x = (view.get_effect_data() >> 3) & 0b11111;
241 const uint8_t color = view.get_effect_data() & 0b111;
242 const uint16_t sine = half_sin8((x << 3) | subsine);
244 view = current_color * sine;
246 view =
Color(((color >> 2) & 1) * sine, ((color >> 1) & 1) * sine, ((color >> 0) & 1) * sine);
248 const uint8_t new_x = x + pos_add;
250 view.set_effect_data(0);
252 view.set_effect_data((new_x << 3) | color);
254 view =
Color(0, 0, 0, 0);
259 if (it[pos].get_effect_data() != 0)
262 it[pos].set_effect_data(0b1000 | color);
270 float twinkle_probability_{};
271 uint32_t progress_interval_{};
272 uint32_t last_progress_{0};
283 const uint32_t now =
millis();
284 if (now - this->last_update_ < this->update_interval_)
286 this->last_update_ = now;
288 const uint8_t fade_out_mult = 255u - this->fade_out_rate_;
289 for (
auto view : it) {
290 Color target = view.get() * fade_out_mult;
295 int last = it.size() - 1;
296 it[0].set(it[0].
get() + (it[1].
get() * 128));
297 for (
int i = 1; i < last; i++) {
298 it[i] = (it[i - 1].get() * 64) + it[i].
get() + (it[i + 1].get() * 64);
300 it[last] = it[last].get() + (it[last - 1].get() * 128);
303 if (this->use_random_color_) {
306 it[pos] = current_color;
317 uint8_t fade_out_rate_{};
318 uint32_t update_interval_{};
319 uint32_t last_update_{0};
320 float spark_probability_{};
321 bool use_random_color_{};
328 const uint32_t now =
millis();
329 const uint8_t intensity = this->intensity_;
330 const uint8_t inv_intensity = 255 - intensity;
331 if (now - this->last_update_ < this->update_interval_)
334 this->last_update_ = now;
336 for (
auto var : it) {
337 rng_state = (rng_state * 0x9E3779B9) + 0x9E37;
338 const uint8_t flicker = (rng_state & 0xFF) % intensity;
340 var = var.get() * (255 - flicker);
343 var = (var.get() * inv_intensity) + (current_color * intensity);
348 void set_intensity(
float intensity) { this->intensity_ = to_uint8_scale(intensity); }
351 uint32_t update_interval_{16};
352 uint32_t last_update_{0};
353 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
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)
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.