Skip to content

Instantly share code, notes, and snippets.

@hsiboy
Created January 16, 2015 13:46
Show Gist options
  • Save hsiboy/41c5a645efd396243229 to your computer and use it in GitHub Desktop.
Save hsiboy/41c5a645efd396243229 to your computer and use it in GitHub Desktop.
WS2811 - bounce using FastLed
// stolen from https://github.com/fibonacci162
#include <FastLED.h>
#define LED_PIN 13 // hardware SPI pin SCK
#define NUM_LEDS 250
#define COLOR_ORDER RGB
#define LED_TYPE WS2811
#define MAX_BRIGHTNESS 255 // watch the power!
#define GRAVITY -9.81 // Downward (negative) acceleration of gravity in m/s^2
#define h0 1 // Starting height, in meters, of the ball (strip length)
#define NUM_BALLS 3 // Number of bouncing balls you want (recommend < 7, but 20 is fun in its own way)
struct CRGB leds[NUM_LEDS];
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)
void setup() {
delay(3000);
LEDS.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(MAX_BRIGHTNESS);
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);
}
}
void loop() {
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;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment