Advertisement
kriegsman

Fire2012: an Arduino/LED fire simulation for FastLED

Apr 3rd, 2014
17,920
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.93 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement