/* This demo is best viewed using the FastLED compiler. Install: pip install fastled Run: fastled This will compile and preview the sketch in the browser, and enable all the UI elements you see below. */ // Perlin noise fire procedure // 16x16 rgb led cylinder demo // Exactly the same as the FireMatrix example, but with a cylinder, meaning that the x=0 // and x = len-1 are connected. // This also showcases the inoise16(x,y,z,t) function which handles 3D+time noise effects. // Keep in mind that a cylinder is embedded in a 3D space with time being used to add // additional noise to the effect. #include "FastLED.h" #include "fl/ui.h" #include "fl/xymap.h" #include "fx/time.h" using namespace fl; #define HEIGHT 100 #define WIDTH 100 #define SERPENTINE true #define BRIGHTNESS 255 UITitle title("FireCylinder Demo"); UIDescription description("This Fire demo wraps around the cylinder. It uses Perlin noise to create a fire effect."); TimeScale timeScale(0, 1.0f); UISlider scaleXY("Scale", 8, 1, 100, 1); UISlider speedY("SpeedY", 1.3, 1, 6, .1); UISlider scaleX("ScaleX", .3, 0.1, 3, .01); UISlider invSpeedZ("Inverse SpeedZ", 20, 1, 100, 1); UISlider brightness("Brightness", 255, 0, 255, 1); UINumberField palette("Palette", 0, 0, 2); CRGB leds[HEIGHT * WIDTH]; DEFINE_GRADIENT_PALETTE(firepal){ // define fire palette 0, 0, 0, 0, // black 32, 255, 0, 0, // red 190, 255, 255, 0, // yellow 255, 255, 255, 255 // white }; DEFINE_GRADIENT_PALETTE(electricGreenFirePal){ 0, 0, 0, 0, // black 32, 0, 70, 0, // dark green 190, 57, 255, 20, // electric neon green 255, 255, 255, 255 // white }; DEFINE_GRADIENT_PALETTE(electricBlueFirePal){ 0, 0, 0, 0, // Black 32, 0, 0, 70, // Dark blue 128, 20, 57, 255, // Electric blue 255, 255, 255, 255 // White }; XYMap xyMap(HEIGHT, WIDTH, SERPENTINE); void setup() { Serial.begin(115200); FastLED.addLeds(leds, HEIGHT * WIDTH).setScreenMap(xyMap); FastLED.setCorrection(TypicalLEDStrip); } uint8_t getPaletteIndex(uint32_t millis32, int width, int max_width, int height, int max_height, uint32_t y_speed) { // get palette index uint16_t scale = scaleXY.as(); float xf = (float)width / (float)max_width; uint8_t x = (uint8_t)(xf * 255); uint32_t cosx = cos8(x); uint32_t sinx = sin8(x); float trig_scale = scale * scaleX.value(); cosx *= trig_scale; sinx *= trig_scale; uint32_t y = height * scale + y_speed; // swapped: now using height uint16_t z = millis32 / invSpeedZ.as(); uint16_t noise16 = inoise16(cosx << 8, sinx << 8, y << 8, 0); uint8_t noise_val = noise16 >> 8; int8_t subtraction_factor = abs8(height - (max_height - 1)) * 255 / (max_height - 1); // swapped: now using height return qsub8(noise_val, subtraction_factor); } CRGBPalette16 getPalette() { // get palette switch (palette) { case 0: return firepal; case 1: return electricGreenFirePal; case 2: return electricBlueFirePal; default: return firepal; } } void loop() { FastLED.setBrightness(brightness); CRGBPalette16 myPal = getPalette(); uint32_t now = millis(); timeScale.setScale(speedY); uint32_t y_speed = timeScale.update(now); for (int width = 0; width < WIDTH; width++) { for (int height = 0; height < HEIGHT; height++) { uint8_t palette_index = getPaletteIndex(now, width, WIDTH, height, HEIGHT, y_speed); CRGB c = ColorFromPalette(myPal, palette_index, BRIGHTNESS); int index = xyMap((WIDTH - 1) - width, (HEIGHT - 1) - height); leds[index] = c; } } FastLED.show(); }