{"id":32,"date":"2016-12-15T16:31:50","date_gmt":"2016-12-15T16:31:50","guid":{"rendered":"http:\/\/www.anirama.com\/1000leds\/?p=32"},"modified":"2020-11-23T12:49:06","modified_gmt":"2020-11-23T20:49:06","slug":"1d-fireworks","status":"publish","type":"post","link":"https:\/\/www.anirama.com\/1000leds\/1d-fireworks\/","title":{"rendered":"1D fireworks"},"content":{"rendered":"<p>My first LED strip project was a vertical one-dimensional fireworks display. It&#8217;s 2 meters tall with 120 LEDs driven by an Arduino Uno.<\/p>\n<p><iframe src=\"https:\/\/www.youtube.com\/embed\/3AL_2X6n284?rel=0\" width=\"640\" height=\"360\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n<p>Here&#8217;s the code for the Arduino.<\/p>\n<p>boom.ino<\/p>\n<pre>#include &lt;FastLED.h&gt;\r\n#define NUM_LEDS 120\r\n#define DATA_PIN 6\r\nCRGB leds[NUM_LEDS]; \/\/ sets up block of memory\r\n\r\n#define NUM_SPARKS 61 \/\/ max number (could be NUM_LEDS \/ 2);\r\nfloat sparkPos[NUM_SPARKS];\r\nfloat sparkVel[NUM_SPARKS];\r\nfloat sparkCol[NUM_SPARKS];\r\nfloat flarePos;\r\n\r\nfloat gravity = -.004; \/\/ m\/s\/s\r\n\r\nvoid setup() {\r\n  Serial.begin(115200);\r\n  FastLED.addLeds&lt;NEOPIXEL, DATA_PIN&gt;(leds, NUM_LEDS);\r\n}\r\n\r\n\/*\r\n * Main Loop\r\n *\/\r\nvoid loop() {  \r\n  \/\/ send up flare\r\n  flare();\r\n  \r\n  \/\/ explode\r\n  explodeLoop();\r\n\r\n  \/\/ wait before sending up another\r\n  delay(random16(1000, 4000));\r\n}\r\n\r\n\r\n\/*\r\n * Send up a flare\r\n * \r\n *\/\r\nvoid flare() {\r\n  \r\n  flarePos = 0;\r\n  float flareVel = float(random16(50, 90)) \/ 100; \/\/ trial and error to get reasonable range\r\n  float brightness = 1;\r\n\r\n  \/\/ initialize launch sparks\r\n  for (int i = 0; i &lt; 5; i++) { \r\n    sparkPos[i] = 0;\r\n    sparkVel[i] = (float(random8()) \/ 255) * (flareVel \/ 5);\r\n    \/\/ random around 20% of flare velocity\r\n    sparkCol[i] = sparkVel[i] * 1000;\r\n    sparkCol[i] = constrain(sparkCol[i], 0, 255);\r\n  } \r\n  \/\/ launch \r\n  FastLED.clear();\r\n  while (flareVel &gt;= -.2) {\r\n    \/\/ sparks\r\n    for (int i = 0; i &lt; 5; i++) {\r\n      sparkPos[i] += sparkVel[i];\r\n      sparkPos[i] = constrain(sparkPos[i], 0, 120);\r\n      sparkVel[i] += gravity;\r\n      sparkCol[i] += -.8;\r\n      sparkCol[i] = constrain(sparkCol[i], 0, 255);\r\n      leds[int(sparkPos[i])] = HeatColor(sparkCol[i]);\r\n      leds[int(sparkPos[i])] %= 50; \/\/ reduce brightness to 50\/255\r\n    }\r\n    \r\n    \/\/ flare\r\n    leds[int(flarePos)] = CHSV(0, 0, int(brightness * 255));\r\n    FastLED.show();\r\n    FastLED.clear();\r\n    flarePos += flareVel;\r\n    flareVel += gravity;\r\n    brightness *= .985;\r\n  }\r\n}\r\n\r\n\/*\r\n * Explode!\r\n * \r\n * Explosion happens where the flare ended.\r\n * Size is proportional to the height.\r\n *\/\r\nvoid explodeLoop() {\r\n  int nSparks = flarePos \/ 2; \/\/ works out to look about right\r\n  \r\n  \/\/ initialize sparks\r\n  for (int i = 0; i &lt; nSparks; i++) { \r\n    sparkPos[i] = flarePos; sparkVel[i] = (float(random16(0, 20000)) \/ 10000.0) - 1.0; \/\/ from -1 to 1 \r\n    sparkCol[i] = abs(sparkVel[i]) * 500; \/\/ set colors before scaling velocity to keep them bright \r\n    sparkCol[i] = constrain(sparkCol[i], 0, 255); \r\n    sparkVel[i] *= flarePos \/ NUM_LEDS; \/\/ proportional to height \r\n  } \r\n  sparkCol[0] = 255; \/\/ this will be our known spark \r\n  float dying_gravity = gravity; \r\n  float c1 = 120; \r\n  float c2 = 50; \r\n  while(sparkCol[0] &gt; c2\/128) { \/\/ as long as our known spark is lit, work with all the sparks\r\n    FastLED.clear();\r\n    for (int i = 0; i &lt; nSparks; i++) { \r\n      sparkPos[i] += sparkVel[i]; \r\n      sparkPos[i] = constrain(sparkPos[i], 0, NUM_LEDS); \r\n      sparkVel[i] += dying_gravity; \r\n      sparkCol[i] *= .99; \r\n      sparkCol[i] = constrain(sparkCol[i], 0, 255); \/\/ red cross dissolve \r\n      if(sparkCol[i] &gt; c1) { \/\/ fade white to yellow\r\n        leds[int(sparkPos[i])] = CRGB(255, 255, (255 * (sparkCol[i] - c1)) \/ (255 - c1));\r\n      }\r\n      else if (sparkCol[i] &lt; c2) { \/\/ fade from red to black\r\n        leds[int(sparkPos[i])] = CRGB((255 * sparkCol[i]) \/ c2, 0, 0);\r\n      }\r\n      else { \/\/ fade from yellow to red\r\n        leds[int(sparkPos[i])] = CRGB(255, (255 * (sparkCol[i] - c2)) \/ (c1 - c2), 0);\r\n      }\r\n    }\r\n    dying_gravity *= .995; \/\/ as sparks burn out they fall slower\r\n    FastLED.show();\r\n  }\r\n  FastLED.clear();\r\n  FastLED.show();\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>My first LED strip project was a vertical one-dimensional fireworks display. It&#8217;s 2 meters tall with 120 LEDs driven by an Arduino Uno. Here&#8217;s the code for the Arduino. boom.ino #include &lt;FastLED.h&gt; #define NUM_LEDS 120 #define DATA_PIN 6 CRGB leds[NUM_LEDS]; \/\/ sets up block of memory #define NUM_SPARKS 61 \/\/ max number (could be NUM_LEDS  [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":true,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[4],"class_list":["post-32","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-code"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p8pDaO-w","_links":{"self":[{"href":"https:\/\/www.anirama.com\/1000leds\/wp-json\/wp\/v2\/posts\/32","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.anirama.com\/1000leds\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.anirama.com\/1000leds\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.anirama.com\/1000leds\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.anirama.com\/1000leds\/wp-json\/wp\/v2\/comments?post=32"}],"version-history":[{"count":9,"href":"https:\/\/www.anirama.com\/1000leds\/wp-json\/wp\/v2\/posts\/32\/revisions"}],"predecessor-version":[{"id":504,"href":"https:\/\/www.anirama.com\/1000leds\/wp-json\/wp\/v2\/posts\/32\/revisions\/504"}],"wp:attachment":[{"href":"https:\/\/www.anirama.com\/1000leds\/wp-json\/wp\/v2\/media?parent=32"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.anirama.com\/1000leds\/wp-json\/wp\/v2\/categories?post=32"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.anirama.com\/1000leds\/wp-json\/wp\/v2\/tags?post=32"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}