Last active
March 5, 2017 21:49
-
-
Save NealEhardt/3be36efb0fccb13acf4c0ad5c839e265 to your computer and use it in GitHub Desktop.
Paints a sine wave pattern to a variable number of TLC5971 chips.
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
/* | |
* Paints a sine wave pattern to a variable number of TLC5971 chips. | |
* Animates with time on a 2-second loop. | |
* Assumes monochrome, but should look good on RGB too. | |
* Only tested on Arduino Due. Framerate may suffer on Uno. | |
* | |
* :: PACKET STRUCTURE :: | |
* 224 bit shift register | |
* | 32 bit header | |
* | 6 bit WC (Write Command) | |
* | 5 bit FC (Function Control) | |
* | 21 bit BC (Brightness Control) | |
* | 7 bit Blue (0-3) | |
* | 7 bit Green (0-3) | |
* | 7 bit Red (0-3) | |
* | 192 bit GS (GrayScale) | |
* | 16 bit Blue3 | |
* | 16 bit Green3 | |
* | 16 bit Red3 | |
* | 16 bit Blue2 | |
* ... | |
* | 16 bit Red0 | |
*/ | |
const int DATA = 2; // SDI pin | |
const int CLOCK = 3; // SCK pin | |
const int PACKET_BYTES = 28; | |
const int REGISTER_COUNT = 10; // How many chips are in series? | |
void setup() { | |
pinMode(DATA, OUTPUT); | |
pinMode(CLOCK, OUTPUT); | |
} | |
void writeHeaderToPacket(byte packet[], byte brightness = 0xFF) { | |
// Use a 32-bit long to collect 6 WC, 5 FC, and 21 BC | |
// |6 WC| | |
// |5FC| | |
long header = 0b10010100010 << (32-6-5); | |
// Use same brightness control for all 3 colors | |
brightness >>= 1; // cut brightness down to 7 bits | |
header |= brightness; // BC red | |
header |= (long)brightness << 7; // BC green | |
header |= (long)brightness << 7*2; // BC blue | |
// Copy to packet | |
packet[0] = header >> 8*3; | |
packet[1] = header >> 8*2; | |
packet[2] = header >> 8; | |
packet[3] = header; | |
} | |
void writeSineWaveToPacket(byte packet[], unsigned long t = millis(), | |
float phaseShift = 0, float period = 12) { | |
const static int C = (1 << 15) - 1; | |
const float iScale = 2*PI / period; | |
const static float tScale = 2*PI / 2000; // 2-second loop | |
const float tShift = t * tScale; | |
for (int i = 0; i < 12; i++) { | |
float angle = (i + phaseShift)*iScale + tShift; | |
int value = C*cos(angle) + C; | |
packet[i*2 + 4] = value >> 8; | |
packet[i*2 + 5] = value; | |
} | |
} | |
void writePacketToShiftRegister(byte packet[]) { | |
for (byte i = 0; i < PACKET_BYTES; i++) { | |
shiftOut(DATA, CLOCK, MSBFIRST, packet[i]); | |
} | |
} | |
void loop() { | |
byte packets[REGISTER_COUNT][PACKET_BYTES]; | |
// first, compute data for one frame | |
const unsigned long t = millis(); | |
for (int i = 0; i < REGISTER_COUNT; i++) { | |
writeHeaderToPacket(packets[i], 0x33); // brightness up to 0xFF | |
writeSineWaveToPacket(packets[i], t, 12*i, 12*REGISTER_COUNT); | |
} | |
// then, shift it all out | |
for (int i = 0; i < REGISTER_COUNT; i++) { | |
writePacketToShiftRegister(packets[i]); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment