Michael On Everything Else

Arduino float to bytes for LoRa transmission

For a recent Arduino project; a gas sensor with a LoRa radio, I needed to transmit large, floating decimal values over the air from one LoRa radio to another. There doesn’t seem to be a lot of information out there for this, and the information that is out there, didn’t really explain things to me well enough to feel confident. But I finally got it working using unions. Here is how I understand it to work:

The basics, bulleted:

We’ll take advantage of the ‘shared memory’ aspect to make the union a little data type-converter where we put in a float and we take out a byte, or vice versa.

First, define the union:

union gasUnion  
        float gasFloat;
        unsigned char gasBytes[4];

To put data in, we do the following:

gasUnion a; //declare the union
a.gasFloat = 99.9; //put the float into place

Now our union holds the value 99.9 expressed as either a float or four bytes. As long as we don’t put anything in the a.gasBytes[] array, it will contain the byte form of the float “99.9” because of the shared memory aspect of unions.

To transmit the 99.9 via LoRa, just pump the gasBytes[] into a LoRa payload:

  //take bytes from the union and place into LoRa payload
  GasPayLoad[0] = a.gasBytes[0];
  GasPayLoad[1] = a.gasBytes[1];
  GasPayLoad[2] = a.gasBytes[2];
  GasPayLoad[3] = a.gasBytes[3];

On the receiving end, I created an identical union and did the same operation, but in reverse; pull bytes out of the LoRa payload, pump them into the union, and immediately pull a float out of the union:

  //pull bytes out of LoRa payload
  GASfullpayload[0] = LoRa.read();
  GASfullpayload[1] = LoRa.read();
  GASfullpayload[2] = LoRa.read();
  GASfullpayload[3] = LoRa.read();


  gasUnion a; //declare the union

  //put bytes in
  a.gasBytes[0] = GASfullpayload[0];
  a.gasBytes[1] = GASfullpayload[1];
  a.gasBytes[2] = GASfullpayload[2];
  a.gasBytes[3] = GASfullpayload[3];

  ValueNH3 = a.gasFloat; //take out a float

It really is that simple, but for some reason, the way it was explained in all the forums and blog posts I looked at, it was difficult for me to understand.

Note; I read several places about a concern with underlying architecture and endianness, which would mean the four bytes could be backwords on some systems. I compile with Arduino IDE on a MacBook Pro and didn’t have that problem.