Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "FastLED.h" // FastLED library. Preferably the latest copy of FastLED 2.1.
- //#include <SoftwareSerial.h>
- //potentionmeters
- int p0 = 0;
- int p1 = 0;
- int p2 = 0;
- int p3 = 0;
- int p4 = 0;
- int p5 = 0;
- int p6 = 0;
- int p7 = 0;
- int p8 = 0;
- int p9 = 0;
- int p10 = 0;
- int CurPatt = 0; //main function selector
- //strip definitions
- #define COLOR_ORDER GRB
- #define LED_TYPE WS2812 //WS2811
- #define NUM_LEDS 120
- struct CRGB leds[NUM_LEDS]; //init LED array
- uint8_t UPDATES_PER_SECOND = 1000;
- //pin definitions
- #define ledData 5 // Serial data pin for WS2812 or WS2801.
- #define ledSwitch 11
- //#define BUTTON_PIN 11
- // color macros
- #define qsubd(x, b) ((x>b)?wavebright:0) // Use qsuba for smooth pixel colouring and qsubd for non-smooth pixel colouring
- #define qsuba(x, b) ((x>b)?x-b:0)
- //constants
- #define h0 1 // Starting height, in meters, of the ball (strip length)
- const int NUM_BALLS = 3; // Number of bouncing balls you want (recommend < 7, but 20 is fun in its own way)
- // fire function vars
- int SPARKING = 20;
- int COOLING = 80;
- //bouncer vars
- float GRAVITY = -2.81; // Downward (negative) acceleration of gravity in m/s^2
- 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)
- //generic variables
- uint8_t max_bright = 128; // for patts that need to be dimmer
- uint8_t CurSpeed = 4; // main speed parmeter
- uint8_t CurBright = 4; //main brightness parameter
- bool oldState = HIGH;
- //ripple definitions and variables
- #define maxsteps 16 // Case statement wouldn't allow a variable.
- uint8_t colour; // Ripple colour is randomized.
- int center = 0; // Center of the current ripple.
- int step = -1; // -1 is the initializing step.
- uint8_t myfade = 128; // Starting brightness.
- uint8_t bgcol = 8; // Background colour rotates.
- int thisdelay = 50; // Standard delay value.
- //move defs
- uint8_t wavebright = 128; //You can change the brightness of the waves/bars rolling across the screen. Best to make them not as bright as the sparkles.
- uint8_t thishue = 0; //starting hue value for the this wave.
- uint8_t thathue = 140; //starting hue value for the that wave.
- uint8_t thisrot = 0; //how quickly the hue rotates for this wave.
- uint8_t thatrot = 0; //how quickly the hue rotates for that wave.
- uint8_t allsat = 255; //saturated with colour.
- uint8_t allfreq = 32; //frequency/width of bars.
- uint8_t thisphase = 0; //this phase change
- uint8_t thatphase = 0; //thatchange
- uint8_t thiscutoff = 192; //cutoff value to display this wave. Lower value = longer wave.
- uint8_t thatcutoff = 192; //cutoff value to display that wave.
- uint8_t twinkrun = 0; //Enable/disable twinkles.
- uint8_t thisdir = 0; //direction
- int8_t thisspeed = 4; //this speed.
- int8_t thatspeed = -4; //that speed.
- typedef struct { //structure for the twinkles
- int twinkled; // Supports a long strand of LED's.
- int twinkbright; // Defined as 'int', so that we can trigger change on a negative brightness value.
- } twinks;
- #define numtwinks 8 // You can change the number of twinkles.
- twinks mytwinks[numtwinks];
- // palette definitions
- CRGBPalette16 currentPalette;
- CRGBPalette16 gPal;
- TBlendType currentBlending;
- const TProgmemRGBPalette16 SALS_p PROGMEM =
- {
- 0xFF6600,
- 0xFF0000,
- 0xFF6600,
- 0x993300,
- 0xFF6600,
- 0x880000,
- 0xFF6600,
- 0x880000,
- 0xFF6600,
- 0xFF0000,
- 0xFF6600,
- 0x993300,
- 0xFF6600,
- 0x880000,
- 0xFF6600,
- 0x880000
- };
- const TProgmemPalette16 RWB_p PROGMEM =
- {
- CRGB::Red,
- CRGB::Gray, // 'white' is too bright compared to red and blue
- CRGB::Blue,
- CRGB::Black,
- CRGB::Red,
- CRGB::Gray,
- CRGB::Blue,
- CRGB::Black,
- CRGB::Red,
- CRGB::Red,
- CRGB::Gray,
- CRGB::Gray,
- CRGB::Blue,
- CRGB::Blue,
- CRGB::Black,
- CRGB::Black
- };
- void setup() {
- Serial.begin(4800);
- pinMode ( ledSwitch, INPUT );
- //palettes
- LEDS.addLeds<LED_TYPE, ledData,COLOR_ORDER>(leds, NUM_LEDS); // WS2812
- FastLED.setBrightness(max_bright);
- set_max_power_in_volts_and_milliamps(5, 8000);
- currentPalette = RainbowColors_p;
- //bouncer
- 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);
- }
- } // setup()
- //**********************************************************************************************************************************
- void loop()
- {
- getParams();
- if (CurPatt == 12)
- {
- random16_add_entropy(random());
- Fire2012WithPalette();
- FastLED.show(); // display this frame
- FastLED.delay(map(p2,0,1023,1,20) );
- }
- else if (CurPatt == 13)
- {
- bouncer();
- }
- else if (CurPatt == 14)
- {
- ripple();
- show_at_max_brightness_for_power();
- delay_at_max_brightness_for_power(thisdelay*1.5);
- }
- else if (CurPatt == 15)
- {
- ChangeMe(); // Muck those variable around.
- two_sin(); // Simple call to the routine.
- show_at_max_brightness_for_power();
- delay_at_max_brightness_for_power(thisdelay*1.5);
- }
- else if (CurPatt == 16)
- {
- ChangeMe(); // Muck those variable around.
- two_sin(); // Simple call to the routine.
- twinkleover(); // You can keep or lose the twinkles.
- show_at_max_brightness_for_power();
- delay_at_max_brightness_for_power(thisdelay*1.5);
- }
- else
- {
- RunManual();
- static uint8_t startIndex = 0;
- startIndex = startIndex + CurSpeed; /* motion speed */
- FillLEDsFromPaletteColors( startIndex);
- FastLED.show();
- FastLED.delay(30);
- }
- }
- //**********************************************************************************************************************************
- void getParams()
- {
- bool newState = digitalRead(ledSwitch);
- String settings;
- p0 = analogRead(A0);
- p0 = analogRead(A0);
- p1 = analogRead(A1);
- p1 = analogRead(A1);
- p2 = analogRead(A2);
- p2 = analogRead(A2);
- p3 = analogRead(A3);
- p3 = analogRead(A3);
- p4 = analogRead(A4);
- p4 = analogRead(A4);
- p5 = analogRead(A5);
- p5 = analogRead(A5);
- p6 = analogRead(A6);
- p6 = analogRead(A6);
- p7 = analogRead(A7);
- p7 = analogRead(A7);
- p8 = analogRead(A8);
- p8 = analogRead(A8);
- p9 = analogRead(A9);
- p9 = analogRead(A9);
- p10 = analogRead(A10);
- p10 = analogRead(A10);
- CurPatt = map(p0,0,1023,0,17);
- CurBright = map(p1,0,1023,1,255);
- CurSpeed = map(p2,0,1023,1,50);
- if (newState == LOW) {
- settings = "P0:"+ p0;
- settings = settings + " P1:"+ p1 + " P2:"+ p2 + " P3:"+ p3 + " P4:" + p4 + " P5:"+ p5 + " P6:" + p6 + " P7:"+ p7 + " P8:" + p8 + " P9:"+ p9 + " P10:"+ p10;
- Serial.println(settings);
- }
- }
- void RunManual()
- {
- switch (CurPatt)
- {
- case 0:
- currentPalette = SALS_p;
- break;
- case 1:
- currentPalette = RainbowColors_p;
- break;
- case 2:
- currentPalette = RainbowStripeColors_p;
- break;
- case 3:
- currentPalette = PartyColors_p;
- break;
- case 4:
- currentPalette = HeatColors_p;
- break;
- case 5:
- currentPalette = OceanColors_p;
- break;
- case 6:
- currentPalette = ForestColors_p;
- break;
- case 7:
- currentPalette = LavaColors_p;
- break;
- case 8:
- currentPalette = CloudColors_p;
- break;
- case 9:
- currentPalette = RWB_p;
- break;
- case 10:
- SetupPurpleAndGreenPalette();
- break;
- case 11:
- SetupBlackAndWhiteStripedPalette();
- break;
- }
- }// end manual
- void FillLEDsFromPaletteColors( uint8_t colorIndex)
- {
- uint8_t brightness = CurBright;
- for( int i = 0; i < NUM_LEDS; i++) {
- leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending);
- colorIndex += 3;
- }
- }
- void SetupPurpleAndGreenPalette()
- {
- CRGB purple = CHSV( HUE_PURPLE, 255, 255);
- CRGB green = CHSV( HUE_GREEN, 255, 255);
- CRGB black = CRGB::Black;
- currentPalette = CRGBPalette16(
- green, green, black, black,
- purple, purple, black, black,
- green, green, black, black,
- purple, purple, black, black );
- }
- void SetupBlackAndWhiteStripedPalette()
- {
- // 'black out' all 16 palette entries...
- fill_solid( currentPalette, 16, CRGB::Black);
- // and set every fourth one to white.
- currentPalette[0] = CRGB::White;
- currentPalette[4] = CRGB::White;
- currentPalette[8] = CRGB::White;
- currentPalette[12] = CRGB::White;
- }
- void Fire2012WithPalette()
- {
- currentPalette = HeatColors_p;
- SPARKING = map(p5,0,1023,5,80);
- COOLING = map(p4,0,1023,5,80);
- // Array of temperature readings at each simulation cell
- static byte heat[NUM_LEDS];
- // Step 1. Cool down every cell a little
- for( int i = 0; i < NUM_LEDS; i++) {
- heat[i] = qsub8( heat[i], random8(0, ((COOLING * 10) / NUM_LEDS) + 2));
- }
- // Step 2. Heat from each cell drifts 'up' and diffuses a little
- for( int k= NUM_LEDS - 1; k >= 2; k--) {
- heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
- }
- // Step 3. Randomly ignite new 'sparks' of heat near the bottom
- if( random8() < SPARKING ) {
- int y = random8(7);
- heat[y] = qadd8( heat[y], random8(160,240) );
- }
- // Step 4. Map from heat cells to LED colors
- for( int j = 0; j < NUM_LEDS; j++) {
- // Scale the heat value from 0-255 down to 0-240
- // for best results with color palettes.
- byte colorindex = scale8( heat[j], 230);
- leds[j] = ColorFromPalette( currentPalette, colorindex);
- }
- }
- void bouncer() {
- 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] * (NUM_LEDS - 1) / h0); // Map "h" to a "pos" integer index position on the LED strip
- }
- //Choose color of LEDs, then the "pos" LED on
- for (int i = 0 ; i < NUM_BALLS ; i++) leds[pos[i]] = CHSV( uint8_t (i * 40) , 255, 255);
- FastLED.show();
- //Then off for the next loop around
- for (int i = 0 ; i < NUM_BALLS ; i++) {
- leds[pos[i]] = CRGB::Black;
- }
- }
- void ripple() {
- thisdelay = map(p2,0,1023,1,20);
- for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(bgcol++, 255, CurBright/2); // Rotate background colour.
- switch (step) {
- case -1: // Initialize ripple variables.
- center = random(NUM_LEDS);
- colour = random16(0,256);
- step = 0;
- break;
- case 0:
- leds[center] = CHSV(colour, 255, 255); // Display the first pixel of the ripple.
- step ++;
- break;
- case maxsteps: // At the end of the ripples.
- step = -1;
- break;
- default: // Middle of the ripples.
- leds[wrap(center + step)] += CHSV(colour, 255, myfade/step*3); // Display the next pixels in the range for one side.
- leds[wrap(center - step)] += CHSV(colour, 255, myfade/step*3); // Display the next pixels in the range for the other side.
- step ++; // Next step.
- break;
- } // switch step
- } // ripple()
- int wrap(int step) {
- if(step < 0) return NUM_LEDS + step;
- if(step > NUM_LEDS - 1) return step - NUM_LEDS;
- return step;
- } // wrap()
- void ChangeMe() {
- wavebright = map(p1,0,1023,0,128);
- allfreq = map(p2,0,1023,1,128);
- thisspeed = map(p3,0,1023,-50,50);
- thatspeed = map(p4,0,1023,-50,50);
- thisrot = map(p5,0,1023,0,255);
- thatrot = map(p6,0,1023,0,255);
- thishue = map(p7,0,1023,0,255);
- thathue = map(p8,0,1023,0,255);
- thiscutoff = map(p9,0,1023,1,240);
- thatcutoff = map(p10,0,1023,1,240);
- } // ChangeMe()
- void two_sin() { // This is the heart of this program. Sure is short.
- if (thisdir == 0) {thisphase += thisspeed; thatphase += thatspeed;}
- else {thisphase -= thisspeed; thatphase -= thatspeed;}
- thishue = thishue + thisrot; // Hue rotation is fun for thiswave.
- thathue = thathue + thatrot; // It's also fun for thatwave.
- for (int k=0; k<NUM_LEDS-1; k++) {
- int thisbright = qsubd(cubicwave8((k*allfreq)+thisphase), thiscutoff); // qsub sets a minimum value called thiscutoff. If < thiscutoff, then bright = 0. Otherwise, bright = 128 (as defined in qsub)..
- int thatbright = qsubd(cubicwave8((k*allfreq)+128+thatphase), thatcutoff); // This wave is 180 degrees out of phase (with the value of 128).
- leds[k] = CHSV(thishue, allsat, thisbright); // Assigning hues and brightness to the led array.
- leds[k] += CHSV(thathue, allsat, thatbright);
- }
- } // two_sin()
- void twinkleover() { // This has been added for Mark Kriegsman.
- for (int i = 0; i < numtwinks; i++) {
- if (mytwinks[i].twinkbright <0) {
- mytwinks[i].twinkled = random8(0, NUM_LEDS-1);
- mytwinks[i].twinkbright = random8(230, 250);
- }
- leds[mytwinks[i].twinkled] = CHSV(150, 200, mytwinks[i].twinkbright); // Trying to make a soft white twinkle
- mytwinks[i].twinkbright -= 8;
- }
- } // twinkle()
Advertisement
Add Comment
Please, Sign In to add comment