/******************************************************************************
* Addressable LED Strip Fireworks Show
* By Joe Larson, the 3D Printing Professor
* http://3dpprofessor.com
******************************************************************************/
#include "FastLED.h"
/***************************************
* Hardware definitions *
***************************************/
#define NUM_LEDS 20
#define LED_DATA_PIN 3
#define POT_PIN A3
/***************************************/
#define Brightness 255
CRGB leds[NUM_LEDS];
int curmode = 1;
CRGBPalette16 gPal;
void setup()
{
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(POT_PIN, INPUT);
randomSeed(analogRead(A0));
FastLED.addLeds<WS2812B, LED_DATA_PIN, GRB>(leds, NUM_LEDS); // Added "GRB" for my manufacturer who decided to mix up the colors
FastLED.setBrightness(Brightness);
}
const int numModes = 4;
void loop()
{
fireworks();
}
/******************************************************************************/
const int numsparks = NUM_LEDS/3;
uint8_t fworkType[numsparks];
float fworkHeat[numsparks];
CRGB fworkColor[numsparks];
float fworkLocation[numsparks];
float fworkVelocity[numsparks];
void fireworks()
{
fadeToBlackBy(leds, NUM_LEDS, 96);
//fill_solid(leds, NUM_LEDS, CRGB::Black);
if (sparkCount() == 0 || random(100) <= 2) // randomly fire off a new one
{
newSpark(1, CRGB(29, 48, 48), 0, 1.5 + (float)random(13)/4.0);
}
updateFireworks();
showFireworks();
FastLED.show();
delay(50);
}
void updateFireworks()
{
for (int i = 0; i < numsparks; i++)
{
switch (fworkType[i])
{
case 0:
break;
case 1: // rising
//fworkLocation[i] += constrain(fworkVelocity[i], -1.0, 1.0);
//fworkVelocity[i] -= .08; // gravity
fworkLocation[i] = random(6,13);
fworkVelocity[i] = 0.99; // gravity
if (fworkVelocity[i] < 1.0) { // Explode
fworkType[i] = 0;
int numNew = 4 + random16(4);
float newDiamter = ((float)random16(4) / 3.0) + 1.0;
CRGB newColor = CHSV(random(255), 192, 255);
for (int j = 0; j < numNew; j++)
{
float newVel = (newDiamter / 2.0) - ((newDiamter/(float)numNew) * (float)(j));
newSpark(2, newColor, fworkLocation[i]+newVel, newVel + (float)random16(10)/20.0);
}
}
break;
case 2: // exploding
fworkLocation[i] += fworkVelocity[i];
fworkHeat[i] -= 0.07;
if (fworkHeat[i] <= 0)
{
fworkType[i] = 0;
}
else if (fworkHeat[i] < 0.5)
{
fworkColor[i] -= CRGB(128,128,128);
fworkVelocity[i] /= 3;
if (random8(100) < 50)
fworkVelocity[i] += 0.05;
else
fworkVelocity[i] -= 0.05;
if (random8(100) < 50)
fworkColor[i] += CRGB(25,25,25);
else
fworkColor[i] -= CRGB(25,25,25);
}
break;
}
}
}
void newSpark(uint8_t type, CRGB newCol, int newLoc, float newVel)
{
int newfirework = nextdead();
if (newfirework < 0)
{
//Serial.println("Out of new sparks for now");
return;
}
fworkType[newfirework] = type;
fworkHeat[newfirework] = 1.0;
fworkColor[newfirework] = newCol;
fworkLocation[newfirework] = newLoc;
fworkVelocity[newfirework] = newVel;
}
void showFireworks()
{
for (int i = 0; i < numsparks; i++)
{
//Serial.print(fworkVelocity[i]); Serial.print(",");
if (fworkType[i] > 0)
{
if ((fworkLocation[i] < 0)|| (fworkLocation[i] >= NUM_LEDS))
{
fworkType[i] = 0; // just kill it if it goes out of bounds.
}
else
{
leds[(int)fworkLocation[i]] += fworkColor[i];
}
}
}
//Serial.println();
}
int sparkCount()
{
int retval = 0;
for (int i = 0; i < numsparks; i++)
if (fworkType[i] > 0)
retval++;
return retval;
}
int nextdead()
{
for (int i = 0; i < numsparks; i++)
{
if (fworkType[i] == 0)
return i;
}
return -1;
}
uno:A5.2
uno:A4.2
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
neopixels:DOUT
neopixels:VDD
neopixels:VSS
neopixels:DIN