2

I have an Arduino reading serial data and responding to other inputs as well, I'm trying to read incoming serial data without using the while, if at all possible. the incoming serial data will be formatted in a specific manner each time and will be CSV; It will look like such:

19,1400700083, 1-0,1-10,and other values delimited with a new line character "/n".

The first value will tell how many bytes are coming in so the serial receive function wont parse data until it gets all the bytes,second value is a Unix time-stamp, the third value (1-0) is the "get" or set" value; which will tell the Arduino to return a value or to set a value. The fourth (1-10) value will correspond to what variable to get or set. and the other values will be integers as well but are dependent on the other values.

My code is as follows:

void CheckSerialData() { // begin function  if(Serial.available() >= 2) { // begin one, first line will be how many bytes incoming.  int NumberOfIncomingBytes = Serial.parseInt();    if(Serial.available() >= NumberOfIncomingBytes) { //begin two    int IncomingTime = Serial.parseInt();    setTime(IncomingTime); //time is always incoming with serial values    int GetOrSetValue = Serial.parseInt(); //this value should be 1 or 0 for "getting values(1)" or "setting values(0)"      if(GetOrSetValue == 1) { //BEGIN THREE        int ValueToGet = Serial.parseInt();           switch(ValueToGet) {// BEGIN SWITCH            case 0:              Serial.print(GetTemp());              Serial.print("/n");              break;            case 1:              //serialwrite yaw pitch roll              break;            case 2:              Serial.print(GetVoltage());              Serial.print("/n");              break;            case 3:              //append all RGB final values together and serial print it              break;            case 4:              //print out accel values              break;            case 5:              //print alarm alarmed status              break;            case 6:              //print out last time alarm set off              break;            case 7:              //print out time allowed lights to turn on              break;            case 8:              //print out arduino time               break;            case 9:              //print out system summary, (time,voltage,temp,yaw,pitch,roll,accel              break;          }//END SWITCH         }//END THREE       else { //BEGIN TWO B //SET VALUES      int ValueToGet = Serial.parseInt();           switch(ValueToGet) {// BEGIN SWITCH            case 0:              //set global rgb value set LEFT              break;            case 1:              //set global rgb value set RIGHT              break;            case 2:              //set global alarm value              break;            case 3:              //set global angle to start flashing emergency led's              break;            case 4:              //set turn signal RGB value              break;            case 5:              //set time that lights are ok to turn on              break;            case 6:              //set light override value              break;            case 7:              //set pattern enable              break;          } //END SWITCH      }//END TWO B          }        }//end two       }//end one    }//end function    //**********************END SERIAL FUNCTION**************************

I would like to know if this looks like it can work, or am I going about this all wrong?

(I don't have access to my Arduino currently to test the code)

Nick Gammon's user avatar
Nick Gammon
38.9k13 gold badges70 silver badges126 bronze badges
askedMay 21, 2014 at 19:36
Sam W's user avatar

1 Answer1

2

Unfortunately your code could end up dropping data quite easily, or parsing it incorrectly.

Let's say your code has successfully read the first couple of bytes intoNumberOfIncomingBytes. However, when it reachesbegin two, let's imagine the sender hasn't finished sending all the data yet.

Your code will drop through toend two, discarding theNumberOfIncomingBytes value it just read. Next time round, it will start all over again from scratch, and attempt to readNumberOfIncomingBytes again. However, that data isn't there anymore. The next data waiting on serial will actually be the timestamp from the previous message.

From there, it could end up parsing arbitrary data with unpredictable results, getting completely out-of-sync with the sender.

A way to fix it would be to store theNumberOfIncomingBytes value outside the function (e.g. as a global variable), along with a flag indicating if you're still waiting for the rest of the data to arrive. At the start ofCheckSerialData(), the code should check that flag. If it's true, then it should skip trying to readNumberOfIncomingBytes. Instead, go straight on tobegin two.

An alternative approach would be to avoid usingNumberOfIncomingBytes at all. Each call toCheckSerialData() would read whatever serial data is available, and accumulate it in a buffer. As soon as it hits a newline character, it will stop reading, and parse the data it's accumulated. If it runs out of serial data before it hits a newline, it should stop and carry on from there next time it's called.

answeredMay 22, 2014 at 15:18
Peter Bloomfield's user avatar

Your Answer

Sign up orlog in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to ourterms of service and acknowledge you have read ourprivacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.