I'm afraid I have to post a lengthy bit of code, because I can't pinpoint what's causing my issues – in short, it appears repeatedlyrepeatedly adding float position + float speedfloat position + float speed
in a struct ends up borking the whole thing.
I'm afraid I have to post a lengthy bit of code, because I can't pinpoint what's causing my issues – in short, it appears repeatedly adding float position + float speed in a struct ends up borking the whole thing.
I'm afraid I have to post a lengthy bit of code, because I can't pinpoint what's causing my issues – in short, it appears repeatedly adding float position + float speed
in a struct ends up borking the whole thing.
I'm afraid I have to post a lengthy bit of code, because I can't pinpoint what's causing my issues – in short, it appears repeatedly adding float position + float speed in a struct ends up borking the whole thing. Here's
The purpose of the code: is to animate at most MAX_PARTICLES
particles ("pixels") traveling at random speeds across the LED stripe.
The array named particles
stores the current list of particles being managed. Each particle in the array is stored as a struct, as defined at the beginning of the code. Particles are added to the array using function addParticle()
at the very end of the code. Particles which reach the end of the stripe are killed in the second part of the loop()
function (after FastLED.show()
).
Here's the code:
The purpose of the code is to animate at most MAX_PARTICLES particles ("pixels") traveling at random speeds across the LED stripe.
The array named particles stores the current list of particles being managed. Each particle in the array is stored as a struct, as defined at the beginning of the code. Particles are added to the array using function addParticle() at the very end of the code. Particles which reach the end of the stripe are killed in the second part of the loop() function (after FastLED.show()).
I'm afraid I have to post a lengthy bit of code, because I can't pinpoint what's causing my issues – in short, it appears repeatedly adding float position + float speed in a struct ends up borking the whole thing. Here's the code:
The purpose of the code is to animate at most MAX_PARTICLES particles ("pixels") traveling at random speeds across the LED stripe.
The array named particles stores the current list of particles being managed. Each particle in the array is stored as a struct, as defined at the beginning of the code. Particles are added to the array using function addParticle() at the very end of the code. Particles which reach the end of the stripe are killed in the second part of the loop() function (after FastLED.show()).
I'm afraid I have to post a lengthy bit of code, because I can't pinpoint what's causing my issues – in short, it appears repeatedly adding float position + float speed in a struct ends up borking the whole thing.
The purpose of the code is to animate at most MAX_PARTICLES
particles ("pixels") traveling at random speeds across the LED stripe.
The array named particles
stores the current list of particles being managed. Each particle in the array is stored as a struct, as defined at the beginning of the code. Particles are added to the array using function addParticle()
at the very end of the code. Particles which reach the end of the stripe are killed in the second part of the loop()
function (after FastLED.show()
).
Here's the code:
#define FASTLED_INTERNAL // Eliminates a compiler warning
#include <FastLED.h>
#include <colorutils.h>
#define NUM_LEDS 149
#define DATA_PIN 6
#define MAX_PARTICLES 5 // This uses up the memory, mostly
CRGB leds[NUM_LEDS];
struct particle {
float position;
CRGB color;
float speed;
int id;
};
typedef struct particle Particle;
Particle particles[MAX_PARTICLES];
int numParticles = 0;
int maxId = 0;
// Gramma Correctioncorrection tables (Defalt Gamma = 2.8)
const uint8_t PROGMEM gammaR[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5,
5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9,
9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 14, 14, 14,
15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
23, 24, 24, 25, 25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33,
33, 34, 35, 36, 36, 37, 38, 39, 40, 40, 41, 42, 43, 44, 45, 46,
46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
62, 63, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 78, 79, 80,
81, 83, 84, 85, 87, 88, 89, 91, 92, 94, 95, 97, 98, 99,101,102,
104,105,107,109,110,112,113,115,116,118,120,121,123,125,127,128,
130,132,134,135,137,139,141,143,145,146,148,150,152,154,156,158,
160,162,164,166,168,170,172,174,177,179,181,183,185,187,190,192,
194,196,199,201,203,206,208,210,213,215,218,220,223,225,227,230 };
const uint8_t PROGMEM gammaG[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };
const uint8_t PROGMEM gammaB[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 8,
8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11, 12, 12, 12, 13,
13, 13, 14, 14, 15, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 19,
20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 27, 27, 28, 28,
29, 30, 30, 31, 32, 32, 33, 34, 34, 35, 36, 37, 37, 38, 39, 40,
40, 41, 42, 43, 44, 44, 45, 46, 47, 48, 49, 50, 51, 51, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 69, 70,
71, 72, 73, 74, 75, 77, 78, 79, 80, 81, 83, 84, 85, 86, 88, 89,
90, 92, 93, 94, 96, 97, 98,100,101,103,104,106,107,109,110,112,
113,115,116,118,119,121,122,124,126,127,129,131,132,134,136,137,
139,141,143,144,146,148,150,152,153,155,157,159,161,163,165,167,
169,171,173,175,177,179,181,183,185,187,189,191,193,196,198,200 };
void setup() {
FastLED.addLeds<WS2812B, DATA_PIN, BGR>(leds, NUM_LEDS);
randomSeed(analogRead(0));
Serial.begin(115200);
}
void loop() {
if (numParticles < MAX_PARTICLES && random(10)>8) {
addParticle();
}
for (int i=0; i<numParticles; i++) {
// Antialiasing
int basePosition = floor(particles[i].position);
byte percentOnePos = round(255 * (particles[i].position-basePosition));
byte percentBasePos = 255 - percentOnePos;
CRGB color0 = particles[i].color % percentOnePos;
CRGB color1 = particles[i].color % percentBasePos;
leds[basePosition] += color0;
leds[basePosition+1] += color1;
}
// Apply gamma correction
for (int i=0; i<NUM_LEDS; i++) {
//leds[i] = applyGamma_video(leds[i], 2.2);
// *** applyGamma_video(2.2) pros and cons:
// PROs: smoother color transitions
// CONs: much slower; much worse color calibration
// TODO: pre-render custom, color calibrated gamma tables
leds[i].red = pgm_read_byte(&gammaR[leds[i].red]);
leds[i].green = pgm_read_byte(&gammaG[leds[i].green]);
leds[i].blue = pgm_read_byte(&gammaB[leds[i].blue]);
}
FastLED.show();
for (int i=0; i<numParticles; i++) {
int basePosition = floor(particles[i].position);
leds[basePosition] = CRGB::Black;
leds[basePosition+1] = CRGB::Black;
particles[i].position += particles[i].speed;
if (particles[i].position > (NUM_LEDS+1)) { // We want to render it fading out
for (int j = i; j<numParticles-1; j++) {
particles[j] = particles[j+1];
}
numParticles--;
i--; // We want the for() cycle to process the particle we shifted down
}
}
debugParticles();
}
void debugParticles()
{
for (int i = 0; i<MAX_PARTICLES; i++) {
if (i>0) {
Serial.print(", ");
}
Serial.print(i);
Serial.print(",");
Serial.print(particles[i].id);
Serial.print(",");
Serial.print(particles[i].position);
}
Serial.println("");
}
void addParticle()
{
particles[numParticles].color = CHSV(random8(),255,150);
particles[numParticles].position = 0;
particles[numParticles].speed = (0.0+random(10))/100+0.01;
particles[numParticles].id = maxId++;
numParticles++;
}
#define FASTLED_INTERNAL // Eliminates a compiler warning
#include <FastLED.h>
#include <colorutils.h>
#define NUM_LEDS 149
#define DATA_PIN 6
#define MAX_PARTICLES 5 // This uses up the memory, mostly
CRGB leds[NUM_LEDS];
struct particle {
float position;
CRGB color;
float speed;
int id;
};
typedef struct particle Particle;
Particle particles[MAX_PARTICLES];
int numParticles = 0;
int maxId = 0;
// Gramma Correction (Defalt Gamma = 2.8)
const uint8_t PROGMEM gammaR[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5,
5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9,
9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 14, 14, 14,
15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
23, 24, 24, 25, 25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33,
33, 34, 35, 36, 36, 37, 38, 39, 40, 40, 41, 42, 43, 44, 45, 46,
46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
62, 63, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 78, 79, 80,
81, 83, 84, 85, 87, 88, 89, 91, 92, 94, 95, 97, 98, 99,101,102,
104,105,107,109,110,112,113,115,116,118,120,121,123,125,127,128,
130,132,134,135,137,139,141,143,145,146,148,150,152,154,156,158,
160,162,164,166,168,170,172,174,177,179,181,183,185,187,190,192,
194,196,199,201,203,206,208,210,213,215,218,220,223,225,227,230 };
const uint8_t PROGMEM gammaG[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };
const uint8_t PROGMEM gammaB[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 8,
8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11, 12, 12, 12, 13,
13, 13, 14, 14, 15, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 19,
20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 27, 27, 28, 28,
29, 30, 30, 31, 32, 32, 33, 34, 34, 35, 36, 37, 37, 38, 39, 40,
40, 41, 42, 43, 44, 44, 45, 46, 47, 48, 49, 50, 51, 51, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 69, 70,
71, 72, 73, 74, 75, 77, 78, 79, 80, 81, 83, 84, 85, 86, 88, 89,
90, 92, 93, 94, 96, 97, 98,100,101,103,104,106,107,109,110,112,
113,115,116,118,119,121,122,124,126,127,129,131,132,134,136,137,
139,141,143,144,146,148,150,152,153,155,157,159,161,163,165,167,
169,171,173,175,177,179,181,183,185,187,189,191,193,196,198,200 };
void setup() {
FastLED.addLeds<WS2812B, DATA_PIN, BGR>(leds, NUM_LEDS);
randomSeed(analogRead(0));
Serial.begin(115200);
}
void loop() {
if (numParticles < MAX_PARTICLES && random(10)>8) {
addParticle();
}
for (int i=0; i<numParticles; i++) {
// Antialiasing
int basePosition = floor(particles[i].position);
byte percentOnePos = round(255 * (particles[i].position-basePosition));
byte percentBasePos = 255 - percentOnePos;
CRGB color0 = particles[i].color % percentOnePos;
CRGB color1 = particles[i].color % percentBasePos;
leds[basePosition] += color0;
leds[basePosition+1] += color1;
}
for (int i=0; i<NUM_LEDS; i++) {
//leds[i] = applyGamma_video(leds[i], 2.2);
// *** applyGamma_video(2.2) pros and cons:
// PROs: smoother color transitions
// CONs: much slower; much worse color calibration
// TODO: pre-render custom, color calibrated gamma tables
leds[i].red = pgm_read_byte(&gammaR[leds[i].red]);
leds[i].green = pgm_read_byte(&gammaG[leds[i].green]);
leds[i].blue = pgm_read_byte(&gammaB[leds[i].blue]);
}
FastLED.show();
for (int i=0; i<numParticles; i++) {
int basePosition = floor(particles[i].position);
leds[basePosition] = CRGB::Black;
leds[basePosition+1] = CRGB::Black;
particles[i].position += particles[i].speed;
if (particles[i].position > (NUM_LEDS+1)) { // We want to render it fading out
for (int j = i; j<numParticles-1; j++) {
particles[j] = particles[j+1];
}
numParticles--;
i--; // We want the for() cycle to process the particle we shifted down
}
}
debugParticles();
}
void debugParticles()
{
for (int i = 0; i<MAX_PARTICLES; i++) {
if (i>0) {
Serial.print(", ");
}
Serial.print(i);
Serial.print(",");
Serial.print(particles[i].id);
Serial.print(",");
Serial.print(particles[i].position);
}
Serial.println("");
}
void addParticle()
{
particles[numParticles].color = CHSV(random8(),255,150);
particles[numParticles].position = 0;
particles[numParticles].speed = (0.0+random(10))/100+0.01;
particles[numParticles].id = maxId++;
numParticles++;
}
#define FASTLED_INTERNAL // Eliminates a compiler warning
#include <FastLED.h>
#include <colorutils.h>
#define NUM_LEDS 149
#define DATA_PIN 6
#define MAX_PARTICLES 5 // This uses up the memory, mostly
CRGB leds[NUM_LEDS];
struct particle {
float position;
CRGB color;
float speed;
int id;
};
typedef struct particle Particle;
Particle particles[MAX_PARTICLES];
int numParticles = 0;
int maxId = 0;
// Gramma correction tables (Defalt Gamma = 2.8)
const uint8_t PROGMEM gammaR[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5,
5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9,
9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 14, 14, 14,
15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
23, 24, 24, 25, 25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33,
33, 34, 35, 36, 36, 37, 38, 39, 40, 40, 41, 42, 43, 44, 45, 46,
46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
62, 63, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 78, 79, 80,
81, 83, 84, 85, 87, 88, 89, 91, 92, 94, 95, 97, 98, 99,101,102,
104,105,107,109,110,112,113,115,116,118,120,121,123,125,127,128,
130,132,134,135,137,139,141,143,145,146,148,150,152,154,156,158,
160,162,164,166,168,170,172,174,177,179,181,183,185,187,190,192,
194,196,199,201,203,206,208,210,213,215,218,220,223,225,227,230 };
const uint8_t PROGMEM gammaG[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };
const uint8_t PROGMEM gammaB[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 8,
8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11, 12, 12, 12, 13,
13, 13, 14, 14, 15, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 19,
20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 27, 27, 28, 28,
29, 30, 30, 31, 32, 32, 33, 34, 34, 35, 36, 37, 37, 38, 39, 40,
40, 41, 42, 43, 44, 44, 45, 46, 47, 48, 49, 50, 51, 51, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 69, 70,
71, 72, 73, 74, 75, 77, 78, 79, 80, 81, 83, 84, 85, 86, 88, 89,
90, 92, 93, 94, 96, 97, 98,100,101,103,104,106,107,109,110,112,
113,115,116,118,119,121,122,124,126,127,129,131,132,134,136,137,
139,141,143,144,146,148,150,152,153,155,157,159,161,163,165,167,
169,171,173,175,177,179,181,183,185,187,189,191,193,196,198,200 };
void setup() {
FastLED.addLeds<WS2812B, DATA_PIN, BGR>(leds, NUM_LEDS);
randomSeed(analogRead(0));
Serial.begin(115200);
}
void loop() {
if (numParticles < MAX_PARTICLES && random(10)>8) {
addParticle();
}
for (int i=0; i<numParticles; i++) {
// Antialiasing
int basePosition = floor(particles[i].position);
byte percentOnePos = round(255 * (particles[i].position-basePosition));
byte percentBasePos = 255 - percentOnePos;
CRGB color0 = particles[i].color % percentOnePos;
CRGB color1 = particles[i].color % percentBasePos;
leds[basePosition] += color0;
leds[basePosition+1] += color1;
}
// Apply gamma correction
for (int i=0; i<NUM_LEDS; i++) {
//leds[i] = applyGamma_video(leds[i], 2.2);
// *** applyGamma_video(2.2) pros and cons:
// PROs: smoother color transitions
// CONs: much slower; much worse color calibration
// TODO: pre-render custom, color calibrated gamma tables
leds[i].red = pgm_read_byte(&gammaR[leds[i].red]);
leds[i].green = pgm_read_byte(&gammaG[leds[i].green]);
leds[i].blue = pgm_read_byte(&gammaB[leds[i].blue]);
}
FastLED.show();
for (int i=0; i<numParticles; i++) {
int basePosition = floor(particles[i].position);
leds[basePosition] = CRGB::Black;
leds[basePosition+1] = CRGB::Black;
particles[i].position += particles[i].speed;
if (particles[i].position > (NUM_LEDS+1)) { // We want to render it fading out
for (int j = i; j<numParticles-1; j++) {
particles[j] = particles[j+1];
}
numParticles--;
i--; // We want the for() cycle to process the particle we shifted down
}
}
debugParticles();
}
void debugParticles()
{
for (int i = 0; i<MAX_PARTICLES; i++) {
if (i>0) {
Serial.print(", ");
}
Serial.print(i);
Serial.print(",");
Serial.print(particles[i].id);
Serial.print(",");
Serial.print(particles[i].position);
}
Serial.println("");
}
void addParticle()
{
particles[numParticles].color = CHSV(random8(),255,150);
particles[numParticles].position = 0;
particles[numParticles].speed = (0.0+random(10))/100+0.01;
particles[numParticles].id = maxId++;
numParticles++;
}