FastLED 3.9.15
Loading...
Searching...
No Matches
FxWave2d.ino
Go to the documentation of this file.
1
2
3/*
4This demo is best viewed using the FastLED compiler.
5Install: pip install fastled
6Run: fastled <this sketch directory>
7This will compile and preview the sketch in the browser, and enable
8all the UI elements you see below.
9*/
10
11#include <Arduino.h>
12#include <FastLED.h>
13
14#include "fl/math_macros.h"
15#include "fl/time_alpha.h"
16#include "fl/ui.h"
17#include "fx/2d/blend.h"
18#include "fx/2d/wave.h"
19
20using namespace fl;
21
22#define HEIGHT 64
23#define WIDTH 64
24#define NUM_LEDS ((WIDTH) * (HEIGHT))
25#define IS_SERPINTINE true
26
28
29UITitle title("FxWave2D Demo");
30UIDescription description("Advanced layered and blended wave effects.");
31
32UIButton button("Trigger");
33UIButton buttonFancy("Trigger Fancy");
34UICheckbox autoTrigger("Auto Trigger", true);
35UISlider triggerSpeed("Trigger Speed", .5f, 0.0f, 1.0f, 0.01f);
36UICheckbox easeModeSqrt("Ease Mode Sqrt", false);
37UISlider blurAmount("Global Blur Amount", 0, 0, 172, 1);
38UISlider blurPasses("Global Blur Passes", 1, 1, 10, 1);
39UISlider superSample("SuperSampleExponent", 1.f, 0.f, 3.f, 1.f);
40
41UISlider speedUpper("Wave Upper: Speed", 0.12f, 0.0f, 1.0f);
42UISlider dampeningUpper("Wave Upper: Dampening", 8.9f, 0.0f, 20.0f, 0.1f);
43UICheckbox halfDuplexUpper("Wave Upper: Half Duplex", true);
44UISlider blurAmountUpper("Wave Upper: Blur Amount", 95, 0, 172, 1);
45UISlider blurPassesUpper("Wave Upper: Blur Passes", 1, 1, 10, 1);
46
47UISlider speedLower("Wave Lower: Speed", 0.26f, 0.0f, 1.0f);
48UISlider dampeningLower("Wave Lower: Dampening", 9.0f, 0.0f, 20.0f, 0.1f);
49UICheckbox halfDuplexLower("Wave Lower: Half Duplex", true);
50UISlider blurAmountLower("Wave Lower: Blur Amount", 0, 0, 172, 1);
51UISlider blurPassesLower("Wave Lower: Blur Passes", 1, 1, 10, 1);
52
53UISlider fancySpeed("Fancy Speed", 796, 0, 1000, 1);
54UISlider fancyIntensity("Fancy Intensity", 32, 1, 255, 1);
55UISlider fancyParticleSpan("Fancy Particle Span", 0.06f, 0.01f, 0.2f, 0.01f);
56
57
58DEFINE_GRADIENT_PALETTE(electricBlueFirePal){
59 0, 0, 0, 0, // Black
60 32, 0, 0, 70, // Dark blue
61 128, 20, 57, 255, // Electric blue
62 255, 255, 255, 255 // White
63};
64
65DEFINE_GRADIENT_PALETTE(electricGreenFirePal){
66 0, 0, 0, 0, // black
67 8, 128, 64, 64, // green
68 16, 255, 222, 222, // red
69 64, 255, 255, 255, // white
70 255, 255, 255, 255 // white
71};
72
78 .factor = SUPER_SAMPLE_4X,
79 .half_duplex = true,
80 .speed = 0.18f,
81 .dampening = 9.0f,
82 .crgbMap = WaveCrgbGradientMapPtr::New(electricBlueFirePal),
83 });
84
87 .factor = SUPER_SAMPLE_4X,
88 .half_duplex = true,
89 .speed = 0.25f,
90 .dampening = 3.0f,
91 .crgbMap = WaveCrgbGradientMapPtr::New(electricGreenFirePal),
92 });
93
95
96void setup() {
97 Serial.begin(115200);
98 auto screenmap = xyMap.toScreenMap();
99 screenmap.setDiameter(.2);
100 FastLED.addLeds<NEOPIXEL, 2>(leds, NUM_LEDS).setScreenMap(screenmap);
101 fxBlend.add(waveFxLower);
102 fxBlend.add(waveFxUpper);
103}
104
106 switch (int(superSample)) {
107 case 0:
109 case 1:
111 case 2:
113 case 3:
115 default:
117 }
118}
119
121 float perc = .15f;
122 uint8_t min_x = perc * WIDTH;
123 uint8_t max_x = (1 - perc) * WIDTH;
124 uint8_t min_y = perc * HEIGHT;
125 uint8_t max_y = (1 - perc) * HEIGHT;
126 int x = random(min_x, max_x);
127 int y = random(min_y, max_y);
128 waveFxLower.setf(x, y, 1);
129 waveFxUpper.setf(x, y, 1);
130}
131
132void applyFancyEffect(uint32_t now, bool button_active) {
133 uint32_t total = map(fancySpeed.as<uint32_t>(), 0, fancySpeed.max_value(), 1000, 100);
134 static TimeRamp pointTransition = TimeRamp(total, 0, 0);
135
136 if (button_active) {
137 pointTransition.trigger(now, total, 0, 0);
138 }
139
140 if (!pointTransition.isActive(now)) {
141 // no need to draw
142 return;
143 }
144 int mid_x = WIDTH / 2;
145 int mid_y = HEIGHT / 2;
146 // now make a cross
147 int amount = WIDTH / 2;
148 int start_x = mid_x - amount;
149 int end_x = mid_x + amount;
150 int start_y = mid_y - amount;
151 int end_y = mid_y + amount;
152 int curr_alpha = pointTransition.update(now);
153 int left_x = map(curr_alpha, 0, 255, mid_x, start_x);
154 int down_y = map(curr_alpha, 0, 255, mid_y, start_y);
155 int right_x = map(curr_alpha, 0, 255, mid_x, end_x);
156 int up_y = map(curr_alpha, 0, 255, mid_y, end_y);
157
158 float curr_alpha_f = curr_alpha / 255.0f;
159
160 float valuef = (1.0f - curr_alpha_f) * fancyIntensity.value() / 255.0f;
161
162 int span = fancyParticleSpan.value() * WIDTH;
163 for (int x = left_x - span; x < left_x + span; x++) {
164 waveFxLower.addf(x, mid_y, valuef);
165 waveFxUpper.addf(x, mid_y, valuef);
166 }
167
168 for (int x = right_x - span; x < right_x + span; x++) {
169 waveFxLower.addf(x, mid_y, valuef);
170 waveFxUpper.addf(x, mid_y, valuef);
171 }
172
173 for (int y = down_y - span; y < down_y + span; y++) {
174 waveFxLower.addf(mid_x, y, valuef);
175 waveFxUpper.addf(mid_x, y, valuef);
176 }
177
178 for (int y = up_y - span; y < up_y + span; y++) {
179 waveFxLower.addf(mid_x, y, valuef);
180 waveFxUpper.addf(mid_x, y, valuef);
181 }
182}
183
184struct ui_state {
185 bool button = false;
186 bool bigButton = false;
187};
188
193 waveFxLower.setSpeed(speedLower);
194 waveFxLower.setDampening(dampeningLower);
195 waveFxLower.setHalfDuplex(halfDuplexLower);
196 waveFxLower.setSuperSample(getSuperSample());
197 waveFxLower.setEasingMode(easeMode);
198
199 waveFxUpper.setSpeed(speedUpper);
200 waveFxUpper.setDampening(dampeningUpper);
201 waveFxUpper.setHalfDuplex(halfDuplexUpper);
202 waveFxUpper.setSuperSample(getSuperSample());
203 waveFxUpper.setEasingMode(easeMode);
204 fxBlend.setGlobalBlurAmount(blurAmount);
205 fxBlend.setGlobalBlurPasses(blurPasses);
206
207 Blend2dParams lower_params = {
208 .blur_amount = blurAmountLower,
209 .blur_passes = blurPassesLower,
210 };
211
212 Blend2dParams upper_params = {
213 .blur_amount = blurAmountUpper,
214 .blur_passes = blurPassesUpper,
215 };
216
217 fxBlend.setParams(waveFxLower, lower_params);
218 fxBlend.setParams(waveFxUpper, upper_params);
219 ui_state state{
220 .button = button,
221 .bigButton = buttonFancy,
222 };
223 return state;
224}
225
226void processAutoTrigger(uint32_t now) {
227 static uint32_t nextTrigger = 0;
228 uint32_t trigger_delta = nextTrigger - now;
229 if (trigger_delta > 10000) {
230 // rolled over!
231 trigger_delta = 0;
232 }
233 if (autoTrigger) {
234 if (now >= nextTrigger) {
236 float speed = 1.0f - triggerSpeed.value();
237 uint32_t min_rand = 400 * speed;
238 uint32_t max_rand = 2000 * speed;
239
240 uint32_t min = MIN(min_rand, max_rand);
241 uint32_t max = MAX(min_rand, max_rand);
242 if (min == max) {
243 max += 1;
244 }
245 nextTrigger = now + random(min, max);
246 }
247 }
248}
249
250void loop() {
251 // Your code here
252 uint32_t now = millis();
253 ui_state state = ui();
254 if (state.button) {
256 }
257 applyFancyEffect(now, state.bigButton);
259 Fx::DrawContext ctx(now, leds);
260 fxBlend.draw(ctx);
261 FastLED.show();
262}
CRGB leds[NUM_LEDS]
Definition Apa102.ino:11
#define NUM_LEDS
Definition Apa102.ino:6
#define WIDTH
Definition Blur2d.ino:9
#define HEIGHT
Definition Blur2d.ino:10
CFastLED FastLED
Global LED strip management instance.
Definition FastLED.cpp:58
central include file for FastLED, defines the CFastLED class/object
uint32_t x[NUM_LAYERS]
Definition Fire2023.ino:80
uint32_t y[NUM_LAYERS]
Definition Fire2023.ino:81
XYMap xyMap(HEIGHT, WIDTH, SERPENTINE)
#define IS_SERPINTINE
Definition FxEngine.ino:35
UISlider blurAmount("Global Blur Amount", 0, 0, 172, 1)
XYMap xyMap(WIDTH, HEIGHT, IS_SERPINTINE)
UISlider blurPassesLower("Wave Lower: Blur Passes", 1, 1, 10, 1)
UISlider blurPasses("Global Blur Passes", 1, 1, 10, 1)
Blend2d fxBlend(xyMap)
ui_state ui()
Definition FxWave2d.ino:189
UISlider blurAmountLower("Wave Lower: Blur Amount", 0, 0, 172, 1)
UISlider speedLower("Wave Lower: Speed", 0.26f, 0.0f, 1.0f)
UISlider blurPassesUpper("Wave Upper: Blur Passes", 1, 1, 10, 1)
WaveFx waveFxLower(xyRect, WaveFx::Args{ .factor=SUPER_SAMPLE_4X,.half_duplex=true,.speed=0.18f,.dampening=9.0f,.crgbMap=WaveCrgbGradientMapPtr::New(electricBlueFirePal), })
UISlider fancyParticleSpan("Fancy Particle Span", 0.06f, 0.01f, 0.2f, 0.01f)
UICheckbox autoTrigger("Auto Trigger", true)
void setup()
Definition FxWave2d.ino:96
UICheckbox halfDuplexUpper("Wave Upper: Half Duplex", true)
UISlider speedUpper("Wave Upper: Speed", 0.12f, 0.0f, 1.0f)
UITitle title("FxWave2D Demo")
WaveFx waveFxUpper(xyRect, WaveFx::Args{ .factor=SUPER_SAMPLE_4X,.half_duplex=true,.speed=0.25f,.dampening=3.0f,.crgbMap=WaveCrgbGradientMapPtr::New(electricGreenFirePal), })
void processAutoTrigger(uint32_t now)
Definition FxWave2d.ino:226
UIButton button("Trigger")
UISlider fancySpeed("Fancy Speed", 796, 0, 1000, 1)
XYMap xyRect(WIDTH, HEIGHT, false)
UISlider dampeningUpper("Wave Upper: Dampening", 8.9f, 0.0f, 20.0f, 0.1f)
UICheckbox easeModeSqrt("Ease Mode Sqrt", false)
UIButton buttonFancy("Trigger Fancy")
UISlider fancyIntensity("Fancy Intensity", 32, 1, 255, 1)
UISlider triggerSpeed("Trigger Speed",.5f, 0.0f, 1.0f, 0.01f)
UIDescription description("Advanced layered and blended wave effects.")
UISlider blurAmountUpper("Wave Upper: Blur Amount", 95, 0, 172, 1)
SuperSample getSuperSample()
Definition FxWave2d.ino:105
void triggerRipple()
Definition FxWave2d.ino:120
UISlider superSample("SuperSampleExponent", 1.f, 0.f, 3.f, 1.f)
void applyFancyEffect(uint32_t now, bool button_active)
Definition FxWave2d.ino:132
UISlider dampeningLower("Wave Lower: Dampening", 9.0f, 0.0f, 20.0f, 0.1f)
UICheckbox halfDuplexLower("Wave Lower: Half Duplex", true)
void loop()
Definition FxWave2d.ino:250
uint16_t speed
Definition Noise.ino:63
LED controller for WS2812 LEDs with GRB color order.
Definition FastLED.h:138
_DrawContext DrawContext
Definition fx.h:21
uint8_t update(uint32_t now) override
Compute current 0–255 output based on how much time has elapsed since trigger().
bool isActive(uint32_t now) const override
void trigger(uint32_t now) override
Call this when you want to (re)start the ramp cycle.
WaveFxArgs Args
Definition wave.h:78
#define DEFINE_GRADIENT_PALETTE(X)
Defines a static RGB palette very compactly using a series of connected color gradients.
Definition colorutils.h:69
#define MIN(a, b)
Definition math_macros.h:8
#define MAX(a, b)
Definition math_macros.h:4
U8EasingFunction
@ WAVE_U8_MODE_LINEAR
@ WAVE_U8_MODE_SQRT
SuperSample
Definition supersample.h:4
@ SUPER_SAMPLE_8X
Definition supersample.h:8
@ SUPER_SAMPLE_2X
Definition supersample.h:6
@ SUPER_SAMPLE_4X
Definition supersample.h:7
@ SUPER_SAMPLE_NONE
Definition supersample.h:5
Implements a simple red square effect for 2D LED grids.
Definition crgb.h:16
Representation of an RGB pixel (Red, Green, Blue)
Definition crgb.h:54
bool bigButton
Definition FxWave2d.ino:186
bool button
Definition FxWave2d.ino:185
ui_state()
Definition ui_state.h:12