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)
1 Answer1
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.
Explore related questions
See similar questions with these tags.