Can anyone help me make this code more efficient? This code uses a variable delay to sequence light strands at a specified speed (matches the speed of a conveyor belt). The shorter the delay, the more frequent characters are missed when reading from / writing to the Serial port. I am using the Arduino Mega and had the same issue with the Uno.
Am I missing something that insures all characters are passed? Is there a buffer that can be configured? I have tried this code using the serial monitor and a separate VB.NET project. Both the same issue with dropped characters.
For example, I send this. The semi colon indicates the end of a character set.
Lane:1 R:20 G:0 B:0;Lane:2 R:0 G:20 B:0;Lane:3 R:0 G:0 B:20;
The response:
Set Lane:1 R:20 G:0 B:0;
Set Lane:2 R:0 G:20 B:0;
Set Lane:3 R:0 G:0 B:0; <---Missing digit, it should say B:20;
This happens at random. Sometimes it misses a single digit, sometimes an entire line.
Here is the code:
// // Serial Input
// // Lane:1 R:20 G:0 B:0;Lane:2 R:0 G:20 B:0;Lane:3 R:0 G:0 B:20; (Pin 1 numeric, r, g, b 3 numeric)
// // Delay:1000; (delay between between moving lights in miliseconds)
// // LightCount:300; (total lights in a strand. ie 300 lights = 15' strand)
#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel lane1 = Adafruit_NeoPixel(300, 2, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel lane2 = Adafruit_NeoPixel(300, 3, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel lane3 = Adafruit_NeoPixel(300, 4, NEO_GRB + NEO_KHZ800);
int lightcount = 300; //initialize maximum number of lights.
int lightdelay = 300; //initialize delay for light movement.
void setup() {
Serial.begin(9600);
Serial.println("Serial Light Sequencer 9.2");
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() {
for (int i = lightcount; i >= 2 ; i--) {
lane1.setPixelColor(i, lane1.getPixelColor(i - 1));
lane1.setPixelColor(i - 1, 0);
lane2.setPixelColor(i, lane2.getPixelColor(i - 1));
lane2.setPixelColor(i - 1, 0);
lane3.setPixelColor(i, lane3.getPixelColor(i - 1));
lane3.setPixelColor(i - 1, 0);
}
lane1.show();
lane2.show();
lane3.show();
delay(lightdelay);
}
void serialEvent() {
GetSerial();
}
//Read Serial Data
void GetSerial () {
byte lane, r, g, b;
int length = Serial.available();
//Serial.println(length);
int i, loc, Delay, Count;
char c;
String readString, substring;
//while (Serial.available() > 0) {
for (i = 0; i < length; i++) {
c = Serial.read();
if (c != ';') {
readString += c;
} else {
break;
}
}
readString.trim();
if (readString.length() > 0 ) {
//Check for Pin, R, G, B sequence
loc = readString.indexOf("Lane:");
if (loc != -1) {
substring = readString.substring(loc + 5, loc + 7);
lane = substring.toInt();
} else {
lane = 0;
}
if (lane > 0) {
loc = readString.indexOf("R:");
if (loc != -1) {
substring = readString.substring(loc + 2, loc + 6);
r = substring.toInt();
} else {
r = 0;
}
loc = readString.indexOf("G:");
if (loc != -1) {
substring = readString.substring(loc + 2, loc + 6);
g = substring.toInt();
} else {
g = 0;
}
loc = readString.indexOf("B:");
if (loc != -1) {
substring = readString.substring(loc + 2, loc + 6);
b = substring.toInt();
} else {
b = 0;
}
Serial.print ("Set Lane:");
Serial.print (lane);
Serial.print (" R:");
Serial.print (r);
Serial.print (" G:");
Serial.print (g);
Serial.print (" B:");
Serial.print(b);
Serial.println(";");
switch (lane) {
case 1:
lane1.setPixelColor(1, r, g, b);
break;
case 2:
lane2.setPixelColor(1, r, g, b);
break;
case 3:
lane3.setPixelColor(1, r, g, b);
break;
}
}
//Check Delay Number
loc = readString.indexOf("Delay:");
//Serial.println(loc);
if (loc != -1) {
substring = readString.substring(loc + 6, loc + 15);
Delay = substring.toInt();
//Serial.println(substring);
if (delay > 0) {
lightdelay = Delay;
Serial.print ("Set Delay:");
Serial.println (Delay);
}
}
//Check light count
loc = readString.indexOf("LightCount:");
//Serial.println(loc);
if (loc != -1) {
substring = readString.substring(loc + 11, loc + 14);
Count = substring.toInt();
//Serial.println(substring);
if (Count > 0) {
lightcount = Count;
Serial.print ("Set Light Count:");
Serial.println (lightcount);
}
}
}
}