# Anyone seen a pattern like this?

**URL:** <https://forum.electromage.com/t/anyone-seen-a-pattern-like-this/1583>\
**Category:** Uncategorized\
**Created:** [September 19, 2021, 10:56pm UTC](https://forum.electromage.com/t/anyone-seen-a-pattern-like-this/1583 "2021-09-19T22:56:22Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jsharkbite](https://forum.electromage.com/letter_avatar_proxy/v4/letter/j/6a8cbe/32.png) [@Jsharkbite](https://forum.electromage.com/u/Jsharkbite)\
**Post date:** [September 19, 2021, 10:56pm UTC](https://forum.electromage.com/t/anyone-seen-a-pattern-like-this/1583/1 "2021-09-19T22:56:23Z")

</div>

Flame effect from Dave’s Garage

[![](https://img.youtube.com/vi/MauVVTJb2tk/maxresdefault.jpg "10-My Shop's on Fire! with FastLED Arduino RGB LED Flames Effect Tutorial") ](https://www.youtube.com/watch?v=MauVVTJb2tk)

I’ve got sparkfire going as the closest thing.  
I don’t think the arduino based code will work on the PB so I was curious if anyone came across anything like this.

---

<div class="post-metadata">

**Author:** ![Scruffynerf](https://forum.electromage.com/letter_avatar_proxy/v4/letter/s/34f0e0/32.png) [@Scruffynerf](https://forum.electromage.com/u/Scruffynerf)\
**Post date:** [September 20, 2021, 12:46am UTC](https://forum.electromage.com/t/anyone-seen-a-pattern-like-this/1583/2 "2021-09-20T00:46:50Z")

</div>

There are a handful of 1D and 2D fire patterns.  
If none of them is enough of a match, we can look at his particular code and figure out what it does differently.

He’s actually about to open source his led code wrapper, sits on top of FastLED,etc and adds a few standards like circles, lines, and so on, and some directional wipes/etc.

Nothing PB can’t do now.

---

<div class="post-metadata">

**Author:** ![jeff](https://forum.electromage.com/user_avatar/forum.electromage.com/jeff/32/3473_2.png) [@jeff](https://forum.electromage.com/u/jeff)\
**Post date:** [September 20, 2021, 5:30am UTC](https://forum.electromage.com/t/anyone-seen-a-pattern-like-this/1583/3 "2021-09-20T05:30:58Z")

</div>

Hey @Jsharkbite - What are the biggest differences between sparkfire and what you see in the video? Are you just referring to how the fire is coming from both sides?

Sparkfire can be a little unruly to tune, especially depending on how many LEDs you have and their spacing.

---

<div class="post-metadata">

**Author:** ![wizard](https://forum.electromage.com/user_avatar/forum.electromage.com/wizard/32/4_2.png) [@wizard](https://forum.electromage.com/u/wizard)\
**Post date:** [September 20, 2021, 6:05am UTC](https://forum.electromage.com/t/anyone-seen-a-pattern-like-this/1583/4 "2021-09-20T06:05:30Z")

</div>

To me, it looks like spark fire, and maybe a 2d spark fire that could be just multiple lines of spark fire (no horizontal heat transfer).

---

<div class="post-metadata">

**Author:** ![Jsharkbite](https://forum.electromage.com/letter_avatar_proxy/v4/letter/j/6a8cbe/32.png) [@Jsharkbite](https://forum.electromage.com/u/Jsharkbite)\
**Post date:** [September 20, 2021, 11:09am UTC](https://forum.electromage.com/t/anyone-seen-a-pattern-like-this/1583/5 "2021-09-20T11:09:55Z")

</div>

The biggest difference in sparkfire is the strobing effect. Too frequently the entire strip of LEDs will flash white. I can’t seem to limit the frequency and or the amount of LEDs that partake in the strobing effect.

The end of the video captured the strobe.

> [@Clearing LEDs on strip before running a program](https://forum.electromage.com/t/clearing-leds-on-strip-before-running-a-program/1523/3):
>
> Thanks Jeff! I will give this a shot tomorrow. I am super excited to learn what I can do with the setup and I appreciate the help. I can already see some limitations in how I wired it though. Here’s a video when it runs correctly. The biggest drawback is that it doesn’t look random due to the symmetry of how I wired it. It would be really cool to get to a point where each gable side has it’s own spark-fire pattern running randomly.

---

<div class="post-metadata">

**Author:** ![Scruffynerf](https://forum.electromage.com/letter_avatar_proxy/v4/letter/s/34f0e0/32.png) [@Scruffynerf](https://forum.electromage.com/u/Scruffynerf)\
**Post date:** [September 20, 2021, 2:15pm UTC](https://forum.electromage.com/t/anyone-seen-a-pattern-like-this/1583/6 "2021-09-20T14:15:12Z")

</div>

Yes, it’s a bit too much white. Dave’s never does white but leans yellow.

There are a lot of fire simulator patterns, and folding the various techniques/methods into a customizable pattern would be good.

We also lack pallette support currently, which would allow further tweaking, not just to slightly tweak the color scheme but to allow things like “coldfire” (a blue fire), for example.

I’m thinking this might be a fun November theme for a contest… Make the best looking fire in 1D or 2D… Graded on things like realism, adjustability, and so on.

October is still Halloween themed contest, reminder.

---

<div class="post-metadata">

**Author:** ![jeff](https://forum.electromage.com/user_avatar/forum.electromage.com/jeff/32/3473_2.png) [@jeff](https://forum.electromage.com/u/jeff)\
**Post date:** [September 20, 2021, 5:00pm UTC](https://forum.electromage.com/t/anyone-seen-a-pattern-like-this/1583/7 "2021-09-20T17:00:30Z")

</div>

@Jsharkbite

OK, here’s a version of sparkfire where you can play with all the parameters with sliders. I also added a way to select how white the hottest parts get. Note that this uses `pow()` inside `render()`, which is a classic way to slow down your framerate 🙂 Once you’ve found the right level of `whiteness` / saturation, you can make things faster by replacing it with similar math that doesn’t use `pow()`.

I pre-populated it with parameters that looked good on my 4m of 60/m SK6812 (FYI mine are RGBW). Because sparks regenerate when they get to the end of the strip, your total strip length will affect how much fire is present at once.

Let me know how this goes!

> **Code for "sparkfire tunable"**
>
> ```javascript
> /*
> Sparkfire
>   
> What happens when you allow a pattern like 'sparks' to heat the air around it?
> You get spark fire! It's probably a good idea to read through the comments on
> 'sparks' first.
> 
> Depending on the number of pixels in your strip, you may need to adjust the
> first few variables to your liking; While there's meant to
> mostly work depending on the number of pixels, you should tune them to look
> good on your setup.
> */
> 
> // Number of sparks. Try 3-6.
> numSparks = 3 + floor(pixelCount / 80)  
> 
> // Subtractive cooling. Try 0.02..0.3. Higher cools faster.
> export var cooling1 = .0217
> export function sliderCooling1 (_v) {
> cooling1 = _v * .2
> }
> 
> // Coefficient cooling. Try 0.9..0.995. Lower cools faster.
> export var cooling2 = .97
> export function sliderCooling2 (_v) {
> cooling2 = .97 + sqrt((1-_v)) * .03
> }
> 
> export var accel = .03 // How much sparks accelerate as they rise (try 0.02..0.05)
> export function sliderAccel (_v) {
> accel = _v * .05
> }
> 
> export var speed = .07 // Baseline speed of travel for each spark (try 0.03..0.1)
> export function sliderSpeed (_v) {
> speed = _v * .1
> }
> 
> export var whiteness = .33 // Baseline speed of travel for each spark (try 0.03..0.1)
> export function sliderWhiteness (_v) {
> whiteness = 3 * (1 - _v)
> }
> 
> // Energy of each spark. Affects pixel heating and spark speed.
> export var sparks = array(numSparks)
> sparkX = array(numSparks) // X position of each spark, in units of pixel index
> var pixels = array(pixelCount) // Brightness (heat energy) of each pixel
> 
> // Initialize sparks with random position and energy
> for (i = 0; i < numSparks; i++) {
> sparkX[i] = random(pixelCount)
> // Further sparks are older and have less energy
> sparks[i] = .2 * (1 - sparkX[i] / pixelCount) + random(.4)
> }
> 
> // Set up an initial heat value so init doesn't look empty
> pixels[0] = 20
> 
> // Store the maximum energy seen each frame
> export var maxEnergy = 0
> 
> export function beforeRender(delta) {
> delta *= speed // Scale the time between loops by speed.
> maxEnergy = 0
> 
> for(i = 0; i < pixelCount; i++) {
> // When more time has passed, more subtractive cooling occurs
> cooldown = cooling1 * delta
>    
> if(cooldown > pixels[i]) {
> pixels[i] = 0
> } else {
> // Coefficient cooling (`cooling2`) makes hotter sparks lose more energy.
> // Subtractive cooling makes all sparks lose some energy.
> pixels[i] = pixels[i] * cooling2 - cooldown
> }
>     
> maxEnergy = max(maxEnergy, pixels[i]) // Keep track of max energy seen
> }
> /*
> Heat rises. Starting at the far end and working towards the first pixel,
> compute a weighted average of the heat from the preceding pixels and apply
> it to this one. Weighting several pixels behind higher creates a nice wispy
> pattern that can be seen more clearly by turning down `speed`.
> */
> for (k = pixelCount - 1; k >= 4; k--) {
> h1 = pixels[k - 1]
> h2 = pixels[k - 2]
> h3 = pixels[k - 3]
> h4 = pixels[k - 4]
> pixels[k] = (h1 + h2 + h3 * 2 + h4 * 3) / 7
> }
>   
> for (i = 0; i < numSparks; i++) {
> // Reinitialize a spark that's passed the end and been reset
> if (sparks[i] <= 0) {
> sparks[i] = .1 + random(.4)
> sparkX[i] = 0
> }
> 
> // Accelerate (add kinetic energy) to each spark
> sparks[i] += accel * delta
>     
> // Stash the original x position of this spark 
> ox = sparkX[i]
> 
> // Δd = r·Δt 
> // Sparks advance at a rate that's the square of their energy
> sparkX[i] += sparks[i] * sparks[i] * delta
> 
> // Reset sparks that are past the end
> if (sparkX[i] > pixelCount) {
> sparkX[i] = 0
> sparks[i] = 0
> continue // Skip the rest of the for() loop for this iteration
> }
>     
> 
> /*
> For all pixels between the new x position and the original x position,
> heat the pixels (add brightness). Higher energy sparks are travelling
> faster and thus don't heat each pixel of air as much.
> */
> for (j = ox; j < sparkX[i]; j++)
> pixels[j] += clamp(1 - sparks[i] * .4, 0 , 1) * .5
> }
> }
> 
> export function render(index) {
> v = pixels[index]
>   
> var pctOfMax = v / maxEnergy // This pixel's percentage of the overall highest energy pixel
> 
> /*
> v * v is our typical gamma correction, and it's constrained to remain
> between 0 and 1. Multiplying this by 0.1 keeps us in the red-yellow range;
> higher energies will be yellow.
> */
> h = .1 * clamp(v * v, 0, 1) 
>   
> /*
> Desaturate (to white) any pixel with energy values between 1 and 1.5;
> Saturation will be clamped to 0 for any energy value above 1.5. Without
> this, the hottest pixels are just yellow instead of white hot.
> */
> // s = 1 - (v - 1) * 2 // Default saturation code
> s = 1 - pow(pctOfMax, whiteness) // To greatly speed up pattern, replace this with equivalent scaling nce you've tuned your look with the whiteness slider
> 
> // It's useful to remember that HSV clamps s and v for us to within 0..1
> hsv(h, s, v)
> }
> 
> ```

---

<div class="post-metadata">

**Author:** ![Jsharkbite](https://forum.electromage.com/letter_avatar_proxy/v4/letter/j/6a8cbe/32.png) [@Jsharkbite](https://forum.electromage.com/u/Jsharkbite)\
**Post date:** [September 20, 2021, 11:03pm UTC](https://forum.electromage.com/t/anyone-seen-a-pattern-like-this/1583/8 "2021-09-20T23:03:17Z")

</div>

This sounds awesome! I will start tinkering with it as soon as my little one is in bed. I had all kinds of crazy ideas for candy corn going along the roof and candy canes (1D stix). This is probably the most helpful forum i’ve been on in a long time!

---

<div class="post-metadata">

**Author:** ![Jsharkbite](https://forum.electromage.com/letter_avatar_proxy/v4/letter/j/6a8cbe/32.png) [@Jsharkbite](https://forum.electromage.com/u/Jsharkbite)\
**Post date:** [September 21, 2021, 2:05am UTC](https://forum.electromage.com/t/anyone-seen-a-pattern-like-this/1583/9 "2021-09-21T02:05:17Z")

</div>

Yep! this is very cool! I’ve got it running and I see what you mean by it being very dependent upon the number of pixels I have going. So it got me wondering, since the gable above the garage is about 90 pixels and the two smaller gables are only 40-60, is it possible to have each of the strands running different settings (slider options)? So channel 1 would have a different speed/acceleration LED count than channel 2 etc, etc…

---

<div class="post-metadata">

**Author:** ![Scruffynerf](https://forum.electromage.com/letter_avatar_proxy/v4/letter/s/34f0e0/32.png) [@Scruffynerf](https://forum.electromage.com/u/Scruffynerf)\
**Post date:** [September 21, 2021, 2:33pm UTC](https://forum.electromage.com/t/anyone-seen-a-pattern-like-this/1583/10 "2021-09-21T14:33:33Z")

</div>

Yes, you’d have to add sliders and some conditional changes based on which strand (by index #) to use the “right” values.

---

<div class="post-metadata">

**Author:** ![jeff](https://forum.electromage.com/user_avatar/forum.electromage.com/jeff/32/3473_2.png) [@jeff](https://forum.electromage.com/u/jeff)\
**Post date:** [September 22, 2021, 12:27am UTC](https://forum.electromage.com/t/anyone-seen-a-pattern-like-this/1583/11 "2021-09-22T00:27:56Z")

</div>

For the next version of PB, I’m thinking we should refactor Sparkfire to generate new sparks at a probabilistic rate, instead of one that depends so much on recycling the cooled sparks that made it to the end.

---

<div class="post-metadata">

**Author:** ![zranger1](https://forum.electromage.com/user_avatar/forum.electromage.com/zranger1/32/301_2.png) [@zranger1](https://forum.electromage.com/u/zranger1)\
**Post date:** [September 22, 2021, 2:28am UTC](https://forum.electromage.com/t/anyone-seen-a-pattern-like-this/1583/12 "2021-09-22T02:28:08Z")

</div>

> We also lack pallette support currently, which would allow further tweaking, not just to slightly tweak the color scheme but to allow things like “coldfire” (a blue fire), for example.

Although it’s not 1D (for now) Doom Fire has color control. You can set the base hue to anything you want, and the rest of the fire colors are determined by the “temperature” - basically small random shifts in hue, plus desaturation (towards white) as it heats up. Try the updated 2.0 version from the library, set it in “Dragon” mode, crank the flames up a bit, add a little wind and…

Also, I’ve got this more “explode-y” noise based fire in the works. Not sure it’s better, but it’s definitely different.  
 ![fire2](https://forum.electromage.com/uploads/default/original/2X/9/9b59c4694bc2cd53f09355d7726a7edd5e8a96e7.gif)

---

<div class="post-metadata">

**Author:** ![Scruffynerf](https://forum.electromage.com/letter_avatar_proxy/v4/letter/s/34f0e0/32.png) [@Scruffynerf](https://forum.electromage.com/u/Scruffynerf)\
**Post date:** [September 22, 2021, 3:07am UTC](https://forum.electromage.com/t/anyone-seen-a-pattern-like-this/1583/13 "2021-09-22T03:07:09Z")

</div>

The new 2.0 version is nifty, and yes, it’s got a hue option.

We really don’t have any patterns with palettes, because we don’t have palettes (yet).  
Hopefully soon, based on something I know Ben’s doing with arrays, it’ll be easier to do so.

---

<div class="post-metadata">

**Author:** ![Scruffynerf](https://forum.electromage.com/letter_avatar_proxy/v4/letter/s/34f0e0/32.png) [@Scruffynerf](https://forum.electromage.com/u/Scruffynerf)\
**Post date:** [October 3, 2021, 4:07pm UTC](https://forum.electromage.com/t/anyone-seen-a-pattern-like-this/1583/14 "2021-10-03T16:07:17Z")

</div>

Related to the original fire at the top:

Dave of Dave’s Garage has just released NightDriver…his esp32 led code all organized.  
I suspect all of the usual suspects will be poring over the code and playing with it to see what different he did.

> **[GitHub - PlummersSoftwareLLC/NightDriverStrip: NightDriver client for ESP32](https://github.com/PlummersSoftwareLLC/NightDriverStrip)**
>
> NightDriver client for ESP32. Contribute to PlummersSoftwareLLC/NightDriverStrip development by creating an account on GitHub.
