I picked up an Octobrite from www.macetech.com at Maker Faire last weekend and finally got around to trying it out. Here’s some code that works for a single Octobrite, and should work for multiple daisy-chained together as well.
/*
- Octobrite Test
- 6/8/2009 - yergacheffe@yerga.com
- Cycles a continuous color cycle through the 8 leds
*/// Color channel constants
#define RED 0
#define GREEN 1
#define BLUE 2// TLC5947 maintains 12 bits of grayscale per LED channel
#define CHANNEL_BITS 12
#define CHANNEL_MAX ( (1<<CHANNEL_BITS) - 1)// TLC5947 pins
int SIN_PIN = 8;
int SCLK_PIN = 9;
int BLANK_PIN = 10;
int XLAT_PIN = 11;// Interpolation constants
int lerpsteps = 5;
int stepdelay = 25;int lerpindex = 0;
// Color table and current/prev color state. The interpolation looks
// best when only one channel is changing during an interpolation
// between a pair of adjacent colors.
int colorCount = 6;
int clutred[6] = { 1, 1, 0, 0, 0, 1};
int clutgreen[6] = { 0, 0, 0, 1, 1, 1};
int clutblue[6] = { 0, 1, 1, 1, 0, 0};
int currentColorIndex = 0;
int previousColor[3];
int currentColor[3];void setup()
{
// Setup TLC5947 pins
pinMode(SIN_PIN, OUTPUT);
pinMode(SCLK_PIN, OUTPUT);
pinMode(BLANK_PIN, OUTPUT);
pinMode(XLAT_PIN, OUTPUT);// Turn off all LEDs
digitalWrite(BLANK_PIN, HIGH);// Default state for clock and data latch
digitalWrite(SCLK_PIN, LOW);
digitalWrite(XLAT_PIN, LOW);// Init comms for debug info
Serial.begin(9600);// Reset color state
currentColor = clutred[currentColorIndex];
currentColor = clutgreen[currentColorIndex];
currentColor = clutblue[currentColorIndex];
NextColor();// And write the colors to the octobrite
WriteColors();// Finally enable the LEDs
digitalWrite(BLANK_PIN, LOW);
}// Called when we’ve completed an interpolation between a pair of
// colors. This sets us up to interpolate to the next color in
// the lookup table
void NextColor()
{
// We’ve finished interpolating to the current color, so it becomes the
// previoud color we’re interpolating from
previousColor = currentColor;
previousColor = currentColor;
previousColor = currentColor;// And pick the next color in the CLUT for the current color
currentColorIndex = (currentColorIndex + 1) % colorCount;
lerpindex = 0;
currentColor = clutred[currentColorIndex];
currentColor = clutgreen[currentColorIndex];
currentColor = clutblue[currentColorIndex];
}// Writes out a single 12-bit grayscale channel
void WriteChannel(int value)
{
int bit;// Write value, MSB first
for (bit=11; bit>=0; --bit)
{
if (value & (1<<bit))
{
digitalWrite(SIN_PIN, HIGH);
}
else
{
digitalWrite(SIN_PIN, LOW);
}// We need to wait 30ns after writing data before clocking it in.
// Fortunately, our AVR is slow enough that we don’t need to
// do an explicit wait here
digitalWrite(SCLK_PIN, HIGH);
digitalWrite(SCLK_PIN, LOW);
}
}void WriteColors()
{
// First calculate the current interpolated color value
int red = (CHANNEL_MAXpreviousColor(lerpsteps-lerpindex) + CHANNEL_MAXcurrentColorlerpindex) / lerpsteps;
int green = (CHANNEL_MAXpreviousColor(lerpsteps-lerpindex) + CHANNEL_MAXcurrentColorlerpindex) / lerpsteps;
int blue = (CHANNEL_MAXpreviousColor(lerpsteps-lerpindex) + CHANNEL_MAXcurrentColorlerpindex) / lerpsteps;// Disbaled debug output
if (false)
{
Serial.print(“RGB=(”);
Serial.print(red);
Serial.print(", “);
Serial.print(green);
Serial.print(”, “);
Serial.print(blue);
Serial.println(”)");
}// Now write the next RGB value, which will shift the colors
// down along the other LEDs
WriteChannel(red);
WriteChannel(green);
WriteChannel(blue);// Finally latch in the new color values
digitalWrite(XLAT_PIN, HIGH);
delay(1);
digitalWrite(XLAT_PIN, LOW);
}void loop()
{
// Step the interpolation by one frame
++lerpindex;
if (lerpindex > lerpsteps)
{
// We finished the interpolation between the current
// color pair. Set up the next color pair.
NextColor();
}// Update the LEDs
WriteColors();// Throttle the animation
delay(stepdelay);
}[/quote]