FastLED 3.9.15
Loading...
Searching...
No Matches
Fire2023.h
Go to the documentation of this file.
1
10
11/*This is a fire effect based on the famous Fire2012; but with various small improvements.
12Perlin noise is being used to make a fire layer and a smoke layer;
13and the overlay of both can make a quite realistic effect.
14
15The speed of both need to be adapted to the matrix size and width:
16* Super small matrices (like 3x3 led) don't need the smoke
17* medium sized matrices (8x8 for example) profit from fine tuning both Fire Speed/scale as well as Smoke speed/scale
18
19This code was adapted for a matrix with just four LED columns in 90° around a core and a height of 28.
20
21Right at the bottom of the code, you find a translation matrix that needs to be adapted to your set up. I included
22a link to a helpful page for this.
23
24@repo https://github.com/Anderas2/Fire2023
25@author https://github.com/Anderas2
26
27Demo: https://www.youtube.com/shorts/a_Wr0q9YQs4
28*/
29
30
31#include "FastLED.h"
32#include "fl/xymap.h"
33#include "fl/screenmap.h"
34#include "fl/vector.h"
35
36using namespace fl;
37
38
39// matrix size
40#define WIDTH 4
41#define HEIGHT 28
42#define CentreX (WIDTH / 2) - 1
43#define CentreY (HEIGHT / 2) - 1
44
45// NUM_LEDS = WIDTH * HEIGHT
46#define PIXELPIN 3 // universal pin that works on all platforms
47#define NUM_LEDS 120
48#define LAST_VISIBLE_LED 119
49
50
51// Fire properties
52#define BRIGHTNESS 255
53#define FIRESPEED 17
54#define FLAMEHEIGHT 3.8 // the higher the value, the higher the flame
55#define FIRENOISESCALE 125 // small values, softer fire. Big values, blink fire. 0-255
56
57// Smoke screen properties
58// The smoke screen works best for big fire effects. It effectively cuts of a part of the flames
59// from the rest, sometimes; which looks very much fire-like. For small fire effects with low
60// LED count in the height, it doesn't help
61// speed must be a little different and faster from Firespeed, to be visible.
62// Dimmer should be somewhere in the middle for big fires, and low for small fires.
63#define SMOKESPEED 25 // how fast the perlin noise is parsed for the smoke
64#define SMOKENOISE_DIMMER 250 // thickness of smoke: the lower the value, the brighter the flames. 0-255
65#define SMOKENOISESCALE 125 // small values, softer smoke. Big values, blink smoke. 0-255
66
68
69// fire palette roughly like matlab "hot" colormap
70// This was one of the most important parts to improve - fire color makes fire impression.
71// position, r, g, b value.
72// max value for "position" is BRIGHTNESS
74 27, 0, 0, 0, // black
75 28, 140, 40, 0, // red
76 30, 205, 80, 0, // orange
77 155, 255, 100, 0,
78 210, 255, 200, 0, // yellow
79 255, 255, 255, 255 // white
80};
81CRGBPalette32 hotPalette = hot_gp;
82
83// Map XY coordinates to numbers on the LED strip
84uint8_t XY (uint8_t x, uint8_t y);
85
86
87// parameters and buffer for the noise array
88#define NUM_LAYERS 2
89// two layers of perlin noise make the fire effect
90#define FIRENOISE 0
91#define SMOKENOISE 1
92uint32_t x[NUM_LAYERS];
93uint32_t y[NUM_LAYERS];
94uint32_t z[NUM_LAYERS];
97
100
101uint8_t heat[NUM_LEDS];
102
103
105
106void setup() {
107
108 //Serial.begin(115200);
109 // Adjust this for you own setup. Use the hardware SPI pins if possible.
110 // On Teensy 3.1/3.2 the pins are 11 & 13
111 // Details here: https://github.com/FastLED/FastLED/wiki/SPI-Hardware-or-Bit-banging
112 // In case you see flickering / glitching leds, reduce the data rate to 12 MHZ or less
113 auto screenMap = makeScreenMap();
114 FastLED.addLeds<NEOPIXEL, PIXELPIN>(leds, NUM_LEDS).setScreenMap(screenMap); // Pin für Neopixel
115 FastLED.setBrightness(BRIGHTNESS);
116 FastLED.setDither(DISABLE_DITHER);
117}
118
119void Fire2023(uint32_t now);
120
121void loop() {
123 Fire2023(millis());
124 }
125 FastLED.show();
126}
127
130 for (uint16_t y = 0; y < WIDTH; y++) {
131 for (uint16_t x = 0; x < HEIGHT; x++) {
132 vec2f xy = {float(x) * 3, float(y) * 20};
133 lut.push_back(xy);
134 }
135 }
136 return ScreenMap(lut.data(), lut.size(), 1);
137}
138
139void Fire2023(uint32_t now) {
140 // some changing values
141 // these values are produced by perlin noise to add randomness and smooth transitions
142 uint16_t ctrl1 = inoise16(11 * now, 0, 0);
143 uint16_t ctrl2 = inoise16(13 * now, 100000, 100000);
144 uint16_t ctrl = ((ctrl1 + ctrl2) >> 1);
145
146 // parameters for the fire heat map
147 x[FIRENOISE] = 3 * ctrl * FIRESPEED;
148 y[FIRENOISE] = 20 * now * FIRESPEED;
149 z[FIRENOISE] = 5 * now * FIRESPEED;
152
153 //calculate the perlin noise data for the fire
154 for (uint8_t x_count = 0; x_count < WIDTH; x_count++) {
155 uint32_t xoffset = scale_x[FIRENOISE] * (x_count - CentreX);
156 for (uint8_t y_count = 0; y_count < HEIGHT; y_count++) {
157 uint32_t yoffset = scale_y[FIRENOISE] * (y_count - CentreY);
158 uint16_t data = ((inoise16(x[FIRENOISE] + xoffset, y[FIRENOISE] + yoffset, z[FIRENOISE])) + 1);
159 noise[FIRENOISE][x_count][y_count] = data >> 8;
160 }
161 }
162
163 // parameters for the smoke map
164 x[SMOKENOISE] = 3 * ctrl * SMOKESPEED;
165 y[SMOKENOISE] = 20 * now * SMOKESPEED;
166 z[SMOKENOISE] = 5 * now * SMOKESPEED;
169
170 //calculate the perlin noise data for the smoke
171 for (uint8_t x_count = 0; x_count < WIDTH; x_count++) {
172 uint32_t xoffset = scale_x[SMOKENOISE] * (x_count - CentreX);
173 for (uint8_t y_count = 0; y_count < HEIGHT; y_count++) {
174 uint32_t yoffset = scale_y[SMOKENOISE] * (y_count - CentreY);
175 uint16_t data = ((inoise16(x[SMOKENOISE] + xoffset, y[SMOKENOISE] + yoffset, z[SMOKENOISE])) + 1);
176 noise[SMOKENOISE][x_count][y_count] = data / SMOKENOISE_DIMMER;
177 }
178 }
179
180 //copy everything one line up
181 for (uint8_t y = 0; y < HEIGHT - 1; y++) {
182 for (uint8_t x = 0; x < WIDTH; x++) {
183 heat[XY(x, y)] = heat[XY(x, y + 1)];
184 }
185 }
186
187 // draw lowest line - seed the fire where it is brightest and hottest
188 for (uint8_t x = 0; x < WIDTH; x++) {
190 //if (heat[XY(x, HEIGHT-1)] < 200) heat[XY(x, HEIGHT-1)] = 150;
191 }
192
193 // dim the flames based on FIRENOISE noise.
194 // if the FIRENOISE noise is strong, the led goes out fast
195 // if the FIRENOISE noise is weak, the led stays on stronger.
196 // once the heat is gone, it stays dark.
197 for (uint8_t y = 0; y < HEIGHT - 1; y++) {
198 for (uint8_t x = 0; x < WIDTH; x++) {
199 uint8_t dim = noise[FIRENOISE][x][y];
200 // high value in FLAMEHEIGHT = less dimming = high flames
201 dim = dim / FLAMEHEIGHT;
202 dim = 255 - dim;
203 heat[XY(x, y)] = scale8(heat[XY(x, y)] , dim);
204
205 // map the colors based on heatmap
206 // use the heat map to set the color of the LED from the "hot" palette
207 // whichpalette position brightness blend or not
208 leds[XY(x, y)] = ColorFromPalette(hotPalette, heat[XY(x, y)], heat[XY(x, y)], LINEARBLEND);
209
210 // dim the result based on SMOKENOISE noise
211 // this is not saved in the heat map - the flame may dim away and come back
212 // next iteration.
213 leds[XY(x, y)].nscale8(noise[SMOKENOISE][x][y]);
214
215 }
216 }
217}
218
219/* Physical layout of LED strip ****************************/
220uint8_t XY (uint8_t x, uint8_t y) {
221 // any out of bounds address maps to the first hidden pixel
222 // https://macetech.github.io/FastLED-XY-Map-Generator/
223 if ( (x >= WIDTH) || (y >= HEIGHT) ) {
224 return (LAST_VISIBLE_LED + 1);
225 }
226 const uint8_t XYTable[] = {
227 25, 26, 81, 82,
228 25, 27, 81, 83,
229 25, 28, 80, 84,
230 24, 29, 79, 85,
231 23, 30, 78, 86,
232 22, 31, 77, 87,
233 21, 32, 76, 88,
234 20, 33, 75, 89,
235 19, 34, 74, 90,
236 18, 35, 73, 91,
237 17, 36, 72, 92,
238 16, 37, 71, 93,
239 15, 38, 70, 94,
240 14, 39, 69, 95,
241 13, 40, 68, 96,
242 12, 41, 67, 97,
243 11, 42, 66, 98,
244 10, 43, 65, 99,
245 9, 44, 64, 100,
246 8, 45, 63, 101,
247 7, 46, 62, 102,
248 6, 47, 61, 103,
249 5, 48, 60, 104,
250 4, 49, 59, 105,
251 3, 50, 58, 106,
252 2, 51, 57, 107,
253 1, 52, 56, 108,
254 0, 53, 55, 109
255 };
256
257 uint8_t i = (y * WIDTH) + x;
258 uint8_t j = XYTable[i];
259 return j;
260}
261
262
CRGB leds[NUM_LEDS]
#define NUM_LEDS
int y
Definition simple.h:93
int x
Definition simple.h:92
#define BRIGHTNESS
Definition Blur.ino:8
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
Definition FastLED.cpp:74
central include file for FastLED, defines the CFastLED class/object
#define SMOKENOISE
Definition Fire2023.h:91
uint8_t noise[NUM_LAYERS][WIDTH][HEIGHT]
Definition Fire2023.h:98
#define CentreX
Definition Fire2023.h:42
#define FLAMEHEIGHT
Definition Fire2023.h:54
#define SMOKENOISESCALE
Definition Fire2023.h:65
uint32_t z[NUM_LAYERS]
Definition Fire2023.h:94
void setup()
Definition Fire2023.h:106
ScreenMap makeScreenMap()
Definition Fire2023.h:128
uint8_t heat[NUM_LEDS]
Definition Fire2023.h:101
CRGBPalette32 hotPalette
Definition Fire2023.h:81
uint8_t noise2[NUM_LAYERS][WIDTH][HEIGHT]
Definition Fire2023.h:99
#define SMOKESPEED
Definition Fire2023.h:63
#define LAST_VISIBLE_LED
Definition Fire2023.h:48
uint32_t scale_y[NUM_LAYERS]
Definition Fire2023.h:96
#define PIXELPIN
Definition Fire2023.h:46
#define FIRENOISE
Definition Fire2023.h:90
#define FIRENOISESCALE
Definition Fire2023.h:55
#define SMOKENOISE_DIMMER
Definition Fire2023.h:64
#define FIRESPEED
Definition Fire2023.h:53
void Fire2023(uint32_t now)
Definition Fire2023.h:139
#define NUM_LAYERS
Definition Fire2023.h:88
#define CentreY
Definition Fire2023.h:43
uint32_t scale_x[NUM_LAYERS]
Definition Fire2023.h:95
void loop()
Definition Fire2023.h:121
unsigned int xy(unsigned int x, unsigned int y)
#define WIDTH
Definition advanced.h:36
#define HEIGHT
Definition advanced.h:37
LED controller for WS2812 LEDs with GRB color order.
Definition FastLED.h:158
fl::size size() const
Definition vector.h:545
void push_back(const T &value)
Definition vector.h:552
#define DEFINE_GRADIENT_PALETTE(X)
Defines a static RGB palette very compactly using a series of connected color gradients.
Definition colorutils.h:121
#define DISABLE_DITHER
Disable dithering.
Definition dither_mode.h:12
fl::ScreenMap screenMap
Definition Corkscrew.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:420
LIB8STATIC_ALWAYS_INLINE uint8_t scale8(uint8_t i, fract8 scale)
Scale one byte by a second one, which is treated as the numerator of a fraction whose denominator is ...
Definition scale8.h:44
#define EVERY_N_MILLISECONDS(N)
Alias for EVERY_N_MILLIS.
Definition lib8tion.h:1221
fl::u16 XY(fl::u8 x, fl::u8 y)
Definition blur.cpp:22
CRGB ColorFromPalette(const CRGBPalette16 &pal, fl::u8 index, fl::u8 brightness, TBlendType blendType)
vec2< float > vec2f
Definition geometry.h:333
HeapVector< T, Allocator > vector
Definition vector.h:1214
IMPORTANT!
Definition crgb.h:20
Representation of an RGB pixel (Red, Green, Blue)
Definition crgb.h:86