roo_blink
API Documentation for roo_blink
Loading...
Searching...
No Matches
blinker.cpp
Go to the documentation of this file.
2
3#include "roo_blink.h"
5#include "roo_logging.h"
6
7using namespace roo_time;
8
9namespace roo_blink {
10
12
13RgbBlinker::RgbBlinker(RgbLed& led, roo_scheduler::Scheduler& scheduler)
14 : led_(led),
15 stepper_(scheduler, [this]() { step(); }),
16 sequence_(),
17 pos_(0) {}
18
20 updateSequence(std::move(sequence), -1, Color());
21}
22
23void RgbBlinker::repeat(RgbBlinkSequence sequence, int repetitions,
24 Color terminal_color) {
25 updateSequence(std::move(sequence), repetitions - 1, terminal_color);
26}
27
28void RgbBlinker::execute(RgbBlinkSequence sequence, Color terminal_color) {
29 updateSequence(std::move(sequence), 0, terminal_color);
30}
31
32void RgbBlinker::setColor(Color color) { updateSequence({}, 0, color); }
33
34void RgbBlinker::turnOff() { updateSequence({}, 0, Color()); }
35
36void RgbBlinker::updateSequence(RgbBlinkSequence sequence, int repetitions,
37 Color terminal_color) {
38 roo::lock_guard<roo::mutex> lock(mutex_);
39 sequence_ = std::move(sequence.sequence_);
40 terminal_color_ = terminal_color;
41 current_color_ = terminal_color;
42 repetitions_ = repetitions;
43 fade_in_progress_ = false;
44 pos_ = 0;
45 if (!sequence_.empty() && !stepper_.is_scheduled()) {
46 stepper_.scheduleNow(roo_scheduler::PRIORITY_ELEVATED);
47 } else {
48 current_color_ = terminal_color;
49 led_.setColor(current_color_);
50 }
51}
52
53void RgbBlinker::step() {
54 roo::lock_guard<roo::mutex> lock(mutex_);
55 if (fade_in_progress_) {
56 roo_time::Uptime now = roo_time::Uptime::Now();
57 if (now >= fade_end_time_) {
58 fade_in_progress_ = false;
59 current_color_ = fade_target_color_;
60 led_.setColor(current_color_);
61 } else {
62 float progress = (now - fade_start_time_).inMillisFloat() /
63 (fade_end_time_ - fade_start_time_).inMillisFloat();
64 uint8_t new_r = (uint8_t)((float)fade_start_color_.r() +
65 ((float)fade_target_color_.r() -
66 (float)fade_start_color_.r()) *
67 progress);
68 uint8_t new_g = (uint8_t)((float)fade_start_color_.g() +
69 ((float)fade_target_color_.g() -
70 (float)fade_start_color_.g()) *
71 progress);
72 uint8_t new_b = (uint8_t)((float)fade_start_color_.b() +
73 ((float)fade_target_color_.b() -
74 (float)fade_start_color_.b()) *
75 progress);
76 current_color_ = Color(new_r, new_g, new_b);
77 led_.setColor(current_color_);
78 stepper_.scheduleAfter(roo_time::Millis(20),
79 roo_scheduler::PRIORITY_ELEVATED);
80 return;
81 }
82 }
83 uint16_t next_delay = 0;
84 do {
85 if (pos_ >= sequence_.size()) {
86 sequence_.clear();
87 return;
88 }
89 const RgbStep& s = sequence_[pos_];
90 switch (s.type_) {
91 case RgbStep::kSet: {
92 current_color_ = s.target_color_;
93 led_.setColor(current_color_);
94 break;
95 }
96 case RgbStep::kHold: {
97 next_delay = s.duration_millis_;
98 break;
99 }
100 case RgbStep::kFade:
101 default: {
102 fade_in_progress_ = true;
103 fade_start_color_ = current_color_;
104 fade_target_color_ = s.target_color_;
105 fade_start_time_ = roo_time::Uptime::Now();
106 fade_end_time_ =
107 fade_start_time_ + roo_time::Millis(s.duration_millis_);
108 next_delay = 20;
109 break;
110 }
111 }
112 ++pos_;
113 if (pos_ == sequence_.size() && repetitions_ != 0) {
114 if (repetitions_ > 0) --repetitions_;
115 pos_ = 0;
116 }
117 } while (next_delay == 0);
118 stepper_.scheduleAfter(roo_time::Millis(next_delay),
119 roo_scheduler::PRIORITY_ELEVATED);
120}
121
122RgbBlinkSequence RgbBlink(roo_time::Duration period, Color color,
123 int duty_percent, int rampup_percent_on,
124 int rampup_percent_off) {
125 CHECK_GE(duty_percent, 0);
126 CHECK_LE(duty_percent, 100);
127 CHECK_GE(rampup_percent_on, 0);
128 CHECK_LE(rampup_percent_on, 100);
129 CHECK_GE(rampup_percent_off, 0);
130 CHECK_LE(rampup_percent_off, 100);
131 int millis = period.inMillis();
132 int millis_1st = duty_percent * millis / 100;
133 int millis_1st_rampup = rampup_percent_on * millis_1st / 100;
134 int millis_2nd = millis - millis_1st;
135 int millis_2nd_rampup = rampup_percent_off * millis_2nd / 100;
136
137 RgbBlinkSequence result;
138
139 if (millis_1st_rampup > 0) {
140 result.add(RgbFadeTo(color, Millis(millis_1st_rampup)));
141 } else {
142 result.add(RgbSetTo(color));
143 }
144 if (millis_1st_rampup < millis_1st) {
145 result.add(RgbHold(Millis(millis_1st - millis_1st_rampup)));
146 }
147
148 if (millis_2nd_rampup > 0) {
149 result.add(RgbFadeOff(Millis(millis_2nd_rampup)));
150 } else {
151 result.add(RgbTurnOff());
152 }
153 if (millis_2nd_rampup < millis_2nd) {
154 result.add(RgbHold(Millis(millis_2nd - millis_2nd_rampup)));
155 }
156
157 return result;
158}
159
160} // namespace roo_blink