Hi,
I’m trying to write some code that polls a serial port (from an Electric Imp) listening for commands or ‘programs’ to execute (i.e. different patterns to run on my xmas lights.)
My command format is simple: up to 19 characters followed by a newline (\n).
I’ve cobbled together the following by looking at other people’s examples, but I think I’m munging strings somewhere, because my debug output is starting to look pretty funky.
#include <SoftwareSerial.h>
SoftwareSerial impSerial(8, 9); // RX on 8, TX on 9
const char programs[][10]={
"RANDOM",
"XMAS",
"USA",
"HWEEN"
};
char incoming[20]; // array to build the string in
char inChar=-1; // current character we just read
byte idx=0; // Where to stick inChar in incoming
byte cmd_valid = 0; // Did we understand the last?
void setup()
{
// Open the hardware serial port
Serial.begin(19200);
// set the data rate for the SoftwareSerial port
impSerial.begin(19200);
}
void loop() // run over and over
{
// Send data from the software serial
if (impSerial.available())
{
if(idx < 19)
{
inChar = impSerial.read();
if (inChar != '\n')
{
incoming[idx] = inChar;
idx++;
incoming[idx] = '\0'; // null terminate
impSerial.print(F("Added the character '"));
impSerial.print(inChar);
impSerial.println(F("' to the buffer."));
impSerial.print(F("idx is now at position: "));
impSerial.println(idx);
}
}
if (idx >= 19 || inChar == '\n') // ran out of space or they typed a newline
{
// see if we recognize a command or a program name
if (strcmp(incoming, "PON") == 0) // power on command
{
impSerial.println(F("Power on command"));
cmd_valid = 1;
}
else if (strcmp(incoming, "POF") == 0) // power off command
{
impSerial.println(F("Power off command"));
cmd_valid = 1;
}
else
{
// walk the array of program names and see if any match our string
for (size_t i = 0; i < sizeof(programs); i++)
{
if (strcmp(incoming, programs[i]) == 0)
{
impSerial.print("Executing program '");
impSerial.print(incoming);
impSerial.println("'.");
cmd_valid = 1;
}
}
if (cmd_valid != 1)
{
impSerial.println("Command or program name not recognized.");
}
}
// erase the string
for (int j=0;j<19;j++) {
incoming[j]=0;
}
idx=0;
cmd_valid = 0;
}
}
// Serial.write(impSerial.read()); // to the hardware serial
// Send data from the hardware serial
if (Serial.available())
impSerial.write(Serial.read()); // to the software serial
}
(Once I got stuff working, I wanted to break more of it out into functions, but right now I’m just trying to make it recognize commands.)
My debug statements started to look like this:
Wed Jul 31 2013 23:55:21 GMT-0500 (CDT): Added the character 'H' to the buffer.
Wed Jul 31 2013 23:55:21 GMT-0500 (CDT): idx is now at position: 7
Wed Jul 31 2013 23:56:22 GMT-0500 (CDT): Added the character 'W' to theat' t.dioaot:
ddhoeue
ot:1Aehcrt f.iiopo3Added the character 'U' to the buffer.
Wed Jul 31 2013 23:56:22 GMT-0500 (CDT): idx is now at position: 14
Wed Jul 31 2013 23:56:24 GMT-0500 (CDT): Added the character 'S' to th ti otpio:8
I get the feeling that as usual, I’m trying to run before I can walk. Instead of hooking the Arduino and Electric Imp together, I’m thinking it would be better if I debugged locally using a USB-FTDI serial cable, until I have the string parsing code working… less places for the data to get lost, messed up, etc.
Still, if anyone sees any obvious errors with my code, or can suggest a better/cleaner way to do what I’m trying to do, I would appreciate hearing about it!
Thank you!