Created
November 14, 2016 19:08
-
-
Save powerswitch/421562ff3da76be5043a6b2c7b2c2f7b to your computer and use it in GitHub Desktop.
Simple APA102 controller via serial and Arduino
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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