Woops, pressed ENTER too fast.
So the idea is: a ball in the original bouncing balls code is 1 LED.
To make it more visible, I added a function "DrawBall", which draws an individual ball at a given location.
The position on the LED strand is the center of the ball.
We additionally pass it the ball colors (red, green, blue), how much the additional LEDs should dim in brightness, and the amount of extra LEDs we'd like to add left and right of the original center LED.
void DrawBall(int ballPosition, byte red, byte green, byte blue, byte dimming, byte ExtraSidePixelCount);
For an example of the picture in the previous post;
DrawBall(Position,colors[0],colors[1],colors[2], 220, 2);
1) The ball is drawn with "Position" as the center.
2) We use the red, green and blue values "colors[0],colors[1],colors[2]".
3) All LEDs, except the center LED, will be dimmed by 220, which seemed like a nice value - but feel free to play with it. As far as I know, 250 will most likely make the LED go OFF.
4) We add 2 LEDs on the left and on the right of the center LED.
If I'd want to make it totally perfect then I gradually dim the extra LEDs, instead of taking just one value, but while testing I kind-a already liked it this way.
Hope this results in a better effect - I assume you'd try with adding 2 LEDs as in the code below, but you could most certainly try more.
Please note that this will only work with the FastLED library since we need to have the fadeLightBy function:
The full code:
#include "FastLED.h"
#define NUM_LEDS 60 // Total strip length
#define HALFLEDS 30 // One half LED count
CRGB leds[NUM_LEDS];
#define PIN 6
void setup()
{
FastLED.addLeds<WS2811, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
}
// REPLACE FROM HERE
void loop() {
byte colors[3][3] = { {0xff, 0,0},
{0xff, 0xff, 0xff},
{0 , 0 , 0xff} };
BouncingColoredBalls(3, colors);
}
void BouncingColoredBalls(int BallCount, byte colors[][3]) {
float Gravity = -9.81;
int StartHeight = 1;
float Height[BallCount];
float ImpactVelocityStart = sqrt( -2 * Gravity * StartHeight );
float ImpactVelocity[BallCount];
float TimeSinceLastBounce[BallCount];
int Position[BallCount];
long ClockTimeSinceLastBounce[BallCount];
float Dampening[BallCount];
for (int i = 0 ; i < BallCount ; i++) {
ClockTimeSinceLastBounce = millis();
Height = StartHeight;
Position = 0;
ImpactVelocity = ImpactVelocityStart;
TimeSinceLastBounce = 0;
Dampening = 0.90 - float(i)/pow(BallCount,2);
}
while (true) {
for (int i = 0 ; i < BallCount ; i++) {
TimeSinceLastBounce = millis() - ClockTimeSinceLastBounce;
Height = 0.5 * Gravity * pow( TimeSinceLastBounce/1000 , 2.0 ) + ImpactVelocity * TimeSinceLastBounce/1000;
if ( Height < 0 ) {
Height = 0;
ImpactVelocity = Dampening * ImpactVelocity;
ClockTimeSinceLastBounce = millis();
if ( ImpactVelocity < 0.01 ) {
ImpactVelocity = ImpactVelocityStart;
}
}
Position = round( Height * (HALFLEDS - 1) / StartHeight);
}
for (int i = 0 ; i < BallCount ; i++) {
// Leftside; (chnage 220 for dimming, and 2 for number of extra LEDs on each side)
DrawBall(Position,colors[0],colors[1],colors[2], 220, 2);
// Rightside;
DrawBall(NUM_LEDS-Position-1,colors[0],colors[1],colors[2], 220, 2);
}
showStrip();
setAll(0,0,0);
}
}
void DrawBall(int ballPosition, byte red, byte green, byte blue, byte dimming, byte ExtraSidePixelCount) {
// LEDs before the center LED
for(int counter=1; counter<=ExtraSidePixelCount; counter++) {
if(ballPosition-counter>=0) {
setPixel(ballPosition-counter,red,green,blue);
leds[ballPosition-counter].fadeLightBy( dimming );
}
}
// Center LED
setPixel(ballPosition,red,green,blue);
// LEDs after the center LED
for(int counter=1; counter<=ExtraSidePixelCount; counter++) {
if(ballPosition+counter<HALFLEDS) {
setPixel(ballPosition+counter,red,green,blue);
leds[ballPosition+counter].fadeLightBy( dimming );
}
}
}
// REPLACE TO HERE
void showStrip() {
#ifdef ADAFRUIT_NEOPIXEL_H
// NeoPixel
strip.show();
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
// FastLED
FastLED.show();
#endif
}
void setPixel(int Pixel, byte red, byte green, byte blue) {
#ifdef ADAFRUIT_NEOPIXEL_H
// NeoPixel
strip.setPixelColor(Pixel, strip.Color(red, green, blue));
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
// FastLED
leds[Pixel].r = red;
leds[Pixel].g = green;
leds[Pixel].b = blue;
#endif
}
void setAll(byte red, byte green, byte blue) {
for(int i = 0; i < NUM_LEDS; i++ ) {
setPixel(i, red, green, blue);
}
showStrip();
}