FastLED 3.10.6
Loading...
Searching...
No Matches

◆ run()

DriftResult autoresearch::timing_drift::run ( int pin,
int num_leds,
int iterations )
inline

Definition at line 87 of file AutoResearchTimingDrift.h.

87 {
88 DriftResult r{};
89 r.pin = pin;
90
91 if (iterations < 1) iterations = 1;
92 if (iterations > kMaxIterations) iterations = kMaxIterations;
93 if (num_leds < 2) num_leds = 2;
94 if (num_leds > kMaxLeds) num_leds = kMaxLeds;
95 r.num_leds = num_leds;
96
98 for (int i = 0; i < num_leds; ++i) {
99 leds[i] = CRGB::Black;
100 }
101
102 // Probe whether the requested pin is dispatchable BEFORE mutating any
103 // global state — invalid pins must not clear other RPC tests' channels.
104 {
105 LegacyClocklessProxy probe(pin, leds, num_leds);
106 if (!probe.valid()) {
107 return r; // valid_pin stays false; no side effects
108 }
109 }
110
111 // Clean slate: drop any channels left over from earlier RPC tests so
112 // show() drives only the legacy controller under test.
114
115 LegacyClocklessProxy proxy(pin, leds, num_leds);
116 r.valid_pin = true;
117
118#if defined(ARDUINO_ARCH_ESP32)
119 r.cpu_mhz = getCpuFrequencyMhz();
120#endif
121
122 // sketch setup() — addLeds happened in the proxy above.
124 FastLED.show();
125
126 constexpr uint32_t kFastLedUpdateMs = 5;
127 MillisDelay ms_fast_led;
128 MillisDelay ms_delay_post;
129
130 ms_delay_post.start(0);
131 ms_fast_led.start(kFastLedUpdateMs);
132
133 int i_post_fade = 255;
134 uint32_t i_iteration_time = millis();
135 int completed = 0;
136
137 r.show_min_us = 0xFFFFFFFFu;
138
139 auto timedShow = [&]() {
140 const uint32_t t0 = micros();
141 FastLED.show();
142 const uint32_t dt = micros() - t0;
143 r.show_count++;
144 r.show_total_us += dt;
145 if (dt < r.show_min_us) r.show_min_us = dt;
146 if (dt > r.show_max_us) r.show_max_us = dt;
147 };
148
149 auto updateLEDs = [&]() {
150 if (ms_fast_led.justFinished()) {
151 timedShow();
152 ms_fast_led.start(kFastLedUpdateMs);
153 }
154 };
155
156 const int i_ring_start = 0;
157 const int i_ring_end = num_leds - 1;
158 const int i_ring_divisor = 7;
159
160 // Each sequence runs ~2.5 s and we may queue up to kMaxIterations of
161 // them, so feed the AutoResearch watchdog (5 s timeout) on a coarse
162 // cadence to keep the device alive through long runs.
163 uint32_t last_wdt_feed_ms = millis();
164 constexpr uint32_t kWdtFeedIntervalMs = 1000;
165 auto maybeFeedWatchdog = [&]() {
166 const uint32_t now = millis();
167 if (now - last_wdt_feed_ms >= kWdtFeedIntervalMs) {
169 last_wdt_feed_ms = now;
170 }
171 };
172
173 // Transliteration of the sketch's loop(); `continue` stands in for the
174 // sketch's early `return` (Arduino re-enters loop()).
175 while (completed < iterations) {
176 if (i_post_fade > 0 && ms_delay_post.justFinished()) {
177 const int i_ring_counter =
178 ((255 - i_post_fade) / i_ring_divisor) + i_ring_start;
179
180 if (i_ring_counter <= i_ring_end) {
181 leds[i_ring_counter] = CRGB::Red;
182 }
183 if (i_ring_counter - 1 >= i_ring_start &&
184 i_ring_counter - 1 <= i_ring_end) {
185 leds[i_ring_counter - 1] = CRGB::Black;
186 }
187
188 i_post_fade--;
189
190 if (i_post_fade == 0) {
191 const uint32_t now = millis();
192 r.iter_ms[completed] = now - i_iteration_time;
193 completed++;
194 i_iteration_time = now;
195 ms_delay_post.stop();
196
197 for (int i = i_ring_start; i <= i_ring_end; i++) {
198 leds[i] = CRGB::Black;
199 }
200
201 updateLEDs();
202 FastLED.watchdog().feed(); // before the 1 s sleep
203 delay(1000);
204 FastLED.watchdog().feed(); // after the 1 s sleep
205 last_wdt_feed_ms = millis();
206 i_post_fade = 255;
207 ms_delay_post.start(225);
208 continue;
209 } else {
210 ms_delay_post.start(5);
211 }
212 }
213 updateLEDs();
214 maybeFeedWatchdog();
215 }
216
217 r.iterations = completed;
218 if (r.show_count == 0) {
219 r.show_min_us = 0;
220 }
221
222 // Teardown: restore unthrottled refresh (boot default). The proxy
223 // destructor removes the legacy controller from the draw list.
225 return r;
226}
CRGB leds[1]
void updateLEDs()
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
void setMaxRefreshRate(fl::u16 refresh, bool constrain=false)
Set the maximum refresh rate.
void show(fl::u8 scale)
Update all our controllers with the current led colors, using the passed in brightness.
static fl::Watchdog & watchdog()
Access the unified cross-platform watchdog timer.
void clear(bool writeData=false)
Clear the leds, wiping the local array of data.
Proxy that creates a legacy clockless controller from runtime inputs.
void feed() FL_NO_EXCEPT
@ CHANNELS
Remove all channels from controller list.
Definition FastLED.h:668
fl::CRGB CRGB
Definition crgb.h:25
TimingDriftState & timingDriftState()
void delay(u32 ms, bool run_async=true) FL_NO_EXCEPT
Public delay wrapper that keeps bare Arduino delay() preferred after using fl::delay; while still all...
Definition delay.h:98
fl::u32 millis()
Universal millisecond timer - returns milliseconds since system startup.
fl::u32 micros()
Universal microsecond timer - returns microseconds since system startup.
fl::u32 uint32_t
Definition stdint.h:218
Faithful emulation of the millisDelay library used by the issue sketch: start(t) arms a deadline; jus...
@ Red
<div style='background:#FF0000;width:4em;height:4em;'></div>
Definition crgb.h:629
@ Black
<div style='background:#000000;width:4em;height:4em;'></div>
Definition crgb.h:517

References fl::CRGB::Black, CHANNELS, FastLED, autoresearch::timing_drift::MillisDelay::justFinished(), kMaxIterations, kMaxLeds, autoresearch::timing_drift::TimingDriftState::leds, leds, autoresearch::timing_drift::DriftResult::pin, fl::CRGB::Red, autoresearch::timing_drift::MillisDelay::start(), autoresearch::timing_drift::MillisDelay::stop(), timingDriftState(), updateLEDs(), and LegacyClocklessProxy::valid().

+ Here is the call graph for this function: