FastLED 3.9.15
Loading...
Searching...
No Matches
FireCylinder.h
Go to the documentation of this file.
1
2/*
3This demo is best viewed using the FastLED compiler.
4
5Windows/MacOS binaries: https://github.com/FastLED/FastLED/releases
6
7Python
8
9Install: pip install fastled
10Run: fastled <this sketch directory>
11This will compile and preview the sketch in the browser, and enable
12all the UI elements you see below.
13
14OVERVIEW:
15This sketch creates a fire effect on a cylindrical LED display using Perlin noise.
16Unlike a flat matrix, this cylinder connects the left and right edges (x=0 and x=width-1),
17creating a seamless wrap-around effect. The fire appears to rise from the bottom,
18with colors transitioning from black to red/yellow/white (or other palettes).
19*/
20
21// Perlin noise fire procedure
22// 16x16 rgb led cylinder demo
23// Exactly the same as the FireMatrix example, but with a cylinder, meaning that the x=0
24// and x = len-1 are connected.
25// This also showcases the inoise16(x,y,z,t) function which handles 3D+time noise effects.
26// Keep in mind that a cylinder is embedded in a 3D space with time being used to add
27// additional noise to the effect.
28
29// HOW THE CYLINDRICAL FIRE EFFECT WORKS:
30// 1. We use sine and cosine to map the x-coordinate to a circle in 3D space
31// 2. This creates a cylindrical mapping where the left and right edges connect seamlessly
32// 3. We use 4D Perlin noise (x,y,z,t) to generate natural-looking fire patterns
33// 4. The height coordinate controls color fade-out to create the rising fire effect
34// 5. The time dimension adds continuous variation to make the fire look dynamic
35
36#include "FastLED.h" // Main FastLED library for controlling LEDs
37#include "fl/ui.h" // UI components for the FastLED web compiler (sliders, buttons, etc.)
38#include "fl/xymap.h" // Mapping between 1D LED array and 2D coordinates
39#include "fx/time.h" // Time manipulation utilities for animations
40
41using namespace fl; // Use the FastLED namespace for convenience
42
43// Cylinder dimensions - this defines the size of our virtual LED grid
44#define HEIGHT 100 // Number of rows in the cylinder (vertical dimension)
45#define WIDTH 100 // Number of columns in the cylinder (circumference)
46#define SERPENTINE true // Whether the LED strip zigzags back and forth (common in matrix layouts)
47#define BRIGHTNESS 255 // Maximum brightness level (0-255)
48
49// UI elements that appear in the FastLED web compiler interface:
50UITitle title("FireCylinder Demo"); // Title displayed in the UI
51UIDescription description("This Fire demo wraps around the cylinder. It uses Perlin noise to create a fire effect.");
52
53// TimeWarp helps control animation speed - it tracks time and allows speed adjustments
54TimeWarp timeScale(0, 1.0f); // Initialize with 0 starting time and 1.0 speed multiplier
55
56// UI Controls for adjusting the fire effect:
57UISlider scaleXY("Scale", 8, 1, 100, 1); // Controls the overall size of the fire pattern
58UISlider speedY("SpeedY", 1.3, 1, 6, .1); // Controls how fast the fire moves upward
59UISlider scaleX("ScaleX", .3, 0.1, 3, .01); // Controls the horizontal scale (affects the wrap-around)
60UISlider invSpeedZ("Inverse SpeedZ", 20, 1, 100, 1); // Controls how fast the fire pattern changes over time (higher = slower)
61UISlider brightness("Brightness", 255, 0, 255, 1); // Controls overall brightness
62UINumberField palette("Palette", 0, 0, 2); // Selects which color palette to use (0=fire, 1=green, 2=blue)
63
64// Array to hold all LED color values - one CRGB struct per LED
66
67// Color palettes define the gradient of colors used for the fire effect
68// Each entry has the format: position (0-255), R, G, B
69
71 // Traditional fire palette - transitions from black to red to yellow to white
72 0, 0, 0, 0, // black (bottom of fire)
73 32, 255, 0, 0, // red (base of flames)
74 190, 255, 255, 0, // yellow (middle of flames)
75 255, 255, 255, 255 // white (hottest part/tips of flames)
76};
77
78DEFINE_GRADIENT_PALETTE(electricGreenFirePal){
79 // Green fire palette - for a toxic/alien look
80 0, 0, 0, 0, // black (bottom)
81 32, 0, 70, 0, // dark green (base)
82 190, 57, 255, 20, // electric neon green (middle)
83 255, 255, 255, 255 // white (hottest part)
84};
85
86DEFINE_GRADIENT_PALETTE(electricBlueFirePal){
87 // Blue fire palette - for a cold/ice fire look
88 0, 0, 0, 0, // Black (bottom)
89 32, 0, 0, 70, // Dark blue (base)
90 128, 20, 57, 255, // Electric blue (middle)
91 255, 255, 255, 255 // White (hottest part)
92};
93
94// Create a mapping between 1D array positions and 2D x,y coordinates
96
97void setup() {
98 Serial.begin(115200); // Initialize serial communication for debugging
99
100 // Initialize the LED strip:
101 // - NEOPIXEL is the LED type
102 // - 3 is the data pin number (for real hardware)
103 // - setScreenMap connects our 2D coordinate system to the 1D LED array
104 fl::ScreenMap screen_map = xyMap.toScreenMap();
105 screen_map.setDiameter(0.1f); // Set the diameter for the cylinder (0.2 cm per LED)
106 FastLED.addLeds<NEOPIXEL, 3>(leds, HEIGHT * WIDTH).setScreenMap(screen_map);
107
108 // Apply color correction for more accurate colors on LED strips
109 FastLED.setCorrection(TypicalLEDStrip);
110}
111
112uint8_t getPaletteIndex(uint32_t millis32, int width, int max_width, int height, int max_height,
113 uint32_t y_speed) {
114 // This function calculates which color to use from our palette for each LED
115
116 // Get the scale factor from the UI slider
117 uint16_t scale = scaleXY.as<uint16_t>();
118
119 // Convert width position to an angle (0-255 represents 0-360 degrees)
120 // This maps our flat coordinate to a position on a cylinder
121 float xf = (float)width / (float)max_width; // Normalized position (0.0 to 1.0)
122 uint8_t x = (uint8_t)(xf * 255); // Convert to 0-255 range for trig functions
123
124 // Calculate the sine and cosine of this angle to get 3D coordinates on the cylinder
125 uint32_t cosx = cos8(x); // cos8 returns a value 0-255 representing cosine
126 uint32_t sinx = sin8(x); // sin8 returns a value 0-255 representing sine
127
128 // Apply scaling to the sine/cosine values
129 // This controls how "wide" the noise pattern is around the cylinder
130 float trig_scale = scale * scaleX.value();
131 cosx *= trig_scale;
132 sinx *= trig_scale;
133
134 // Calculate Y coordinate (vertical position) with speed offset for movement
135 uint32_t y = height * scale + y_speed;
136
137 // Calculate Z coordinate (time dimension) - controls how the pattern changes over time
138 uint16_t z = millis32 / invSpeedZ.as<uint16_t>();
139
140 // Generate 16-bit Perlin noise using our 4D coordinates (x,y,z,t)
141 // The << 8 shifts values left by 8 bits (multiplies by 256) to use the full 16-bit range
142 // The last parameter (0) could be replaced with another time variable for more variation
143 uint16_t noise16 = inoise16(cosx << 8, sinx << 8, y << 8, 0);
144
145 // Convert 16-bit noise to 8-bit by taking the high byte
146 uint8_t noise_val = noise16 >> 8;
147
148 // Calculate how much to subtract based on vertical position (height)
149 // This creates the fade-out effect from bottom to top
150 // The formula maps height from 0 to max_height-1 to a value from 255 to 0
151 int8_t subtraction_factor = abs8(height - (max_height - 1)) * 255 /
152 (max_height - 1);
153
154 // Subtract the factor from the noise value (with underflow protection)
155 // qsub8 is a "saturating subtraction" - it won't go below 0
156 return qsub8(noise_val, subtraction_factor);
157}
158CRGBPalette16 getPalette() {
159 // This function returns the appropriate color palette based on the UI selection
160 switch (palette) {
161 case 0:
162 return firepal; // Traditional orange/red fire
163 case 1:
164 return electricGreenFirePal; // Green "toxic" fire
165 case 2:
166 return electricBlueFirePal; // Blue "cold" fire
167 default:
168 return firepal; // Default to traditional fire if invalid value
169 }
170}
171
172void loop() {
173 // The main program loop that runs continuously
174
175 // Set the overall brightness from the UI slider
176 FastLED.setBrightness(brightness);
177
178 // Get the selected color palette
179 CRGBPalette16 myPal = getPalette();
180
181 // Get the current time in milliseconds
182 uint32_t now = millis();
183
184 // Update the animation speed from the UI slider
185 timeScale.setSpeed(speedY);
186
187 // Calculate the current y-offset for animation (makes the fire move)
188 uint32_t y_speed = timeScale.update(now);
189
190 // Loop through every LED in our cylindrical matrix
191 for (int width = 0; width < WIDTH; width++) {
192 for (int height = 0; height < HEIGHT; height++) {
193 // Calculate which color to use from our palette for this LED
194 // This function handles the cylindrical mapping using sine/cosine
195 uint8_t palette_index =
196 getPaletteIndex(now, width, WIDTH, height, HEIGHT, y_speed);
197
198 // Get the actual RGB color from the palette
199 // BRIGHTNESS ensures we use the full brightness range
200 CRGB c = ColorFromPalette(myPal, palette_index, BRIGHTNESS);
201
202 // Convert our 2D coordinates to the 1D array index
203 // We use (WIDTH-1)-width and (HEIGHT-1)-height to flip the coordinates
204 // This makes the fire appear to rise from the bottom
205 int index = xyMap((WIDTH - 1) - width, (HEIGHT - 1) - height);
206
207 // Set the LED color in our array
208 leds[index] = c;
209 }
210 }
211
212 // Send the color data to the actual LEDs
213 FastLED.show();
214}
CRGB leds[NUM_LEDS]
Definition Apa102.ino:11
#define SERPENTINE
Definition Blur2d.ino:16
#define WIDTH
Definition Blur2d.ino:9
#define HEIGHT
Definition Blur2d.ino:10
#define BRIGHTNESS
Definition Blur.ino:8
UITitle title("Chromancer")
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
Definition FastLED.cpp:62
central include file for FastLED, defines the CFastLED class/object
uint32_t z[NUM_LAYERS]
Definition Fire2023.ino:84
uint32_t x[NUM_LAYERS]
Definition Fire2023.ino:82
uint32_t y[NUM_LAYERS]
Definition Fire2023.ino:83
CRGBPalette16 getPalette()
TimeWarp timeScale(0, 1.0f)
UINumberField palette("Palette", 0, 0, 2)
void setup()
uint8_t getPaletteIndex(uint32_t millis32, int width, int max_width, int height, int max_height, uint32_t y_speed)
UISlider scaleXY("Scale", 8, 1, 100, 1)
UISlider speedY("SpeedY", 1.3, 1, 6,.1)
UISlider invSpeedZ("Inverse SpeedZ", 20, 1, 100, 1)
UISlider scaleX("ScaleX",.3, 0.1, 3,.01)
void loop()
UISlider brightness("Brightness", 1, 0, 1)
int y_speed
LED controller for WS2812 LEDs with GRB color order.
Definition FastLED.h:155
void setDiameter(float diameter)
#define DEFINE_GRADIENT_PALETTE(X)
Defines a static RGB palette very compactly using a series of connected color gradients.
Definition colorutils.h:112
uint16_t scale
Definition funky.cpp:83
XYMap xyMap
Definition gfx.cpp:8
@ TypicalLEDStrip
Typical values for SMD5050 LEDs.
Definition color.h:19
LIB8STATIC_ALWAYS_INLINE int8_t abs8(int8_t i)
Take the absolute value of a signed 8-bit uint8_t.
Definition math8.h:500
LIB8STATIC_ALWAYS_INLINE uint8_t qsub8(uint8_t i, uint8_t j)
Subtract one byte from another, saturating at 0x00.
Definition math8.h:103
uint16_t inoise16(uint32_t x, uint32_t y, uint32_t z, uint32_t t)
16-bit, fixed point implementation of Perlin's noise.
Definition noise.cpp:440
LIB8STATIC uint8_t cos8(uint8_t theta)
Fast 8-bit approximation of cos(x).
Definition trig8.h:271
#define sin8
Platform-independent alias of the fast sin implementation.
Definition trig8.h:221
CRGB ColorFromPalette(const CRGBPalette16 &pal, uint8_t index, uint8_t brightness, TBlendType blendType)
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:55
UIDescription description("Advanced layered and blended wave effects.")