I'm working on an interactive/arts project for an upcoming variety show, which will allow an audience member to control effects being displayed on an LED array made from the addressable RGB LED strips available from Sparkfun (http://www.sparkfun.com/products/10312).
The problem is, my sketch will run for 10-20 seconds, then the whole LED array will turn red and then the Arduino either locks up and becomes unresponsive or it resets itself. I've ruled out problems with the SPI library I'm using, as the sample effects that came with it work fine and I hit the same problem with alternate SPI libraries/methods. So I'm starting to think I might be maxing out the available memory or that there's a leak somewhere, but I can't see where if that's what's happening.
Here's a simplified version of the sketch that doesn't use any external library but exhibits the behavior I've described:
int SDI = 2;
int CKI = 3;
int ledPin = 13; //On board LED
#define STRIP_LENGTH 64
long strip_colors[STRIP_LENGTH];
long cellColors[8][8];
int tempo = 500;
void setup() {
pinMode(SDI, OUTPUT);
pinMode(CKI, OUTPUT);
pinMode(ledPin, OUTPUT);
//Clear out the arrays
for(int x = 0 ; x < STRIP_LENGTH ; x++)
strip_colors[x] = 0;
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
cellColors[i][j] = 0;
}
}
randomSeed(analogRead(0));
}
void setCell(int x, int y, long color) {
cellColors[x][y] = color;
strip_colors[(x*8)+(7-y)] = color;
}
// from Sparkfun example code
long randomColor() {
long new_color = 0;
for(int x = 0; x < 3; x++){
new_color <<= 8;
new_color |= random(0xFF); //Give me a number from 0 to 0xFF
}
return new_color;
}
void shiftRows() {
long newColor = randomColor();
for (int y = 0; y < 7; y++) {
for (int x = 0; x < 8; x++) {
setCell(x, y, cellColors[x][y+1]);
}
}
for (int x = 0; x < 8; x++) {
setCell(x, 7, newColor);
}
post_frame();
}
void loop() {
volatile int state = LOW;
while(1){
state = !state;
digitalWrite(ledPin, state);
shiftRows();
delay(tempo);
}
}
//Takes the current strip color array and pushes it out (from Sparkfun example code)
void post_frame (void) {
//Each LED requires 24 bits of data
//MSB: R7, R6, R5..., G7, G6..., B7, B6... B0
//Once the 24 bits have been delivered, the IC immediately relays these bits to its neighbor
//Pulling the clock low for 500us or more causes the IC to post the data.
long this_led_color;
long mask;
for(int LED_number = 0 ; LED_number < STRIP_LENGTH ; LED_number++) {
this_led_color = strip_colors[LED_number]; //24 bits of color data
for(byte color_bit = 23 ; color_bit != 255 ; color_bit--) {
//Feed color bit 23 first (red data MSB)
digitalWrite(CKI, LOW); //Only change data when clock is low
mask = 1L << color_bit;
//The 1'L' forces the 1 to start as a 32 bit number, otherwise it defaults to 16-bit.
if(this_led_color & mask)
digitalWrite(SDI, HIGH);
else
digitalWrite(SDI, LOW);
digitalWrite(CKI, HIGH); //Data is latched when clock goes high
}
}
//Pull clock low to put strip into reset/post mode
digitalWrite(CKI, LOW);
delayMicroseconds(500); //Wait for 500us to go into reset
}
The reason for the abstraction of the grid is to allow various effects to be implemented at a higher level (with simple x,y coordinates in a single orientation), which can then be transformed (e.g. rotated) at a lower level (controlled by user-operated buttons or a joystick). I've excluded that functionality from this simplification, since it still locks up without that.
Could the arrays be maxing out the memory on my Arduino Uno? 4 bytes * 64 * 2 = 512 bytes, which seems well within range of the 2kb I read about somewhere.
Is there any memory leak here that I'm missing? Given that the program seems to run fine initially, shifting rows one by one until it locks up (as though it hit some sort of threshold), I'm wondering if I'm not cleaning something up properly.
I would appreciate any insights! Thanks!