Hi, here's a little addition to the wonderful sketch Example 5 found in Serial Input Basics - Updated by Robin
I've updated it to make it more bulletproof. What I noticed was, in the original sketch if you send data in the wrong format, the next time you run it by inputting the data exactly as expected, the previous data is still there in the output message. I want to only see the output between the <> markers, because I want to use this for commands between a Teensy and a Processing app.
If data is entered like this:
<hi
Then I want nothing to happen
If <hi, 23
Again, nothing
But if <hi,23>
Then I want to see:
Message hi
Integer 23
if <hi>
is entered, I want to see an error.
Basically the whole goal was to get it so that only entries beginning with < and ending with > would be recognized, and if data was entered between <> incorrectly, then I want to see an error message
All this, because I want to get reliable messages from my Teensy to a Processing app, and if the data is incorrect then it could cause problems.
I'm sure it could be better, so suggestions are welcome.
Thanks,
Mike
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];// temporary array for use when parsing
// variables to hold the parsed data
char command[numChars] = {0};
int intRequested = 0;
//float floatFromPC = 0.0;
boolean messageReceived = false;
bool commandStarted = false;
String ErrorMessage = "";
String ErrNumber = 0;
void setup() {
Serial.begin(9600);
Serial.println("This demo expects 2 pieces of data - text, and an integer");
Serial.println("Enter data in this style <Hi, 2>");
Serial.println();
}
void loop() {
recvWithStartEndMarkers();
if (messageReceived) {
strcpy(tempChars, receivedChars);
// this temporary copy is necessary to protect the original data
// because strtok() used in parseData() replaces the commas with \0
parseData();
showParsedData();
messageReceived = false;
}
}//end void loop
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
unsigned long TimeOut = 500;
unsigned long ReceiveStart = millis();
unsigned long ReceiveInterval = 0;
while (Serial.available() > 0 && messageReceived == false) {
ReceiveInterval = millis() - ReceiveStart;
if (ReceiveInterval < TimeOut) {
rc = Serial.read();
if (commandStarted && rc == startMarker ) {
ndx = 0;
recvInProgress = false;
commandStarted = false;
}
if ((ndx == numChars - 1) && rc != endMarker) {
ndx = 0;
recvInProgress = false;
commandStarted = false;
}
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
messageReceived = true;
//Serial.println("Command Ended!"); // ENABLE TO SEE WHEN CORRECTLY FORMATTED COMMAND IS COMPLETED
}
}
else if (rc == startMarker) {
recvInProgress = true;
commandStarted = true;
//Serial.println("Command Started!"); // ENABLE TO SEE WHEN CORRECTLY FORMATTED COMMAND STARTED
}
}//if not timeout
else {
ErrorOccurred("Time Out");
}
}
}//end void
void parseData() { // split the data into its parts
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(tempChars,","); // get the first part - the string
if (strtokIndx != NULL) {
strcpy(command, strtokIndx); // copy it to command
}
else {
ErrorOccurred("String missing");
}
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
if (strtokIndx != NULL) {
intRequested = atoi(strtokIndx);// convert this part to an integer
}
else {
intRequested = 999;
ErrorOccurred("Integer missing");
}
// floatFromPC = atof(strtokIndx); // convert this part to a float
}
void ErrorOccurred(String ErrMessage) {
char ErrorMessage[4] = "ERR"; // Get a basic error message
strcpy(command, ErrorMessage);
Serial.println(ErrMessage);
}
void showParsedData() {
Serial.println();
Serial.print("Message ");
Serial.println(command);
Serial.print("Integer ");
Serial.println(intRequested);
Serial.println();
// Serial.print("Float ");
// Serial.println(floatFromPC);
}
[sterretje edit]
fixed minor mistake with code tags
[/edit]