In this earlier post, I had documented a Serial Communications Class for data transfer with an Arduino device in the Qt environment. While it worked OK for transferring data at slower data transfer rates, it couldn’t handle fast communications with the the Invensense MPU6050 IMU. Also, that version had a lot of other problems:-
1. Speed could not increase beyond 4200 baud with data integrity being lost. This was happening because Qt’s readyread() signal is emitted at ANY time during the data reception process. This means that the incoming data needs to be rearranged into a proper “sentence” before it is parsed. Scroll below to the screen-shot to see what I mean.
2. No error checking method was implemented
3. Baud rate couldn’t be changed on the fly. This is relatively easy to implement….I was just too lazy to actually do it.
The ArduinoTalker Class is now suitably modified and works much better. Some features are:-
1. It can now handle data rates upto 115200 baud. This is more than enough speed for talking to most sensor devices and may just even allow slow image transfer.
2. There is a rudimentary error checking method implemented. When the Arduino transmits its sequence of values, the last number must equal the sum of all numbers before it. When the ArduinoTalker Class parses the data, it checks to see if the sum of the incoming numbers equals the last value received.For example, if the Arduino were sending 3.4, 5.66, 34.0, then it would append (3.4+5.66+34.0) at the end if its transmission.
I have found that there is sometimes a tiny error of the order of 0.0000001 that creeps into the numbers being received. I think this has something to do with Qt’s QByteArray::ToFLoat() function. To get around this, I introduced a errorLimit variable that is set whenever a connection to an Arduino device is initiated, like this:-
mega1 = new ArduinoTalker(this); mega1->ConnectToArduino("/dev/ttyACM0", errorLimit);
When receiving data, all the values are summed up if SUM(all values) – LAST VALUE > errorLimit, the data packet is rejected. Its definitely not a perfect solution but it works for me.
3. Data from the Arduino is also checked for completeness using a “padding”. Every data packet must begin and end with a ‘ * ‘ for it to be accepted as complete. Also, the ‘&’ character continues to mark the end of a sentence. Scroll below to see an example of how a sentence from an Arduino is formed.
Here is an example of data transfer in progress:-
4. The Arduino must use Serial.print() and not Serial.println() to send the data. Here is an example of how an Arduino device would send two values a and b:-
Serial.print('*'); // starting padding indicator Serial.print(a); // first value Serial.print(','); // value separator Serial.print(b); // second value Serial.print(','); // value separator Serial.print(a+b); // sum of all the previous values Serial.print(','); // value separator Serial.print('*'); // end padding indicator Serial.print("&"); // sentence completed indicator
This new ArduinoTalker Class can be downloaded from here.