Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "FastLED.h"
- // Pattern types supported:
- enum pattern {
- NONE,
- BOUNCINGBALL,
- RAINBOW_CYCLE,
- FIREALL,
- FIRESINGLE,
- THEATER_CHASE,
- COLOR_WIPE,
- COLOR_BOUNCE,
- SCANNER,
- FADE };
- // Patern directions supported:
- enum direction { FORWARD, REVERSE };
- #define NUM_LEDS 1200
- #define NUM_ROWS 8
- #define MAXNUM_LEDSPERROW 150
- CRGB leds[1200];
- //BouncingBalls
- #define GRAVITY -9.81 // Downward (negative) acceleration of gravity in m/s^2
- #define h0 5 // Starting height, in meters, of the ball (strip length)
- #define NUM_BALLS 8 // Number of bouncing balls you want (recommend < 7, but 20 is fun in its own way)
- ///// Hard code length of the strips ////////
- /*
- #define STRING1SIZE 20
- #define STRING2SIZE 20
- #define STRING3SIZE 20
- #define STRING4SIZE 20
- #define STRING5SIZE 20
- #define STRING6SIZE 20
- #define STRING7SIZE 20
- #define STRING8SIZE 20
- */
- #define STRING1SIZE 150
- #define STRING2SIZE 150
- #define STRING3SIZE 150
- #define STRING4SIZE 150
- #define STRING5SIZE 150
- #define STRING6SIZE 150
- #define STRING7SIZE 150
- #define STRING8SIZE 150
- // NeoPattern Class - derived from the Adafruit_NeoPixel class
- class TreePatterns
- {
- public:
- // Member Variables:
- pattern ActivePattern; // which pattern is running
- direction Direction; // direction to run the pattern
- uint16_t Row; // current row/branch to work on
- uint16_t RowSize; //totan length of row
- uint16_t NumRows;
- unsigned long Interval; // milliseconds between updates
- unsigned long lastUpdate; // last update of position
- uint32_t Color1, Color2; // What colors are in use
- uint16_t TotalSteps; // total number of steps in the pattern
- uint16_t Index; // current step within the pattern
- uint16_t EndIndex; //Endindex per pattern
- uint16_t LEDIndex; //start index of a given row
- uint16_t LEDEndIndex; //End of index of a given row
- //Fire2012 VARIABLES
- uint16_t COOLING;
- uint16_t SPARKING;
- uint8_t heat[NUM_ROWS][MAXNUM_LEDSPERROW];
- //BouncingBalls
- float h[NUM_BALLS] ; // An array of heights
- float vImpact0 = sqrt( -2 * GRAVITY * h0 ); // Impact velocity of the ball when it hits the ground if "dropped" from the top of the strip
- float vImpact[NUM_BALLS] ; // As time goes on the impact velocity will change, so make an array to store those values
- float tCycle[NUM_BALLS] ; // The time since the last time the ball struck the ground
- int pos[NUM_BALLS] ; // The integer position of the dot on the strip (LED index)
- long tLast[NUM_BALLS] ; // The clock time of the last ground strike
- float COR[NUM_BALLS] ; // Coefficient of Restitution (bounce damping)
- // Constructor - calls base-class constructor to initialize strip
- TreePatterns(uint16_t row)
- {
- Row = row;
- // FIND the size for the specific row/branch
- switch(Row)
- {
- case 1:
- RowSize = STRING1SIZE;
- LEDIndex = 0;
- LEDEndIndex = STRING1SIZE + LEDIndex -1 ;
- break;
- case 2:
- RowSize = STRING2SIZE;
- LEDIndex = MAXNUM_LEDSPERROW * (Row-1);
- LEDEndIndex = STRING2SIZE + LEDIndex -1 ;
- break;
- case 3:
- RowSize = STRING3SIZE;
- LEDIndex = MAXNUM_LEDSPERROW * (Row-1);
- LEDEndIndex = STRING3SIZE + LEDIndex-1 ;
- break;
- case 4:
- RowSize = STRING4SIZE;
- LEDIndex = MAXNUM_LEDSPERROW * (Row-1);
- LEDEndIndex = STRING4SIZE + LEDIndex - 1 ;
- break;
- case 5:
- RowSize = STRING5SIZE;
- LEDIndex = MAXNUM_LEDSPERROW * (Row-1);
- LEDEndIndex = STRING5SIZE + LEDIndex -1 ;
- break;
- case 6:
- RowSize = STRING6SIZE;
- LEDIndex = MAXNUM_LEDSPERROW * (Row-1);
- LEDEndIndex = STRING6SIZE + LEDIndex -1 ;
- break;
- case 7:
- RowSize = STRING7SIZE;
- LEDIndex = MAXNUM_LEDSPERROW * (Row-1);
- LEDEndIndex = STRING6SIZE + LEDIndex -1 ;
- break;
- case 8:
- RowSize = STRING8SIZE;
- LEDIndex = MAXNUM_LEDSPERROW * (Row-1);
- LEDEndIndex = STRING8SIZE + LEDIndex -1 ;
- break;
- case 9: //ALL STRINGS
- RowSize = NUM_LEDS;
- LEDIndex = 0;
- LEDEndIndex = NUM_LEDS - 1;
- NumRows = 8;
- break;
- default:
- break;
- }
- }
- // Update the pattern
- void Update()
- {
- if((millis() - lastUpdate) > Interval) // time to update
- {
- lastUpdate = millis();
- switch(ActivePattern)
- {
- case BOUNCINGBALL:
- BouncingBallUpdate();
- break;
- case FIRESINGLE:
- Fire2012SingleUpdate();
- break;
- case COLOR_WIPE:
- ColorWipeUpdate();
- break;
- case COLOR_BOUNCE:
- ColorBounceUpdate();
- break;
- case FIREALL:
- Fire2012AllUpdate();
- break;
- default:
- break;
- }
- }
- }
- // Increment the Index and reset at the end
- void Increment()
- {
- if (Direction == FORWARD)
- {
- Index++;
- if (Index >= LEDIndex + TotalSteps)
- {
- Index = LEDIndex;
- }
- }
- else // Direction == REVERSE
- {
- --Index;
- if (Index <= LEDIndex)
- {
- Index = LEDIndex + TotalSteps;
- }
- }
- }
- // Reverse pattern direction
- void Reverse()
- {
- if (Direction == FORWARD)
- {
- Direction = REVERSE;
- Index = LEDIndex + TotalSteps;
- }
- else
- {
- Direction = FORWARD;
- Index = LEDIndex;
- }
- }
- void Reflect()
- {
- if (Direction == FORWARD)
- {
- //Index++;
- Index = Index + 1;
- if (Index >= LEDEndIndex)
- {
- Direction = REVERSE;
- Index -1;
- }
- }
- else
- {
- //Index--;
- Index = Index - 1;
- if (Index <= LEDIndex)
- {
- Direction = FORWARD;
- }
- }
- }
- // Initialize for a ColorWipe
- void ColorWipe(uint32_t color, uint16_t interval,direction dir = FORWARD)
- {
- ActivePattern = COLOR_WIPE;
- Interval = interval;
- TotalSteps = RowSize;
- Color1 = color;
- Index = LEDIndex;
- EndIndex = LEDEndIndex;
- Direction = dir;
- }
- // Update the Color Wipe Pattern
- void ColorWipeUpdate()
- {
- leds[Index] = CRGB::Red;
- Increment();
- }
- // Initialize for a ColorWipe
- void ColorBounce(uint16_t interval)
- {
- ActivePattern = COLOR_BOUNCE;
- Interval = interval;
- Index = LEDIndex;
- EndIndex = LEDEndIndex;
- TotalSteps = RowSize;
- }
- // Update the Color Wipe Pattern
- void ColorBounceUpdate()
- {
- for(int i = LEDIndex; i <= LEDEndIndex; i++ )
- {
- Serial.print("forI is: ");
- Serial.println(i);
- Serial.print("forLEDIndex is: ");
- Serial.println(LEDIndex);
- //delay(500);
- if (i == Index)
- {
- Serial.print("if I is Index: ");
- Serial.print(i);
- Serial.println(" colorgreen ");
- leds[i] = CHSV(100, 100, 255);}
- else {
- Serial.print("elseI is: ");
- Serial.println(i);
- // delay(500);
- leds[i] = CHSV(0, 0, 0);}
- }
- //FastLED.show();
- Reflect();
- Serial.println("loop");
- // delay(2000);
- }
- void Fire2012All(uint16_t cool, uint16_t spark,uint16_t interval)
- {
- ActivePattern = FIREALL;
- Interval = interval;
- Index = LEDIndex;
- EndIndex = LEDEndIndex;
- TotalSteps = RowSize;
- COOLING = cool;
- SPARKING = spark;
- }
- void Fire2012AllUpdate()
- {
- // Array of temperature readings at each simulation cell
- // static byte heat[NUM_ROWS-1][NUM_LEDS];
- for (uint8_t row = 0; row < NUM_ROWS; row++) {
- // Step 1. Cool down every cell a little
- for( int i = 0; i < MAXNUM_LEDSPERROW; i++) {
- heat[row][i] = qsub8( heat[row][i], random8(0, ((COOLING * 10) / MAXNUM_LEDSPERROW) + 2));
- }
- // Step 2. Heat from each cell drifts 'up' and diffuses a little
- for( int k= MAXNUM_LEDSPERROW - 3; k > 0; k--) {
- heat[row][k] = (heat[row][k - 1] + heat[row][k - 2] + heat[row][k - 2] ) / 3;
- }
- // Step 3. Randomly ignite new 'sparks' of heat near the bottom
- if( random8() < SPARKING ) {
- int y = random8(7);
- heat[row][y] = qadd8( heat[row][y], random8(160,255) );
- }
- // Step 4. Map from heat cells to LED colors
- for( int j = 0; j < MAXNUM_LEDSPERROW; j++) {
- leds[XY(row,j)] = HeatColor( heat[row][j]);
- }
- }
- }
- void Fire2012Single(uint16_t cool, uint16_t spark,uint8_t row, uint16_t interval)
- {
- ActivePattern = FIRESINGLE;
- Interval = interval;
- Index = LEDIndex;
- EndIndex = LEDEndIndex;
- TotalSteps = RowSize;
- COOLING = cool;
- SPARKING = spark;
- Row = row-1;
- }
- void Fire2012SingleUpdate()
- {
- // Array of temperature readings at each simulation cell
- // static byte heat[NUM_ROWS-1][NUM_LEDS];
- // Step 1. Cool down every cell a little
- for( int i = Index; i < MAXNUM_LEDSPERROW; i++) {
- heat[Row][i] = qsub8( heat[Row][i], random8(0, ((COOLING * 10) / MAXNUM_LEDSPERROW) + 2));
- }
- // Step 2. Heat from each cell drifts 'up' and diffuses a little
- for( int k= MAXNUM_LEDSPERROW - 3; k > 0; k--) {
- heat[Row][k] = (heat[Row][k - 1] + heat[Row][k - 2] + heat[Row][k - 2] ) / 3;
- }
- // Step 3. Randomly ignite new 'sparks' of heat near the bottom
- if( random8() < SPARKING ) {
- int y = random8(7);
- heat[Row][y] = qadd8( heat[Row][y], random8(160,255) );
- }
- // Step 4. Map from heat cells to LED colors
- for( int j = 0; j < MAXNUM_LEDSPERROW; j++) {
- leds[XY(Row,j)] = HeatColor( heat[Row][j]);
- }
- }
- // Initialize for a ColorWipe
- void BouncingBall(uint16_t row)
- {
- ActivePattern = BOUNCINGBALL;
- TotalSteps = RowSize;
- Index = LEDIndex;
- EndIndex = LEDEndIndex;
- Row = row-1;
- for (int i = 0 ; i < NUM_BALLS ; i++) { // Initialize variables
- tLast[i] = millis();
- h[i] = h0;
- pos[i] = 0; // Balls start on the ground
- vImpact[i] = vImpact0; // And "pop" up at vImpact0
- tCycle[i] = 0;
- COR[i] = 0.90 - float(i)/pow(NUM_BALLS,2);
- }
- }
- // Update the Color Wipe Pattern
- void BouncingBallUpdate()
- {
- for (int i = 0 ; i < NUM_BALLS ; i++) {
- tCycle[i] = millis() - tLast[i] ; // Calculate the time since the last time the ball was on the ground
- // A little kinematics equation calculates positon as a function of time, acceleration (gravity) and intial velocity
- h[i] = 0.5 * GRAVITY * pow( tCycle[i]/1000 , 2.0 ) + vImpact[i] * tCycle[i]/1000;
- if ( h[i] < 0 ) {
- h[i] = 0; // If the ball crossed the threshold of the "ground," put it back on the ground
- vImpact[i] = COR[i] * vImpact[i] ; // and recalculate its new upward velocity as it's old velocity * COR
- tLast[i] = millis();
- if ( vImpact[i] < 0.01 ) vImpact[i] = vImpact0; // If the ball is barely moving, "pop" it back up at vImpact0
- }
- pos[i] = round( h[i] * (TotalSteps - 1) / h0); // Map "h" to a "pos" integer index position on the LED strip
- Serial.println("initial value is: ");
- Serial.print(Row);
- Serial.print(" | | ");
- Serial.print(tCycle[i]);
- Serial.print(" | | ");
- Serial.print(tLast[i]);
- Serial.print(" | | ");
- Serial.print(h[i]);
- Serial.print(" | | ");
- Serial.print(vImpact[i]);
- Serial.print(" | | ");
- Serial.print(h0);
- Serial.print(" | | ");
- Serial.print(pos[i]);
- Serial.print(" | | end");
- }
- //Choose color of LEDs, then the "pos" LED on
- for (int i = 0 ; i < NUM_BALLS ; i++)
- {
- leds[XY(Row,pos[i])] = CHSV( uint8_t (i * 40) , 255, 255);
- Serial.println("BALLRow value is: ");
- Serial.print(Row);
- Serial.print("pos value is: ");
- Serial.print(pos[i]);
- Serial.print("XY value is: ");
- Serial.print(XY(Row,pos[i]));
- }
- delay(50);
- FastLED.show();
- //Then off for the next loop around
- for (int i = 0 ; i < NUM_BALLS ; i++) {
- leds[XY(Row,pos[i])] = CRGB::Black;
- Serial.println("BLACKRow value is: ");
- Serial.print(Row);
- Serial.print("XY value is: ");
- Serial.print(XY(Row,pos[i]));
- }
- //for (int i = LEDIndex ; i < TotalSteps ; i++) {
- //leds[i].nscale8(195);
- // leds[XY(Row,i)].nscale8(195);
- // }
- /*
- for (int i = 0 ; i < NUM_BALLS ; i++) {
- leds[pos[i]] = CRGB::Black;
- }
- */
- }
- };
- TreePatterns Branch1(1);
- TreePatterns Branch2(2);
- TreePatterns Branch3(3);
- TreePatterns Branch4(4);
- TreePatterns Branch5(5);
- TreePatterns Branch6(6);
- TreePatterns AllBranches(9);
- // Initialize everything and prepare to start
- void setup()
- {
- delay(5000);
- Serial.begin(115200);
- FastLED.addLeds<WS2812B, 2, GRB>(leds, MAXNUM_LEDSPERROW * 0, MAXNUM_LEDSPERROW);
- FastLED.addLeds<WS2812B, 14, GRB>(leds, MAXNUM_LEDSPERROW * 1, MAXNUM_LEDSPERROW);
- FastLED.addLeds<WS2812B, 7, GRB>(leds, MAXNUM_LEDSPERROW * 2, MAXNUM_LEDSPERROW);
- FastLED.addLeds<WS2812B, 8, GRB>(leds, MAXNUM_LEDSPERROW * 3, MAXNUM_LEDSPERROW);
- FastLED.addLeds<WS2812B, 6, GRB>(leds, MAXNUM_LEDSPERROW * 4, MAXNUM_LEDSPERROW);
- FastLED.addLeds<WS2812B, 20, GRB>(leds, MAXNUM_LEDSPERROW * 5, MAXNUM_LEDSPERROW);
- FastLED.addLeds<WS2812B, 21, GRB>(leds, MAXNUM_LEDSPERROW * 6, MAXNUM_LEDSPERROW);
- FastLED.addLeds<WS2812B, 5, GRB>(leds, MAXNUM_LEDSPERROW * 7, MAXNUM_LEDSPERROW);
- FastLED.setBrightness(30);
- // Kick off a pattern
- //Branch1.ColorWipe(255, 1000);
- //Branch2.ColorWipe(255, 150);
- Branch2.ColorBounce(200);
- //Branch3.ColorBounce(500);
- Branch4.ColorWipe(255, 1000);
- Branch5.ColorBounce(500);
- Branch1.Fire2012Single(75, 140, 1, 50);
- Branch3.BouncingBall(3);
- AllBranches.Fire2012All(55, 140, 50);
- }
- // Main loop
- void loop()
- {
- random16_add_entropy( random());
- // Update the rings.
- //Fire2012();
- Branch1.Update();
- Branch2.Update();
- Branch3.Update();
- Branch4.Update();
- Branch5.Update();
- Branch6.Update();
- //AllBranches.Update();
- FastLED.show();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement