Skip to content

Instantly share code, notes, and snippets.

@powerswitch
Created November 14, 2016 19:08
Show Gist options
  • Save powerswitch/421562ff3da76be5043a6b2c7b2c2f7b to your computer and use it in GitHub Desktop.
Save powerswitch/421562ff3da76be5043a6b2c7b2c2f7b to your computer and use it in GitHub Desktop.
Simple APA102 controller via serial and Arduino
int clk = 12;
int dat = 13;
int clockspeed = 0;
unsigned long timer;
#define MAXLEDS 19
byte ledred[MAXLEDS];
byte ledgreen[MAXLEDS];
byte ledblue[MAXLEDS];
byte sollred[MAXLEDS];
byte sollgreen[MAXLEDS];
byte sollblue[MAXLEDS];
bool blnk[MAXLEDS];
enum Colors
{
BLACK,
BLUE,
GREEN,
CYAN,
RED,
PURPLE,
YELLOW,
WHITE,
ALERTRED,
};
void clock()
{
digitalWrite(clk, LOW);
delay(clockspeed);
digitalWrite(clk, HIGH);
delay(clockspeed);
}
void send_data(byte data)
{
for (byte mask = 0; mask < 8; ++mask)
{
if (data & (128 >> mask))
{
digitalWrite(dat, HIGH);
}
else
{
digitalWrite(dat, LOW);
}
clock();
}
}
void start_frame()
{
digitalWrite(dat, LOW);
for (byte mask = 0; mask < 32; ++mask)
{
clock();
}
}
void write_led(byte r, byte g, byte b)
{
send_data(255);
send_data(b);
send_data(g);
send_data(r);
}
byte stepcalc(byte a, byte b, byte m=1)
{
// TODO: Improve!
if (a > b) return -m;
if (a < b) return m;
return 0;
}
void anim()
{
unsigned long now = millis();
bool toggle = false;
if (now - timer > 800)
{
toggle = true;
}
if (now - timer >= 1600)
{
timer = now;
}
for (byte i = 0; i < MAXLEDS; ++i)
{
ledred[i] += stepcalc(ledred[i], sollred[i] * blnk[i] * toggle, 2);
ledgreen[i] += stepcalc(ledgreen[i], sollgreen[i] * blnk[i] * toggle);
ledblue[i] += stepcalc(ledblue[i], sollblue[i] * blnk[i] * toggle, 2);
}
}
void refresh()
{
anim();
start_frame();
for (byte i = 0; i < MAXLEDS; ++i)
{
write_led(ledred[i], ledgreen[i], ledblue[i]);
}
}
void set_led(byte nr, byte r, byte g, byte b)
{
if (nr < MAXLEDS)
{
ledred[nr] = r;
ledgreen[nr] = g;
ledblue[nr] = b;
sollred[nr] = r;
sollgreen[nr] = g;
sollblue[nr] = b;
}
}
void schedule_led(byte nr, byte r, byte g, byte b)
{
if (nr < MAXLEDS)
{
sollred[nr] = r;
sollgreen[nr] = g;
sollblue[nr] = b;
}
}
void setup()
{
pinMode(clk, OUTPUT);
pinMode(dat, OUTPUT);
randomSeed(analogRead(0));
Serial.begin(9600);
for (byte r = 0; r < 10; ++r)
{
for (byte m = 0; m < MAXLEDS; ++m)
{
for (byte i = 0; i < MAXLEDS/3; ++i)
{
set_led((i+m)%MAXLEDS, MAXLEDS/3-i, i, 0);
set_led((i+MAXLEDS/3+m)%MAXLEDS, 0, MAXLEDS/3-i, i);
set_led((i+(MAXLEDS/3)*2+m)%MAXLEDS, i, 0, MAXLEDS/3-i);
}
refresh();
}
}
for (byte i = 0; i < MAXLEDS; ++i)
{
set_led(i, 0, 0, 0);
refresh();
}
timer = millis();
}
void set_color(byte nr, Colors c)
{
switch (c)
{
case BLACK:
schedule_led(nr, 0, 0, 0);
break;
case BLUE:
schedule_led(nr, 0, 0, 64);
break;
case GREEN:
schedule_led(nr, 0, 32, 0);
break;
case CYAN:
schedule_led(nr, 0, 32, 64);
break;
case RED:
schedule_led(nr, 64, 0, 0);
break;
case PURPLE:
schedule_led(nr, 64, 0, 64);
break;
case YELLOW:
schedule_led(nr, 64, 28, 0);
break;
case WHITE:
schedule_led(nr, 32, 32, 32);
break;
case ALERTRED:
schedule_led(nr, 200, 0, 0);
break;
}
}
void set_blinking(byte nr, bool onoff)
{
blnk[nr] = onoff;
}
void loop()
{
while (Serial.available() > 0)
{
String str;
str = Serial.readStringUntil(' ');
byte nr = Serial.parseInt();
if (str.endsWith("COLOR"))
{
str = Serial.readStringUntil('=');
str = Serial.readStringUntil('\n');
if (str.indexOf("BLACK") > -1)
set_color(nr, BLACK);
if (str.indexOf("BLUE") > -1)
set_color(nr, BLUE);
if (str.indexOf("GREEN") > -1)
set_color(nr, GREEN);
if (str.indexOf("CYAN") > -1)
set_color(nr, CYAN);
if (str.indexOf("RED") > -1)
set_color(nr, RED);
if (str.indexOf("PURPLE") > -1)
set_color(nr, PURPLE);
if (str.indexOf("YELLOW") > -1)
set_color(nr, YELLOW);
if (str.indexOf("WHITE") > -1)
set_color(nr, WHITE);
if (str.indexOf("ALERTRED") > -1)
set_color(nr, ALERTRED);
if (str.indexOf("BLINK") > -1)
set_blinking(nr, true);
else
set_blinking(nr, false);
}
else if (str.endsWith("VALUES"))
{
byte r = Serial.parseInt();
byte g = Serial.parseInt();
byte b = Serial.parseInt();
set_led(nr, r, g, b);
}
}
refresh();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment