Skip to content

Instantly share code, notes, and snippets.

@NealEhardt
Last active March 5, 2017 21:49
Show Gist options
  • Save NealEhardt/3be36efb0fccb13acf4c0ad5c839e265 to your computer and use it in GitHub Desktop.
Save NealEhardt/3be36efb0fccb13acf4c0ad5c839e265 to your computer and use it in GitHub Desktop.
Paints a sine wave pattern to a variable number of TLC5971 chips.
/*
* 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