RadioHead
|
People often ask about how to send data (such as numbers, sensor readings etc) from one RadioHead node to another. Although this issue is not specific to RadioHead, and more properly lies in the area of programming for networks, we will try to give some guidance here.
One reason for the uncertainty and confusion in this area, especially amongst beginners, is that there is no best way to do it. The best solution for your project may depend on the range of processors and data that you have to deal with. Also, it gets more difficult if you need to send several numbers in one packet, and/or deal with floating point numbers and/or different types of processors.
The principal cause of difficulty is that different microprocessors of the kind that run RadioHead may have different ways of representing binary data such as integers. Some processors are little-endian and some are big-endian in the way they represent multi-byte integers (https://en.wikipedia.org/wiki/Endianness). And different processors and maths libraries may represent floating point numbers in radically different ways: (https://en.wikipedia.org/wiki/Floating-point_arithmetic)
All the RadioHead examples show how to send and receive simple NUL terminated ASCII strings, and if thats all you want, refer to the examples folder in your RadioHead distribution. But your needs may be more complicated than that.
The essence of all engineering is compromise so it will be up to you to decide whats best for your particular needs. The main choices are:
With this technique you just pack the raw binary numbers into the packet:
If you need to send more than one number at a time, its best to pack them into a structure
The disadvantage with this simple technique becomes apparent if your transmitter and receiver have different endianness: the integers you receive will not be the same as the ones you sent (actually they are, but with the internal bytes swapped around, so they probably wont make sense to you). Endianness is not a problem if every data item you send is a just single byte (uint8_t or int8_t or char), or if the transmitter and receiver have the same endianness.
So you should only adopt this technique if:
One solution to the issue of endianness in your processors is to always convert your data from the processor's native byte order to 'network byte order' before transmission and then convert it back to the receiver's native byte order on reception. You do this with the htons (host to network short) macro and friends. These functions may be a no-op on big-endian processors.
With this technique you convert every multi-byte number to and from network byte order (note that in most Arduino processors an integer is in fact a short, and is the same as int16_t. We prefer to use types that explicitly specify their size so we can be sure of applying the right conversions):
If you need to send more than one number at a time, its best to pack them into a structure
This technique is quite general for integers but may not work if you want to send floating point number between transmitters and receivers that have different floating point number representations.
In this technique, you transmit the printable ASCII equivalent of each floating point and then convert it back to a float in the receiver: