This page has been updated. Please see the following newer guides:
Introduction, Using The Serial Monitor, and More
A Look at the Different Serial Libraries
Serial Commands Explained
Getting Started With Using Serial Communication To Send Commands
ASCII Data and Using Markers to Separate Data
In the previous post I went through the basics of using serial on an Arduino and ran through the different commands. In this post I want to talk about different types of serial data and some of the things you should consider before starting to create code. The type of communication you use or can use will depend largely on the project but there are things that can be considered before starting.
- Type of communication? 1-way or 2-way
- Type of data? Values or strings? Simple or complex?
- How much data and how frequent? A couple of values every few seconds or a high rate continuous stream.
- Is the data critical? Must you be sure you receive all the data or can you afford to lose some of it.
Type of communication
The type of communication will determine how complex parts of the project are. One way communication is generally easier to implement but you need to consider which way; sent from the Arduino or sent to the Arduino. The Arduino does not have high level data processing functions so if you have complex data patterns you will need to create code that parses it.
Two way communication means you need to send and receive at both sides. Will communication be synchronous or asynchronous? This will effect your code and what functions you can use, for example, Software Serial on the Arduino cannot receive and send at the same time.
Type of data
Think about what information you need to pass and if you can simplify the data format used to do it. For example, if you just want to switch a light on and off you can do this with very simple codes or commands like a single character (or even one bit of an 8 bit character).
If you are creating a weather monitoring station, you may need to accommodate wind speeds and temperatures which may need floating point values.
If you have a lot of different values you will need some way to let the Arduino know which is which when they are received.
You also need to consider how quickly you need to send/receive the data. If speed is not an issue there are no real restrictions on how complex the data can be and you could use human readable data like XML or something like “Temperature=24.75,humidity=34.5%” for example. If data is received very quickly then it should be as simple as possible.
As always, I advocate keeping things as simple as possible and I always try to simplify the data, or more specifically the format of the data, I use.
For complex data where speed is not the main concern I use formatted data sets and if possible fixed length data. How much you format the data can depend on what the data is.
When sending data to the Arduino I almost always stick to the same methods; I use fixed length data and use ascii for numbers. When sending data to high level languages such as App Inventor or VisualBasic it is less important but formatted data makes things easier.
Fixed length data
To give an example of what I mean here are a couple of examples. If I have 3 sliders in App Inventor used to control a RGB LED connected to an Arduino, I know I have 3 values (red, green, and blue) and each value can be anything from 0 to 255.
Using ascii, where the numeric values are converted to alphanumeric (string) values I will use 3 characters for each value; 0 becomes “000”, 100 becomes “100” and 255 becomes “255”. I may then enclose the data within start and end markers so that the actual data becomes “”. Then on the Arduino side, as I receive data I add it to a buffer, when the buffer has both a start marker and an end marker I know I have all the data. This makes the data easy to read but it does mean the transmission is slower than it needs to be. When speed is important I may reduce the data to “[” byte1 byte2 byte3 “]” where byte1, byte2, and byte3 are the actual numeric values. I would still use the start and end markers though.
How much data
You also need to consider how much data you want to send and how often you want to send it. There is quite a difference between sending a temperature once a minute and streaming music. If you want to send a lot of data very frequently you also need to consider latency and how quickly the Arduino can receive and process data.
For example, using software serial on an Arduino has a limit to how fast you can reliably receive and send data. Hardware serial is much better but still has limits.
If the data is critical and you have to know you have received everything then you need a way of checking. There are many different ways of doing this but, as always, I like to keep it simple if I can. In the few cases where I wanted to know for sure I have received everything I used a basic checksum value and a count of the number of times data has been sent and appended the count to the data. This means, if I get a block of data and the checksum is not correct I know it is corrupted and can request a resend. If every block of data is numbered; block1, block2, block3, I have a simple way of checking that I have received every block and if one is missing it can be resent.
The next couple of posts go through methods for sending serial data from one Arduino to another. In all the examples I use physical wires to connect the Arduinos but the wires can be replaced by any wireless module that speaks UART such as Bluetooth modules. And although I give examples of Arduino to Arduino, the same techniques can be used when receiving serial data from any device.