Please help :-)
Hi all,
I am currently writing an Arduino app which will be acting upon data received through its serial port. I am using the Arduino Uno and the Arduino IDE Serial Monitor. The Uno is connected to the PC through the USB cable. The host will be sending commands in the following form:
<command>:<data>*
<command> is a one character command.
<data> may be a string of letters or digits
The command line is terminated by the trialing asterisk. At this time I have various versions of the routine that receives and interprets 2 possible commands, but none are working as they should. I have tried various techniques but I am not sure which is recommended:
- Locate the serial receive code in the main Loop routine. Use Serial.available(). Interpret the command line as the characters are received.
- Same as above, but first accumulate the command line and then parse and interpret when the asterisk is received.
- Locate code to receive and interpret command line in the serialEvent routine.
- Locate code that accumulates received characters into a string in the serialEvent routine. When done set a Boolean flag. Locate code that parses and interprets command in the main Loop routine and is executed when flag becomes True (all data in).
- In the serialEvent routine use while (Serial.available()).
- In the serialEvent routine use if (Serial.available())
- In the serialEvent routine don’t use neither of the above since the event is fired when there is serial data available
The code below is my latest attempt. It does not work. When I uncomment the “Serial.print("strInComm: ");” lines it seems to print garbage or it stops halfway through the “strInComm’ text.
If I uncomment the lines inside the switch statement ("Percent dec: " and "Delay: ") sometimes they never execute, as though execution does not go into the switch. In some cases gibberish is printed out. I note that both the code and the Serial Monitor are set to 9600 baud.
At this time I am going to start from scratch, but if anyone can look at my code and provide feedback I’d greatly appreciate it. I could use another pair of eyes looking at it. Perhaps it is something trivial that I missed. I took the basic infrastructure of the code from the serial examples. I also watched Jeremy Blum’s episode 6 Arduino tutorial series. This episode describes serial communications. I was introduced to Serial.flush(), a statement that I have not tried (yet).
Thank you for your time and assistance. Salvador
/*
Test program to receive commands from a host computer.
Command format:
<command>:<data>*
* indicates end of command line.
*/
float PercentData;
//For serial reception chars and control.
String strInComm = "";
boolean bComplete = false;
int intDelay = 0;
//int iInChar;
int iCmdType;
void setup()
{
Serial.begin(9600);
// Serial.begin(115200);
// reserve 40 bytes for the settings information:
//strInComm.reserve(40);
strInComm ="";
//Initialize percent variable
PercentData = 0.03;
//Initialize delay variable.
intDelay = 3;
}
void loop() //Main Loop
{
String sCmd = "";
String sData = "";
char chInChar;
if (bComplete) {
//I have the complete line, parse.
//Serial.print("strInComm: ");
//Serial.println(strInComm);
//The entire line is in, now parse the command and interptret.
//Get the command. The command is 1 char.
sCmd = strInComm.substring(0,1);
//Get the data. This goes from the : to the end.
sData = strInComm.substring(strInComm.indexOf(':') + 1);
//Serial.print("sCmd: ");
//Serial.println(sCmd);
//Serial.print("sData: ");
//Serial.println(sData);
if (sCmd=="p" or sCmd=="P")
chInChar = 'p';
if (sCmd=="d" or sCmd=="D")
chInChar = 'd';
switch (chInChar) {
case 'p':
char cmdChar[sData.length() + 1];
sData.toCharArray(cmdChar, (sData.length() + 1));
PercentData = atoi(cmdChar) / 100.0;
//Serial.print("Percent dec: ");
//Serial.println(PercentData);
break;
case 'd':
char cmdChar2[sData.length() + 1];
sData.toCharArray(cmdChar2, (sData.length() + 1));
intDelay = atoi(cmdChar2);
//Serial.print("Delay: ");
//Serial.println(intDelay);
break;
} //Switch chInChar
Serial.print("Percent dec: ");
Serial.println(PercentData);
Serial.print("Delay: ");
Serial.println(intDelay);
//delay(1000);
bComplete = false;
//Reinitialize the input buffer.
strInComm="";
}
}
void serialEvent() {
String sCmd = "";
String sData = "";
//Serial.println("In serialEvent");
char inChar = (char)Serial.read();
// if the incoming character is an *, set a flag
// so the main loop can do something about it:
if (inChar == '*') {
bComplete = true;
}
else {
strInComm += inChar;
}
//Serial.println(strInComm);
}