kriegsman

Fire2012: an Arduino/LED fire simulation for FastLED

Apr 3rd, 2014
13,456
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Fire2012: a basic fire simulation for a one-dimensional string of LEDs
  2. // Mark Kriegsman, July 2012.
  3. //
  4. // Compiled size for Arduino/AVR is about 3,968 bytes.
  5.  
  6. #include <FastLED.h>
  7.  
  8. #define LED_PIN     5
  9. #define COLOR_ORDER GRB
  10. #define CHIPSET     WS2811
  11. #define NUM_LEDS    50
  12.  
  13. #define BRIGHTNESS  200
  14. #define FRAMES_PER_SECOND 60
  15.  
  16. CRGB leds[NUM_LEDS];
  17.  
  18. void setup() {
  19.   delay(3000); // sanity delay
  20.   FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  21.   FastLED.setBrightness( BRIGHTNESS );
  22. }
  23.  
  24. void loop()
  25. {
  26.   // Add entropy to random number generator; we use a lot of it.
  27.   random16_add_entropy( random());
  28.  
  29.   Fire2012(); // run simulation frame
  30.   FastLED.show(); // display this frame
  31.  
  32. #if defined(FASTLED_VERSION) && (FASTLED_VERSION >= 2001000)
  33.   FastLED.delay(1000 / FRAMES_PER_SECOND);
  34. #else  
  35.   delay(1000 / FRAMES_PER_SECOND);
  36. #endif  
  37. }
  38.  
  39.  
  40. // Fire2012 by Mark Kriegsman, July 2012
  41. // as part of "Five Elements" shown here: http://youtu.be/knWiGsmgycY
  42. //
  43. // This basic one-dimensional 'fire' simulation works roughly as follows:
  44. // There's a underlying array of 'heat' cells, that model the temperature
  45. // at each point along the line.  Every cycle through the simulation,
  46. // four steps are performed:
  47. //  1) All cells cool down a little bit, losing heat to the air
  48. //  2) The heat from each cell drifts 'up' and diffuses a little
  49. //  3) Sometimes randomly new 'sparks' of heat are added at the bottom
  50. //  4) The heat from each cell is rendered as a color into the leds array
  51. //     The heat-to-color mapping uses a black-body radiation approximation.
  52. //
  53. // Temperature is in arbitrary units from 0 (cold black) to 255 (white hot).
  54. //
  55. // This simulation scales it self a bit depending on NUM_LEDS; it should look
  56. // "OK" on anywhere from 20 to 100 LEDs without too much tweaking.
  57. //
  58. // I recommend running this simulation at anywhere from 30-100 frames per second,
  59. // meaning an interframe delay of about 10-35 milliseconds.
  60. //
  61. //
  62. // There are two main parameters you can play with to control the look and
  63. // feel of your fire: COOLING (used in step 1 above), and SPARKING (used
  64. // in step 3 above).
  65. //
  66. // COOLING: How much does the air cool as it rises?
  67. // Less cooling = taller flames.  More cooling = shorter flames.
  68. // Default 55, suggested range 20-100
  69. #define COOLING  55
  70.  
  71. // SPARKING: What chance (out of 255) is there that a new spark will be lit?
  72. // Higher chance = more roaring fire.  Lower chance = more flickery fire.
  73. // Default 120, suggested range 50-200.
  74. #define SPARKING 120
  75.  
  76.  
  77. void Fire2012()
  78. {
  79. // Array of temperature readings at each simulation cell
  80.   static byte heat[NUM_LEDS];
  81.  
  82.   // Step 1.  Cool down every cell a little
  83.     for( int i = 0; i < NUM_LEDS; i++) {
  84.       heat[i] = qsub8( heat[i],  random8(0, ((COOLING * 10) / NUM_LEDS) + 2));
  85.     }
  86.  
  87.     // Step 2.  Heat from each cell drifts 'up' and diffuses a little
  88.     for( int k= NUM_LEDS - 3; k > 0; k--) {
  89.       heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
  90.     }
  91.    
  92.     // Step 3.  Randomly ignite new 'sparks' of heat near the bottom
  93.     if( random8() < SPARKING ) {
  94.       int y = random8(7);
  95.       heat[y] = qadd8( heat[y], random8(160,255) );
  96.     }
  97.  
  98.     // Step 4.  Map from heat cells to LED colors
  99.     for( int j = 0; j < NUM_LEDS; j++) {
  100.         leds[j] = HeatColor( heat[j]);
  101.     }
  102. }
  103.  
  104.  
  105.  
  106. // CRGB HeatColor( uint8_t temperature)
  107. // [to be included in the forthcoming FastLED v2.1]
  108. //
  109. // Approximates a 'black body radiation' spectrum for
  110. // a given 'heat' level.  This is useful for animations of 'fire'.
  111. // Heat is specified as an arbitrary scale from 0 (cool) to 255 (hot).
  112. // This is NOT a chromatically correct 'black body radiation'
  113. // spectrum, but it's surprisingly close, and it's extremely fast and small.
  114. //
  115. // On AVR/Arduino, this typically takes around 70 bytes of program memory,
  116. // versus 768 bytes for a full 256-entry RGB lookup table.
  117.  
  118. CRGB HeatColor( uint8_t temperature)
  119. {
  120.   CRGB heatcolor;
  121.  
  122.   // Scale 'heat' down from 0-255 to 0-191,
  123.   // which can then be easily divided into three
  124.   // equal 'thirds' of 64 units each.
  125.   uint8_t t192 = scale8_video( temperature, 192);
  126.  
  127.   // calculate a value that ramps up from
  128.   // zero to 255 in each 'third' of the scale.
  129.   uint8_t heatramp = t192 & 0x3F; // 0..63
  130.   heatramp <<= 2; // scale up to 0..252
  131.  
  132.   // now figure out which third of the spectrum we're in:
  133.   if( t192 & 0x80) {
  134.     // we're in the hottest third
  135.     heatcolor.r = 255; // full red
  136.     heatcolor.g = 255; // full green
  137.     heatcolor.b = heatramp; // ramp up blue
  138.    
  139.   } else if( t192 & 0x40 ) {
  140.     // we're in the middle third
  141.     heatcolor.r = 255; // full red
  142.     heatcolor.g = heatramp; // ramp up green
  143.     heatcolor.b = 0; // no blue
  144.    
  145.   } else {
  146.     // we're in the coolest third
  147.     heatcolor.r = heatramp; // ramp up red
  148.     heatcolor.g = 0; // no green
  149.     heatcolor.b = 0; // no blue
  150.   }
  151.  
  152.   return heatcolor;
  153. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×