I am using the following code to stream RGB Addressable light strip (5M). Aside from setting parameters, the overall process is simple. Because AdaFruit disables interupts, there is a software handshaking, where the controllers asks for input data from the com port. The code receives a command from the PC to turn on light 1 and then it moves the light down the strand at a predetermined speed.
The issue I have is that the code works flawlessly for a period of time and then suddenly the controller hangs and wont respond. Pressing the hardware reset button, doesn't help, I have to unplug the controller from the USB port. The code might run without fail for hours or just minutes... Does anyone see anything I might be missing that could cause random hangs?
#include <Adafruit_NeoPixel.h>
#include <avr/wdt.h>
// // Serial Input
// // L:1:1:20:0:0 (Lane:count:red:green:blue)
// // D:100 (Delay time)
// // C:600 (Total number of lights per lane)
#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel lane1 = Adafruit_NeoPixel(600, 2, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel lane2 = Adafruit_NeoPixel(600, 3, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel lane3 = Adafruit_NeoPixel(600, 4, NEO_GRB + NEO_KHZ800);
int lightcount = 100; //initialize maximum number of lights.
int lightdelay = 1000; //initialize delay for light movement.
int serialdelay = 100; //Check serial port every 500 miliseconds
byte lanetotal = 3; //Total number of lanes to process in the loop
byte lightrefresh = 5;
void setup() {
Serial.begin(9600);
Serial.println("Serial Light Sequencer 10.2");
Serial.println("System Ready");
lane1.begin();
lane1.show(); //Set all lights to off
lane2.begin();
lane2.show(); //Set all lights to off
lane3.begin();
lane3.show(); //Set all lights to off
}
void loop() {
static unsigned long nextLightUpdate = millis();
static unsigned long nextSerialUpdate = millis();
static byte nextLightRefresh = 1;
if (millis() > nextLightUpdate) {
for (int i = lightcount; i >= 1 ; i--) {
lane1.setPixelColor(i, lane1.getPixelColor(i - 1));
lane1.setPixelColor(i - 1, 0);
if (lanetotal >= 2) {
lane2.setPixelColor(i, lane2.getPixelColor(i - 1));
lane2.setPixelColor(i - 1, 0);
}
if (lanetotal >= 3) {
lane3.setPixelColor(i, lane3.getPixelColor(i - 1));
lane3.setPixelColor(i - 1, 0);
}
}
nextLightRefresh ++;
if (nextLightRefresh >= lightrefresh) {
lane1.show();
if (lanetotal >= 2) {
lane2.show();
}
if (lanetotal >= 3) {
lane3.show();
}
nextLightRefresh = 1;
}
//Serial.println("A");
//delay (lightdelay);
nextLightUpdate += lightdelay;
}
//Get Serial Data on interval
if (millis() > nextSerialUpdate) {
Serial.println("A");
GetSerial();
nextSerialUpdate += serialdelay;
}
}
//void serialEvent() {
// GetSerial();
//}
void SoftwareReboot()
{
wdt_enable(WDTO_15MS);
while (1)
{
}
}
//Read Serial Data
void GetSerial () {
//Serial.flush();
if (Serial.available()) {
char *list[7];
char buf[20] ;
byte i;
i = Serial.readBytesUntil('\n', buf, 20);
buf[i] = '\0'; //terminate string with null
//Serial.flush();
// Serial.println(buf);
// return;
char *token = strtok(buf, ":");
i = 0;
list[i] = token;
i++;
while (token)
{
token = strtok(NULL, ":"); // Use NULL as the 1st argument to keep parsing the same string
list[i] = token;
//Serial.println(token);
i++;
}
char tmpproc;
strncpy (&tmpproc, (list[0]), 1); //Copy Char* to Char * convert to INT for Switch comparison
switch (tmpproc) { //Check process
case 'L': //Set light
switch (atoi(list[1])) {
case 1:
for (int i = 1; i <= byte(atoi(list[2])) ; i++) {
lane1.setPixelColor(i, byte(atoi(list[3])), byte(atoi(list[4])), byte(atoi(list[5]))); //(light1,r,g,b)
}
break;
case 2:
if (lanetotal >= 2) {
for (int i = 1; i <= byte(atoi(list[2])) ; i++) {
lane2.setPixelColor(i, byte(atoi(list[3])), byte(atoi(list[4])), byte(atoi(list[5]))); //(light1,r,g,b)
}
}
else
{
Serial.print("Invalid Lane:");
}
break;
case 3:
if (lanetotal >= 3) {
for (int i = 1; i <= byte(atoi(list[2])) ; i++) {
lane3.setPixelColor(i, byte(atoi(list[3])), byte(atoi(list[4])), byte(atoi(list[5]))); //(light1,r,g,b)
}
}
else
{
Serial.print("Invalid Lane:");
}
break;
}
Serial.print((list[0]));
Serial.print (":");
Serial.print((list[1]));
Serial.print(":");
Serial.print((list[2]));
Serial.print(":");
Serial.print((list[3]));
Serial.print (":");
Serial.print((list[4]));
Serial.print (":");
Serial.println((list[5]));
break;
case 'D': //Set Delay
lightdelay = atoi(list[1]);
Serial.print ("D:");
Serial.println((list[1]));
break;
case 'C': //Set Light Count
lightcount = atoi(list[1]);
Serial.print ("C:");
Serial.println((list[1]));
break;
case 'S': //Set Serial Delay
serialdelay = atoi(list[1]);
Serial.print ("S:");
Serial.println((list[1]));
break;
// case 'N': //Set Light Number
// lightnumber = atoi(list[1]);
// Serial.print ("N:");
// Serial.println((list[1]));
// break;
case 'R': //Set Light Refresh Frequency (Strand)
lightrefresh = atoi(list[1]);
Serial.print ("R:");
Serial.println((list[1]));
break;
case 'T': //Set Total Lanes
lanetotal = atoi(list[1]);
Serial.print ("T:");
Serial.println((list[1]));
break;
case 'X': //Reset device
Serial.println("System Reboot");
SoftwareReboot();
break;
}
}
}