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)

migrated from electronics.stackexchange.com May 21 '14 at 19:40

This question came from our site for electronics and electrical engineering professionals, students, and enthusiasts.

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 into NumberOfIncomingBytes. However, when it reaches begin two, let's imagine the sender hasn't finished sending all the data yet.

Your code will drop through to end two, discarding the NumberOfIncomingBytes value it just read. Next time round, it will start all over again from scratch, and attempt to read NumberOfIncomingBytes 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 the NumberOfIncomingBytes 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 of CheckSerialData(), the code should check that flag. If it's true, then it should skip trying to read NumberOfIncomingBytes. Instead, go straight on to begin two.

An alternative approach would be to avoid using NumberOfIncomingBytes at all. Each call to CheckSerialData() 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.