-
-
Save enwi/0ce156eaf2e8b996d393df61b643c7da to your computer and use it in GitHub Desktop.
Fire effect v2.0 for FastLED matrix
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "FastLED.h" | |
const uint8_t BRIGHTNESS = 255; | |
// matrix size | |
const uint8_t WIDTH = 16; | |
const uint8_t HEIGHT = 16; | |
const uint16_t NUM_ | |
= WIDTH * HEIGHT; | |
// parameters and buffer for the noise array | |
const uint8_t NUM_LAYERS = 2; | |
uint8_t noise[NUM_LAYERS][WIDTH][HEIGHT]; | |
uint8_t noise2[NUM_LAYERS][WIDTH][HEIGHT]; | |
uint8_t heat[WIDTH][HEIGHT]; | |
// NUM_LEDS = Width * Height | |
CRGB pixels[NUM_LEDS]; | |
void setup() | |
{ | |
Serial.begin(115200); | |
// Adjust this for you own setup. Use the hardware SPI pins if possible. | |
// On Teensy 3.1/3.2 the pins are 11 & 13 | |
// Details here: https://github.com/FastLED/FastLED/wiki/SPI-Hardware-or-Bit-banging | |
// In case you see flickering / glitching leds, reduce the data rate to 12 MHZ or less | |
LEDS.addLeds<APA102, 11, 13, BGR, DATA_RATE_MHZ(12)>(pixels, NUM_LEDS); | |
FastLED.setBrightness(BRIGHTNESS); | |
FastLED.setDither(DISABLE_DITHER); | |
} | |
void loop() | |
{ | |
Fire2018_2(); | |
// show_fps(); | |
} | |
// check the Serial Monitor for fps rate | |
void show_fps() | |
{ | |
EVERY_N_MILLIS(100) { Serial.println(LEDS.getFPS()); } | |
} | |
// this finds the right index within a serpentine matrix | |
// This is for a strips that are aligned vertically, the first strip starts at the botttom right | |
uint16_t getSerpentineIndex(uint8_t x, uint8_t y) | |
{ | |
uint16_t i; | |
if (x & 0x01) | |
{ | |
i = (x * HEIGHT) + y; | |
} | |
else | |
{ | |
uint8_t reverseY = (HEIGHT - 1) - y; | |
i = (x * HEIGHT) + reverseY; | |
} | |
return i; | |
} | |
template <size_t width, size_t height> | |
void calcNoise(uint8_t (&noise)[width][height], const uint32_t scaleX, const uint32_t scaleY, const uint32_t heatX, | |
const uint32_t heatY, const uint32_t heatZ) | |
{ | |
const uint8_t centerX = (width / 2) - 1; | |
const uint8_t centerY = (height / 2) - 1; | |
for (uint8_t x = 0; x < width; x++) | |
{ | |
uint32_t ioffset = scaleX * (x - centerX); | |
for (uint8_t y = 0; y < height; y++) | |
{ | |
uint32_t joffset = scaleY * (y - centerY); | |
uint16_t data = ((inoise16(heatX + ioffset, heatY + joffset, heatZ)) + 1); | |
noise[x][y] = data >> 8; | |
} | |
} | |
} | |
void Fire2018_2() | |
{ | |
// some changing values | |
uint16_t ctrl1 = inoise16(11 * millis(), 0, 0); | |
uint16_t ctrl2 = inoise16(13 * millis(), 100000, 100000); | |
uint16_t ctrl = ((ctrl1 + ctrl2) / 2); | |
// parameters for the heatmap | |
uint16_t speed = 25; | |
// calculate the noise data | |
calcNoise<WIDTH, HEIGHT>( | |
noise[0], ctrl1 / 2, ctrl2 / 2, 3 * ctrl * speed, 20 * millis() * speed, 5 * millis() * speed); | |
// parameters for te brightness mask | |
speed = 20; | |
// calculate the noise data | |
calcNoise<WIDTH, HEIGHT>( | |
noise[1], ctrl1 / 2, ctrl2 / 2, 3 * ctrl * speed, 20 * millis() * speed, 5 * millis() * speed); | |
// draw lowest line - seed the fire | |
for (uint8_t x = 0; x < WIDTH; x++) | |
{ | |
heat[x][HEIGHT - 1] = noise[0][WIDTH - 1 - x][7]; // was HEIGHT / 2 | |
} | |
// copy everything one line up | |
for (uint8_t y = 0; y < HEIGHT - 1; y++) | |
{ | |
for (uint8_t x = 0; x < WIDTH; x++) | |
{ | |
heat[x][y] = heat[x][y + 1]; | |
} | |
} | |
// dim | |
for (uint8_t y = 0; y < HEIGHT - 1; y++) | |
{ | |
for (uint8_t x = 0; x < WIDTH; x++) | |
{ | |
uint8_t dim = noise[0][x][y]; | |
// high value = high flames | |
// dim = dim / 1.7; | |
dim = dim / 2; | |
dim = 255 - dim; | |
heat[x][y] = scale8(heat[x][y], dim); | |
} | |
} | |
for (uint8_t y = 0; y < HEIGHT; y++) | |
{ | |
for (uint8_t x = 0; x < WIDTH; x++) | |
{ | |
// map the colors based on heatmap and dim the result based on 2nd noise layer | |
// pixels[getSerpentineIndex(x, y)] = CRGB(heat[x][y], 1, 0).nscale8(noise[1][x][y]); | |
pixels[getSerpentineIndex(x, y)] = ColorFromPalette(HeatColors_p, heat[x][y]).nscale8(noise[1][x][y]); | |
} | |
} | |
FastLED.show(); | |
delay(8); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment