FastLED 3.10.8
Loading...
Searching...
No Matches
AnimartrixRing.ino
Go to the documentation of this file.
1// @filter: (memory is large)
2
26
27// Use SPI-based WS2812 driver instead of RMT on ESP32
28#define FASTLED_ESP32_USE_CLOCKLESS_SPI
29
30// FastLED.h must be included first to trigger precompiled headers for FastLED's
31// build system
32#include "FastLED.h"
33
35#include "fl/fx/fx2d_to_1d.h"
36#include "fl/fx/fx_engine.h"
37#include "fl/ui/ui.h"
38
39#include "auto_brightness.h"
40#include "ring_screenmap.h"
41
42FASTLED_TITLE("AnimartrixRing");
43
44#define NUM_LEDS 244
45
46#ifndef PIN_DATA
47#define PIN_DATA 3 // ESP32C6 has this random pin available on the break out.
48#endif // PIN_DATA
49
50#define BRIGHTNESS 8
51
52// Grid dimensions for Animartrix sampling
53#define GRID_WIDTH 16
54#define GRID_HEIGHT 16
55
56// 0.15 cm or 1.5mm -- appropriate for a dense LED rope.
57#define LED_DIAMETER 0.15f
58
59#define FIRST_ANIMATION fl::AnimartrixAnim::SLOW_FADE
60
62
63// Animartrix 2D effect: the source image the ring samples from.
64XYMap xymap = XYMap::constructRectangularGrid(GRID_WIDTH, GRID_HEIGHT);
66
67// ScreenMap for the ring: places each LED on a circle inside the grid.
70
71// The 2D-to-1D sampling effect: bilinear-samples the grid at each ring point.
74
75// FxEngine for the 1D strip
77
78// UI controls. The dropdown order matches fl::AnimartrixAnim exactly, so the
79// selected index can be handed straight to Animartrix::fxSet().
80// Title comes from FASTLED_TITLE above -- do not declare a second fl::UITitle.
82 "Samples a circular ring out of a 2D Animartrix grid. @author of fx is "
83 "StefanPetrick");
84
85fl::UIDropdown fxIndex("Animartrix - index", {
86 "RGB_BLOBS5", "RGB_BLOBS4", "RGB_BLOBS3", "RGB_BLOBS2", "RGB_BLOBS",
87 "POLAR_WAVES", "SLOW_FADE", "ZOOM2", "ZOOM", "HOT_BLOB",
88 "SPIRALUS2", "SPIRALUS", "YVES", "SCALEDEMO1", "LAVA1",
89 "CALEIDO3", "CALEIDO2", "CALEIDO1", "DISTANCE_EXPERIMENT", "CENTER_FIELD",
90 "WAVES", "CHASING_SPIRALS", "ROTATING_BLOB", "RINGS", "COMPLEX_KALEIDO",
91 "COMPLEX_KALEIDO_2", "COMPLEX_KALEIDO_3", "COMPLEX_KALEIDO_4", "COMPLEX_KALEIDO_5", "COMPLEX_KALEIDO_6",
92 "WATER", "PARAMETRIC_WATER", "MODULE_EXPERIMENT1", "MODULE_EXPERIMENT2", "MODULE_EXPERIMENT3",
93 "MODULE_EXPERIMENT4", "MODULE_EXPERIMENT5", "MODULE_EXPERIMENT6", "MODULE_EXPERIMENT7", "MODULE_EXPERIMENT8",
94 "MODULE_EXPERIMENT9", "MODULE_EXPERIMENT10", "MODULE_EXPERIMENT_SM1", "MODULE_EXPERIMENT_SM2", "MODULE_EXPERIMENT_SM3",
95 "MODULE_EXPERIMENT_SM4", "MODULE_EXPERIMENT_SM5", "MODULE_EXPERIMENT_SM6", "MODULE_EXPERIMENT_SM8", "MODULE_EXPERIMENT_SM9",
96 "MODULE_EXPERIMENT_SM10", "FLUFFY_BLOBS"
97});
98fl::UISlider timeSpeed("Time Speed", 1, -10, 10, .1);
99fl::UISlider brightness("Brightness", BRIGHTNESS, 0, 255, 1);
100fl::UICheckbox autoBrightness("Auto Brightness", true);
101fl::UISlider autoBrightnessMax("Auto Brightness Max", 84, 0, 255, 1);
102fl::UISlider autoBrightnessLowThreshold("Auto Brightness Low Threshold", 8, 0,
103 100, 1);
104fl::UISlider autoBrightnessHighThreshold("Auto Brightness High Threshold", 22,
105 0, 100, 1);
106
107void setup() {
108 Serial.begin(115200);
109
110 // Setup LED strip
111 FastLED.addLeds<WS2812, PIN_DATA>(leds, NUM_LEDS)
112 .setCorrection(TypicalLEDStrip)
113 .setScreenMap(screenmap);
114 FastLED.setBrightness(brightness.value());
115
116 // Add the 2D-to-1D effect to FxEngine
117 fxEngine.addFx(fx2dTo1d);
118
119 // Dropdown index maps 1:1 onto fl::AnimartrixAnim, so point it at the boot
120 // animation -- otherwise the UI would read "RGB_BLOBS5" (index 0) while
121 // FIRST_ANIMATION was actually rendering. loop() reconciles from there.
122 fxIndex.setSelectedIndex(static_cast<int>(FIRST_ANIMATION));
123
124 Serial.println("AnimartrixRing setup complete");
125}
126
127void loop() {
128 // Poll rather than use onChanged(): a value the web UI restores (persisted
129 // or from the URL) can land before the first frame, where the change
130 // detector absorbs it into its baseline and never fires. Comparing against
131 // the animation we last pushed cannot miss it. Same pattern as
132 // examples/Animartrix/Animartrix.ino.
133 static int sLastFxIndex = -1;
134 if (fxIndex.as_int() != sLastFxIndex) {
135 sLastFxIndex = fxIndex.as_int();
136 animartrix->fxSet(sLastFxIndex);
137 }
138
139 fxEngine.setSpeed(timeSpeed.value());
140
141 // Draw the effect
142 fxEngine.draw(millis(), leds);
143
144 // Calculate final brightness
145 uint8_t finalBrightness;
146 if (autoBrightness.value()) {
147 float avgBri = getAverageBrightness(leds);
148 finalBrightness = applyBrightnessCompression(
149 avgBri, static_cast<uint8_t>(autoBrightnessMax.value()),
152 } else {
153 finalBrightness = static_cast<uint8_t>(brightness.value());
154 }
155
156 FastLED.setBrightness(finalBrightness);
157 FastLED.show();
158}
CRGB leds[1]
fl::FxEngine fxEngine(NUM_LEDS)
#define NUM_LEDS
fl::Animartrix animartrix(xyMap, FIRST_ANIMATION)
#define PIN_DATA
#define LED_DIAMETER
fl::UIDropdown fxIndex("Animartrix - index", { "RGB_BLOBS5", "RGB_BLOBS4", "RGB_BLOBS3", "RGB_BLOBS2", "RGB_BLOBS", "POLAR_WAVES", "SLOW_FADE", "ZOOM2", "ZOOM", "HOT_BLOB", "SPIRALUS2", "SPIRALUS", "YVES", "SCALEDEMO1", "LAVA1", "CALEIDO3", "CALEIDO2", "CALEIDO1", "DISTANCE_EXPERIMENT", "CENTER_FIELD", "WAVES", "CHASING_SPIRALS", "ROTATING_BLOB", "RINGS", "COMPLEX_KALEIDO", "COMPLEX_KALEIDO_2", "COMPLEX_KALEIDO_3", "COMPLEX_KALEIDO_4", "COMPLEX_KALEIDO_5", "COMPLEX_KALEIDO_6", "WATER", "PARAMETRIC_WATER", "MODULE_EXPERIMENT1", "MODULE_EXPERIMENT2", "MODULE_EXPERIMENT3", "MODULE_EXPERIMENT4", "MODULE_EXPERIMENT5", "MODULE_EXPERIMENT6", "MODULE_EXPERIMENT7", "MODULE_EXPERIMENT8", "MODULE_EXPERIMENT9", "MODULE_EXPERIMENT10", "MODULE_EXPERIMENT_SM1", "MODULE_EXPERIMENT_SM2", "MODULE_EXPERIMENT_SM3", "MODULE_EXPERIMENT_SM4", "MODULE_EXPERIMENT_SM5", "MODULE_EXPERIMENT_SM6", "MODULE_EXPERIMENT_SM8", "MODULE_EXPERIMENT_SM9", "MODULE_EXPERIMENT_SM10", "FLUFFY_BLOBS" })
fl::UISlider timeSpeed("Time Speed", 1, -10, 10,.1)
fl::UISlider brightness("Brightness", BRIGHTNESS, 0, 255)
#define BRIGHTNESS
#define FIRST_ANIMATION
uint8_t applyBrightnessCompression(float inputBrightnessPercent, uint8_t maxBrightness, float lowThreshold, float highThreshold)
float getAverageBrightness(fl::span< const CRGB > leds)
fl::ScreenMap makeRingScreenMap(int numLeds, int gridWidth, int gridHeight, float diameter)
fl::FxEngine fxEngine(NUM_LEDS)
void setup()
fl::UISlider brightness("Brightness", BRIGHTNESS, 0, 255, 1)
XYMap xymap
#define GRID_WIDTH
fl::ScreenMap screenmap
#define GRID_HEIGHT
fl::UIDropdown fxIndex("Animartrix - index", { "RGB_BLOBS5", "RGB_BLOBS4", "RGB_BLOBS3", "RGB_BLOBS2", "RGB_BLOBS", "POLAR_WAVES", "SLOW_FADE", "ZOOM2", "ZOOM", "HOT_BLOB", "SPIRALUS2", "SPIRALUS", "YVES", "SCALEDEMO1", "LAVA1", "CALEIDO3", "CALEIDO2", "CALEIDO1", "DISTANCE_EXPERIMENT", "CENTER_FIELD", "WAVES", "CHASING_SPIRALS", "ROTATING_BLOB", "RINGS", "COMPLEX_KALEIDO", "COMPLEX_KALEIDO_2", "COMPLEX_KALEIDO_3", "COMPLEX_KALEIDO_4", "COMPLEX_KALEIDO_5", "COMPLEX_KALEIDO_6", "WATER", "PARAMETRIC_WATER", "MODULE_EXPERIMENT1", "MODULE_EXPERIMENT2", "MODULE_EXPERIMENT3", "MODULE_EXPERIMENT4", "MODULE_EXPERIMENT5", "MODULE_EXPERIMENT6", "MODULE_EXPERIMENT7", "MODULE_EXPERIMENT8", "MODULE_EXPERIMENT9", "MODULE_EXPERIMENT10", "MODULE_EXPERIMENT_SM1", "MODULE_EXPERIMENT_SM2", "MODULE_EXPERIMENT_SM3", "MODULE_EXPERIMENT_SM4", "MODULE_EXPERIMENT_SM5", "MODULE_EXPERIMENT_SM6", "MODULE_EXPERIMENT_SM8", "MODULE_EXPERIMENT_SM9", "MODULE_EXPERIMENT_SM10", "FLUFFY_BLOBS" })
fl::UISlider timeSpeed("Time Speed", 1, -10, 10,.1)
fl::UISlider autoBrightnessLowThreshold("Auto Brightness Low Threshold", 8, 0, 100, 1)
fl::UICheckbox autoBrightness("Auto Brightness", true)
fl::UISlider autoBrightnessHighThreshold("Auto Brightness High Threshold", 22, 0, 100, 1)
fl::UISlider autoBrightnessMax("Auto Brightness Max", 84, 0, 255, 1)
FASTLED_TITLE("AnimartrixRing")
fl::UIDescription description("Samples a circular ring out of a 2D Animartrix grid. @author of fx is " "StefanPetrick")
void loop()
auto fx2dTo1d
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
@ BILINEAR
Bilinear interpolation (smooth)
Definition fx2d_to_1d.h:42
Manages and renders multiple visual effects (Fx) for LED strips.
Definition fx_engine.h:33
@ TypicalLEDStrip
Typical values for SMD5050 LEDs.
Definition color.h:15
fl::CRGB CRGB
Definition crgb.h:25
shared_ptr< T > make_shared(Args &&... args) FL_NO_EXCEPT
Definition shared_ptr.h:423
#define Serial
Definition serial.h:309
Aggregator header for the fl/ui/ family of per-element UI types.