FastLED 3.9.15
Loading...
Searching...
No Matches

◆ loop()

void loop ( )

Definition at line 240 of file Chromancer.ino.

240 {
241 unsigned long benchmark = millis();
242 FL_UNUSED(benchmark);
243
244 // Fade all dots to create trails
245 for (int strip = 0; strip < 40; strip++) {
246 for (int led = 0; led < 14; led++) {
247 for (int i = 0; i < 3; i++) {
248 ledColors[strip][led][i] *= sliderDecay.value();
249 }
250 }
251 }
252
253 for (int i = 0; i < numberOfRipples; i++) {
254 ripples[i].advance(ledColors);
255 }
256
257 for (int segment = 0; segment < 40; segment++) {
258 for (int fromBottom = 0; fromBottom < 14; fromBottom++) {
259 int strip = ledAssignments[segment][0];
260 int led = fl::round(fmap(fromBottom, 0, 13, ledAssignments[segment][2],
261 ledAssignments[segment][1]));
262 leds[strip][led] = CRGB(ledColors[segment][fromBottom][0],
263 ledColors[segment][fromBottom][1],
264 ledColors[segment][fromBottom][2]);
265 }
266 }
267
268 if (allWhite) {
269 // for all strips
270 for (int i = 0; i < 4; i++) {
271 for (int j = 0; j < lengths[i]; j++) {
272 leds[i][j] = CRGB::White;
273 }
274 }
275 }
276
277 FastLED.show();
278
279
280 // Check if buttons were clicked
286
287 if (wasSpiralClicked) {
288 // Trigger spiral wave effect from center
289 unsigned int baseColor = random(0xFFFF);
290 byte centerNode = 15; // Center node
291
292 // Create 6 ripples in a spiral pattern
293 for (int i = 0; i < 6; i++) {
294 if (nodeConnections[centerNode][i] >= 0) {
295 for (int j = 0; j < numberOfRipples; j++) {
296 if (ripples[j].state == dead) {
297 ripples[j].start(
298 centerNode, i,
300 baseColor + (0xFFFF / 6) * i, 255, 255),
301 0.3 + (i * 0.1), // Varying speeds creates spiral effect
302 2000,
303 i % 2 ? alwaysTurnsLeft : alwaysTurnsRight); // Alternating turn directions
304 break;
305 }
306 }
307 }
308 }
310 }
311
313 // Trigger immediate border wave effect
314 unsigned int baseColor = random(0xFFFF);
315
316 // Start ripples from each border node in sequence
317 for (int i = 0; i < numberOfBorderNodes; i++) {
318 byte node = borderNodes[i];
319 // Find an inward direction
320 for (int dir = 0; dir < 6; dir++) {
321 if (nodeConnections[node][dir] >= 0 &&
322 !isNodeOnBorder(nodeConnections[node][dir])) {
323 for (int j = 0; j < numberOfRipples; j++) {
324 if (ripples[j].state == dead) {
325 ripples[j].start(
326 node, dir,
328 baseColor + (0xFFFF / numberOfBorderNodes) * i,
329 255, 255),
330 .4, 2000, 0);
331 break;
332 }
333 }
334 break;
335 }
336 }
337 }
339 }
340
342 // Trigger immediate rainbow cube effect
343 int node = cubeNodes[random(numberOfCubeNodes)];
344 unsigned int baseColor = random(0xFFFF);
345 byte behavior = random(2) ? alwaysTurnsLeft : alwaysTurnsRight;
346
347 for (int i = 0; i < 6; i++) {
348 if (nodeConnections[node][i] >= 0) {
349 for (int j = 0; j < numberOfRipples; j++) {
350 if (ripples[j].state == dead) {
351 ripples[j].start(
352 node, i,
354 baseColor + (0xFFFF / 6) * i, 255, 255),
355 .5, 2000, behavior);
356 break;
357 }
358 }
359 }
360 }
362 }
363
365 // Trigger immediate starburst effect
366 unsigned int baseColor = random(0xFFFF);
367 byte behavior = random(2) ? alwaysTurnsLeft : alwaysTurnsRight;
368
369 for (int i = 0; i < 6; i++) {
370 for (int j = 0; j < numberOfRipples; j++) {
371 if (ripples[j].state == dead) {
372 ripples[j].start(
373 starburstNode, i,
375 baseColor + (0xFFFF / 6) * i, 255, 255),
376 .65, 1500, behavior);
377 break;
378 }
379 }
380 }
382 }
383
385 // Trigger immediate heartbeat effect
386 for (int i = 0; i < 6; i++) {
387 for (int j = 0; j < numberOfRipples; j++) {
388 if (ripples[j].state == dead) {
389 ripples[j].start(15, i, 0xEE1111,
390 float(random(100)) / 100.0 * .1 + .4, 1000, 0);
391 break;
392 }
393 }
394 }
396 }
397
399 // When biometric data is unavailable, visualize at random
402 unsigned int baseColor = random(0xFFFF);
403
404 if (currentAutoPulseType == 255 ||
407 byte possiblePulse = 255;
408 while (true) {
409 possiblePulse = random(3);
410
411 if (possiblePulse == currentAutoPulseType)
412 continue;
413
414 switch (possiblePulse) {
415 case 0:
417 continue;
418 break;
419
420 case 1:
422 continue;
423 break;
424
425 case 2:
427 continue;
428 break;
429
430 default:
431 continue;
432 }
433
434 currentAutoPulseType = possiblePulse;
436 break;
437 }
438 }
439
440 switch (currentAutoPulseType) {
441 case 0: {
442 int node = 0;
443 bool foundStartingNode = false;
444 while (!foundStartingNode) {
445 node = random(25);
446 foundStartingNode = true;
447 for (int i = 0; i < numberOfBorderNodes; i++) {
448 // Don't fire a pulse on one of the outer nodes - it
449 // looks boring
450 if (node == borderNodes[i])
451 foundStartingNode = false;
452 }
453
454 if (node == lastAutoPulseNode)
455 foundStartingNode = false;
456 }
457
458 lastAutoPulseNode = node;
459
460 for (int i = 0; i < 6; i++) {
461 if (nodeConnections[node][i] >= 0) {
462 for (int j = 0; j < numberOfRipples; j++) {
463 if (ripples[j].state == dead) {
464 ripples[j].start(
465 node, i,
466 // strip0.ColorHSV(baseColor
467 // + (0xFFFF / 6) * i,
468 // 255, 255),
469 Adafruit_DotStar_ColorHSV(baseColor, 255,
470 255),
471 float(random(100)) / 100.0 * .2 + .5, 3000,
472 1);
473
474 break;
475 }
476 }
477 }
478 }
479 break;
480 }
481
482 case 1: {
483 int node = cubeNodes[random(numberOfCubeNodes)];
484
485 while (node == lastAutoPulseNode)
486 node = cubeNodes[random(numberOfCubeNodes)];
487
488 lastAutoPulseNode = node;
489
490 byte behavior = random(2) ? alwaysTurnsLeft : alwaysTurnsRight;
491
492 for (int i = 0; i < 6; i++) {
493 if (nodeConnections[node][i] >= 0) {
494 for (int j = 0; j < numberOfRipples; j++) {
495 if (ripples[j].state == dead) {
496 ripples[j].start(
497 node, i,
498 // strip0.ColorHSV(baseColor
499 // + (0xFFFF / 6) * i,
500 // 255, 255),
501 Adafruit_DotStar_ColorHSV(baseColor, 255,
502 255),
503 .5, 2000, behavior);
504
505 break;
506 }
507 }
508 }
509 }
510 break;
511 }
512
513 case 2: {
514 byte behavior = random(2) ? alwaysTurnsLeft : alwaysTurnsRight;
515
517
518 for (int i = 0; i < 6; i++) {
519 for (int j = 0; j < numberOfRipples; j++) {
520 if (ripples[j].state == dead) {
521 ripples[j].start(
522 starburstNode, i,
524 baseColor + (0xFFFF / 6) * i, 255, 255),
525 .65, 1500, behavior);
526
527 break;
528 }
529 }
530 }
531 break;
532 }
533
534 default:
535 break;
536 }
538 }
539
541 // Simulated heartbeat
543 for (int i = 0; i < 6; i++) {
544 for (int j = 0; j < numberOfRipples; j++) {
545 if (ripples[j].state == dead) {
546 ripples[j].start(
547 15, i, 0xEE1111,
548 float(random(100)) / 100.0 * .1 + .4, 1000, 0);
549
550 break;
551 }
552 }
553 }
554
557 }
558
559 // Simulated EDA ripples
560 if (millis() >= nextSimulatedEda) {
561 for (int i = 0; i < 10; i++) {
562 for (int j = 0; j < numberOfRipples; j++) {
563 if (ripples[j].state == dead) {
564 byte targetNode =
566 byte direction = 255;
567
568 while (direction == 255) {
569 direction = random(6);
570 if (nodeConnections[targetNode][direction] < 0)
571 direction = 255;
572 }
573
574 ripples[j].start(
575 targetNode, direction, 0x1111EE,
576 float(random(100)) / 100.0 * .5 + 2, 300, 2);
577
578 break;
579 }
580 }
581 }
582
584 random(simulatedEdaVariance);
585 }
586 }
587 }
588
589 // Serial.print("Benchmark: ");
590 // Serial.println(millis() - benchmark);
591}
fl::CRGB leds[NUM_LEDS]
byte currentAutoPulseType
#define simulatedHeartbeatBaseTime
bool isNodeOnBorder(byte node)
bool wasStarburstClicked
bool wasRainbowCubeClicked
byte lastAutoPulseNode
unsigned long nextSimulatedHeartbeat
fl::UIButton simulatedHeartbeat("Simulated Heartbeat")
byte ledColors[40][14][3]
unsigned long lastAutoPulseChange
unsigned long lastRandomPulse
#define simulatedEdaBaseTime
fl::UIButton triggerBorderWave("Border Wave")
fl::UICheckbox starburstPulsesEnabled("Starburst Pulses", true)
#define simulatedEdaVariance
fl::UICheckbox allWhite("All White", false)
bool wasSpiralClicked
#define randomPulsesEnabled
constexpr int lengths[]
unsigned long lastHeartbeat
fl::UIButton triggerSpiral("Spiral Wave")
#define autoPulseTimeout
bool wasHeartbeatClicked
fl::UICheckbox simulatedBiometricsEnabled("Simulated Biometrics", true)
#define simulatedHeartbeatVariance
#define randomPulseTime
bool wasBorderWaveClicked
#define numberOfRipples
fl::UISlider sliderDecay("decay",.97f,.8, 1.0,.01)
#define autoPulseChangeTime
unsigned long nextSimulatedEda
byte numberOfAutoPulseTypes
fl::UIButton triggerStarburst("Trigger Starburst")
Ripple ripples[numberOfRipples]
#define cubePulsesEnabled
fl::UIButton triggerRainbowCube("Rainbow Cube")
TestState state
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
uint32_t Adafruit_DotStar_ColorHSV(uint16_t hue, uint8_t sat, uint8_t val)
Definition detail.h:6
fl::CRGB CRGB
Definition crgb.h:25
int starburstNode
Definition mapping.h:156
int numberOfCubeNodes
Definition mapping.h:152
int nodeConnections[25][6]
Definition mapping.h:15
int ledAssignments[40][3]
Definition mapping.h:95
int numberOfBorderNodes
Definition mapping.h:147
int borderNodes[]
Definition mapping.h:148
int cubeNodes[]
Definition mapping.h:153
fl::u32 millis()
Universal millisecond timer - returns milliseconds since system startup.
enable_if<!is_integral< T >::value, T >::type round(T value) FL_NOEXCEPT
Definition math.h:319
@ dead
Definition ripple.h:17
@ alwaysTurnsRight
Definition ripple.h:27
@ alwaysTurnsLeft
Definition ripple.h:28
float fmap(float x, float in_min, float in_max, float out_min, float out_max)
Definition ripple.h:31
#define FL_UNUSED(x)
@ White
<div style='background:#FFFFFF;width:4em;height:4em;'></div>
Definition crgb.h:646

References Adafruit_DotStar_ColorHSV(), allWhite, alwaysTurnsLeft, alwaysTurnsRight, autoPulseChangeTime, autoPulseTimeout, borderNodes, cubeNodes, cubePulsesEnabled, currentAutoPulseType, dead, FastLED, FL_UNUSED, fmap(), isNodeOnBorder(), lastAutoPulseChange, lastAutoPulseNode, lastHeartbeat, lastRandomPulse, ledAssignments, ledColors, leds, lengths, nextSimulatedEda, nextSimulatedHeartbeat, nodeConnections, numberOfAutoPulseTypes, numberOfBorderNodes, numberOfCubeNodes, numberOfRipples, randomPulsesEnabled, randomPulseTime, ripples, fl::round(), simulatedBiometricsEnabled, simulatedEdaBaseTime, simulatedEdaVariance, simulatedHeartbeat, simulatedHeartbeatBaseTime, simulatedHeartbeatVariance, sliderDecay, starburstNode, starburstPulsesEnabled, state, triggerBorderWave, triggerRainbowCube, triggerSpiral, triggerStarburst, wasBorderWaveClicked, wasHeartbeatClicked, wasRainbowCubeClicked, wasSpiralClicked, wasStarburstClicked, and fl::CRGB::White.

+ Here is the call graph for this function: