Skip to content

Instantly share code, notes, and snippets.

@neckro
Created September 6, 2012 02:06
Show Gist options
  • Save neckro/3649899 to your computer and use it in GitHub Desktop.
Save neckro/3649899 to your computer and use it in GitHub Desktop.
LED chasers with LPD8806 controller
// uses https://github.com/neckro/LPD8806
#include "LPD8806.h"
#include "SPI.h"
// strip settings
const uint16_t PIXEL_LENGTH = 32;
// tracer settings
#define NUM_TRACERS 4
const int16_t MIN_POSRATE = 2;
const int16_t MAX_POSRATE = 8;
const int16_t MIN_FADERATE = 1;
const int16_t MAX_FADERATE = 16;
const int16_t MIN_HUERATE = 1;
const int16_t MAX_HUERATE = 4;
const uint16_t MIN_TTL = 1024;
const uint16_t MAX_TTL = 4096;
const uint8_t MAX_ALPHA = 127;
const uint8_t SYMMETRY = 1;
// static multipliers
const uint16_t ALPHA_MULT = 256;
const uint16_t HUE_MULT = 128;
// computed
const uint32_t HUE_MAX = (HUE_MULT * 384);
const uint32_t POS_MAX = (PIXEL_LENGTH * 128);
const int32_t FADE_MAX = (ALPHA_MULT * MAX_ALPHA);
// SPI, data = pin 11, clock = pin 13
LPD8806 strip = LPD8806(PIXEL_LENGTH);
uint8_t n;
struct tracer {
uint16_t pos;
uint16_t hue;
int32_t fade;
int32_t ttl;
int16_t pos_rate;
int16_t hue_rate;
int16_t fade_rate;
};
tracer tr[NUM_TRACERS];
void setup() {
Serial.begin(9600);
strip.begin();
for(int n=0; n<NUM_TRACERS; n++) {
Populate(n);
}
}
void loop() {
strip.clear();
for (uint8_t n=0; n<NUM_TRACERS; n++) {
// update parameters
tr[n].ttl--;
tr[n].pos = (tr[n].pos + tr[n].pos_rate) % POS_MAX;
tr[n].hue = (tr[n].hue + tr[n].hue_rate) % HUE_MAX;
// check and update fade
uint8_t alpha = MAX_ALPHA;
if (tr[n].fade < 0) {
// currently fading in
tr[n].fade = tr[n].fade + tr[n].fade_rate;
// correct for an overshoot
if (tr[n].fade > 0)
tr[n].fade = 0;
alpha = MAX_ALPHA + (tr[n].fade / ALPHA_MULT);
} else if (tr[n].ttl < 0) {
// currently fading out
tr[n].fade = tr[n].fade + tr[n].fade_rate;
// check for extinction
if (tr[n].fade > FADE_MAX) {
Populate(n);
alpha = 0;
} else {
alpha = MAX_ALPHA - (tr[n].fade / ALPHA_MULT);
}
} else {
// not fading, keep max alpha
}
for (uint8_t s=0; s<SYMMETRY; s++) {
strip.renderSubPixel(
((s * POS_MAX / SYMMETRY) + tr[n].pos) % POS_MAX,
HueColor(tr[n].hue / HUE_MULT),
alpha
);
}
/* debug
if (Serial.available() > 0) {
Serial.read();
Serial.print("Tracer ");
Serial.print(n);
Serial.print(": Pos ");
Serial.print(tr[n].pos);
Serial.print(", Hue ");
Serial.print(tr[n].hue);
Serial.print(", Alpha ");
Serial.print(alpha);
Serial.print(", TTL ");
Serial.print(tr[n].ttl);
Serial.print(", Fade ");
Serial.print(tr[n].fade);
Serial.print(", Faderate ");
Serial.println(tr[n].fade_rate);
}
*/
}
strip.show();
}
void Populate(uint8_t index) {
tr[index].pos = random(POS_MAX);
tr[index].hue = random(HUE_MAX);
tr[index].fade = -FADE_MAX;
tr[index].ttl = random(MIN_TTL, MAX_TTL);
tr[index].fade_rate = random(MIN_FADERATE, MAX_FADERATE);
tr[index].pos_rate = random(-MAX_POSRATE, MAX_POSRATE);
if (tr[index].pos_rate == 0)
tr[index].pos_rate = MAX_POSRATE;
tr[index].hue_rate = random(-MAX_HUERATE, MAX_HUERATE);
if (tr[index].hue_rate == 0)
tr[index].hue_rate = MAX_HUERATE;
}
uint32_t HueColor(uint16_t h)
// hue is 0 to 383
{
byte r, g, b;
switch((h / 128) % 3) {
case 0:
r = 127 - (h % 128); // Red down
g = h; // Green up
b = 0; // Blue off
break;
case 1:
g = 127 - (h % 128); // Green down
b = h % 128; // Blue up
r = 0; // Red off
break;
case 2:
b = 127 - (h % 128); // Blue down
r = h % 128; // Red up
g = 0; // Green off
break;
}
return(strip.Color(r,g,b));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment