ARDUINO AND C# SERIAL COMMUNICATION: 2. CREATING A COMMUNICATION PROTOCOL

After publishing my last article (this: Arduino and C# Serial Communication) I have shared it in different places (one of them was Facebook, obviously…)  and somebody left me a comment, a very nice one which made me to write this article. Originally I did not planned to create an article series dedicated to serial communication but here it is its second part.

 

 

His idea was to create a communication protocol in order to check if the received message arrived in one piece without errors to the computer.

In order to make two devices to communicate with each other there is a need for both hardware and software solutions. Like in the last article it was presented, we have chosen the USB (aka. serial) data transfer. The whole communication was set up, it works, safe thread management was solved – its almost perfect.

But how do we know if the message what the PC received is correct? We dont know! That is the problem! How it can be solved? Creating our high level communication protocol. What does that mean? In the following pyramid is represented how you should imagine what this article will explain. Till now, we have got the hardware and low level software layer configured. These first two steps of the pyramid takes care about transferring some data, but its too stupid to make sure if the data is correct or not. The so called high level software layer is going to verify the received and sent data, with the use of a checksum.

 

 

A checksum is a small piece of data which is generated from a block of data in order to detect errors that could influence it during the transmission (or storage). One complete frame consists of the checksum separated by the message with a simple colon. The length of both the checksum and the message can vary.

There are a lot of checksum calculating algorithms, but its more enjoyable to create your own one. I came up with the following checksum calculation method (probably it is used somewhere, I am not a big encryption guru).

 

 

First of all, take a look at the table, in the first column are the steps represented that must be followed if we want to calculate the checksum. In the first column is the data that is going to be sent from the uC to PC, a simple string: “dataofstr”. To make arithmetic operations over characters they should be represented in numerical form. The most common one is the ASCII value of a character, that can be seen on the second row, below you can find the printable characters of the ASCII table. The third row shows the index of the characters in the string. (Here is a link for the C source code if you want to play with it)

 

The last row represents the final checksum value.

Lets take it step by step:

  1. Get the first character of the string (d)
  2. Lookup the ASCII value of that character  (100)
  3. Multiply its ASCII value by its index (for the first one is 1) and remember it (100 x 1 = 100)

 

  1. Take the second character of the string (a)
  2. Lookup the ASCII value of the second character (97)
  3. Multiply its ASCII value by its index (for the second one is 2) and remember it (194) than add it to the previous sum from step 3. (100 + 194 = 294)

Repeat this method for the whole string, than check the modulo of that number and you got your checksum.  Here is a demonstration of this method, written also in plain C, you can also find this on Github, even a compiled *.exe if you want to try it yourself:

This piece of code works like a charm, now it is needed to implement the same algorithm in Arduino specific C language, which is object oriented (actually OOP does not really matters now) – and the string methods are a bit different. The loop() method gets over a small face lift:

And there is a new function added, which calculates the actual checksum:

You can download the whole updated source code from Github. After finishing and testing of the updated Arduino code, the last step is reached which is consisted of updating the C# source to check if the received frame is correct or not.

In the “private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)” method we can check whether the received data is correct or not. After generating locally the checksum they must be compared to the received one, and after that can be decided if the data was transmitted correctly. Of course the whole updated C# project can be found on Github.

I must mention that, this piece of code only analyzes the received information and makes a statistics – but nothing else. It does not makes any decision how the data should be handled.

Serial port framing error can occur in the first place when there is a baud-rate mismatch between the devices or if the serial line is too long. Also electromagnetic noise can disturb the signal if the cable is too long or if its interfered by some powerful emitting element.

Is this this checksum generation algorithm perfect? No, probably. I just wanted to present the basic idea, the principle of “safer” data transmission and handling. How can be made even more safe? The next step will be to encrypt the whole message, so only the PC and uC can understand it. Its important because, for example if there is some kind of malware installed on the host PC which can sniff out and steal the USB and other interface packages, data leakage can happen and it is a big security issue when transmitting for example RFID card IDs.