SensESP 3.3.0
Universal Signal K sensor toolkit ESP32
Loading...
Searching...
No Matches
led_blinker.h
Go to the documentation of this file.
1#ifndef SENSESP_SYSTEM_LED_BLINKER_H_
2#define SENSESP_SYSTEM_LED_BLINKER_H_
3
4#include <Arduino.h>
5#include <ReactESP.h>
6
7#include "crgb.h"
9
10namespace sensesp {
11
12#define PATTERN_END (-1)
13
18 public:
19 BaseBlinker(int pin) : pin_{pin} {
20 pinMode(pin, OUTPUT);
21 event_loop()->onDelay(1, [this]() { this->tick(); });
22 }
23
26 void set_state(bool state) {
27 this->state_ = state;
28 digitalWrite(pin_, state);
30 }
31
35 void flip_state() { this->set_state(!this->state_); }
36
40 void blip(int duration = 20) {
41 // indicator for a blip being in progress
42 static bool blipping = false;
43
44 // only allow one blip at a time
45 if (blipping) {
46 return;
47 }
48 blipping = true;
49
50 bool const orig_state = this->state_;
51 this->set_state(false);
52 int const current_counter = this->update_counter_;
53 event_loop()->onDelay(
54 duration, [this, duration, orig_state, current_counter]() {
55 // only update if no-one has touched the LED in the meanwhile
56 if (this->update_counter_ == current_counter) {
57 this->set_state(true);
58 int const new_counter = this->update_counter_;
59 event_loop()->onDelay(duration, [this, orig_state, new_counter]() {
60 // again, only update if no-one has touched the LED
61 if (this->update_counter_ == new_counter) {
62 this->set_state(orig_state);
63 }
64 blipping = false;
65 });
66 } else {
67 blipping = false;
68 }
69 });
70 }
71
75 void set_enabled(bool state) {
76 bool const was_enabled = this->enabled_;
77 this->enabled_ = state;
78 if (this->enabled_) {
79 this->tick();
80 } else {
81 this->set_state(false);
82 if (was_enabled) {
83 event_->remove(event_loop());
84 }
85 }
86 }
87
91 virtual void tick() = 0;
92
93 protected:
94 int pin_;
95 bool enabled_ = true;
96 bool state_ = false;
98 reactesp::Event* event_ = NULL;
99};
100
101class LEDPattern;
102using FragmentCallback = std::function<void(uint32_t, CRGB&)>;
103
105 public:
106 LEDPatternFragment(uint32_t duration_ms, FragmentCallback callback)
107 : duration_ms_(duration_ms), callback_(callback) {}
108
109 // Copy constructor
112
113 // Assignment operator
116 callback_ = other.callback_;
117 return *this;
118 }
119
120 uint32_t duration_ms_;
122};
123
125 public:
127 LEDPattern(const std::vector<LEDPatternFragment>& fragments)
128 : fragments_(fragments) {}
129 LEDPattern(const std::initializer_list<LEDPatternFragment>& fragments)
130 : fragments_(fragments),
133
134 // Assignment operator
136 fragments_ = other.fragments_;
139 return *this;
140 }
141
142 bool apply(CRGB& crgb, bool oneshot = false) {
143 // Initialize fragment begin time if it's the first time
144 if (fragment_begin_ms_ == 0) {
145 fragment_begin_ms_ = millis();
146 }
147 unsigned long current_fragment_duration_ms =
148 fragments_[current_fragment_idx_].duration_ms_;
149 while (millis() - fragment_begin_ms_ >= current_fragment_duration_ms) {
151 if (current_fragment_idx_ >= fragments_.size()) {
153 if (oneshot) {
154 return false;
155 }
156 }
157 fragment_begin_ms_ += current_fragment_duration_ms;
158 current_fragment_duration_ms =
159 fragments_[current_fragment_idx_].duration_ms_;
160 }
161 // Call the callback function for the current fragment, passing the elapsed
162 // time and a reference to the CRGB object
164 crgb);
165 return true;
166 }
167
168 protected:
169 std::vector<LEDPatternFragment> fragments_;
171 unsigned long fragment_begin_ms_ = 0;
172};
173
191 public:
192 LEDBlinker(CRGB& crgb, LEDPattern pattern, std::function<void()> show_func)
193 : crgb_(crgb), pattern_(pattern), show_func_(show_func) {}
194 void tick() {
195 // Always start with the last color
197 pattern_.apply(crgb_);
199 std::list<LEDPattern>::iterator it = modifiers_.begin();
200 while (it != modifiers_.end()) {
201 LEDPattern* mod = &*it;
202 bool result = mod->apply(crgb_, true);
203 if (!result) {
204 it = modifiers_.erase(it);
205 } else {
206 it++;
207 }
208 }
209 show_func_();
210 }
211
212 void set_pattern(const LEDPattern& pattern) { pattern_ = pattern; }
213
214 void add_modifier(const LEDPattern& modifier) {
215 modifiers_.push_back(modifier);
216 }
217
218 protected:
220 CRGB last_color_ = CRGB::Black; // Previous set color before modifiers
222 std::list<LEDPattern> modifiers_ = {};
223
224 std::function<void()> show_func_;
225};
226
227LEDPatternFragment frag_solid_color(uint32_t duration_ms, const CRGB& color);
228LEDPatternFragment frag_linear_fade(uint32_t duration_ms,
229 uint32_t fade_duration_ms,
230 const CRGB& target_color);
231LEDPatternFragment frag_linear_invert(uint32_t duration_ms,
232 bool reverse = false);
233LEDPatternFragment frag_blend(uint32_t duration_ms, const CRGB& target_color,
234 bool reverse = false);
235LEDPatternFragment frag_nop(uint32_t duration_ms);
236} // namespace sensesp
237
238#endif
void set_state(bool state)
Definition led_blinker.h:26
void set_enabled(bool state)
Definition led_blinker.h:75
void blip(int duration=20)
Definition led_blinker.h:40
virtual void tick()=0
reactesp::Event * event_
Definition led_blinker.h:98
std::function< void()> show_func_
void add_modifier(const LEDPattern &modifier)
void set_pattern(const LEDPattern &pattern)
std::list< LEDPattern > modifiers_
LEDBlinker(CRGB &crgb, LEDPattern pattern, std::function< void()> show_func)
LEDPatternFragment(const LEDPatternFragment &other)
LEDPatternFragment & operator=(const LEDPatternFragment &other)
FragmentCallback callback_
LEDPatternFragment(uint32_t duration_ms, FragmentCallback callback)
LEDPattern(const std::vector< LEDPatternFragment > &fragments)
unsigned long fragment_begin_ms_
bool apply(CRGB &crgb, bool oneshot=false)
uint32_t current_fragment_idx_
std::vector< LEDPatternFragment > fragments_
LEDPattern(const std::initializer_list< LEDPatternFragment > &fragments)
LEDPattern & operator=(const LEDPattern &other)
std::shared_ptr< reactesp::EventLoop > event_loop()
Definition sensesp.cpp:9
LEDPatternFragment frag_linear_fade(uint32_t duration_ms, uint32_t fade_duration_ms, const CRGB &target_color)
LEDPatternFragment frag_nop(uint32_t duration_ms)
LEDPatternFragment frag_blend(uint32_t duration_ms, const CRGB &target_color, bool reverse)
std::function< void(uint32_t, CRGB &)> FragmentCallback
LEDPatternFragment frag_linear_invert(uint32_t duration_ms, bool reverse)
LEDPatternFragment frag_solid_color(uint32_t duration_ms, const CRGB &color)
Minimal RGB color struct.
Definition crgb.h:58
static const CRGB Black
Definition crgb.h:88