Sending floats over the I2C bus between two Arduinos — Part 2

Sandhan Sarma
3 min readDec 8, 2018

--

In the previous part of this tutorial we saw how we can to send and receive floating point numbers over the I²C bus.

The method first involved converting the floating point number to a string, then sending it over the I²C bus as a stream of bytes, and upon receiving, the stream of bytes was read byte by byte as characters and appended to a string, and the string was finally converted to a floating point number.

As it seems, this method of sending floating point numbers may not be the most efficient way.

In the previous program, a byte was sent for every digit in the flaoting point number including the decimal point.

This means that sending just a small floating point number with two digits before the decimal and two digits after the decimal would take up 5-bytes, and the number of bytes scales up as we go on adding more digits.

This is extremely inefficient compared to a 4-byte floating point number which can store any number in the range 1.2E-38 to 3.4E+38 with a precision of 6 decimal places.

Also, add to it the CPU overhead of converting the floating numbers to string before sending and again converting the string back to it original floating point datatype upon reception.

The Solution

To solve this problem, we will be using a very useful datatype in C Language, called thr Union datatype.

The Union datatype is very similar to a Struct datatype in C, excpet one very special property that, all the members of a Union datatype share the same memory location, and as such only one member can be used at a time.

Let us first declare a Union for the sake of understanding.

Here we have defined a custom data structure named “floatToBytes” based on Union datatype and also declared a “floatToBytes” variable called “converter”.

The “floatToBytes” datastructure has two variables, one is a char array of size 4 and a float variable.

One important point to note here, is that the amount of space occupied by a Union datatype depends on the size of its largest memeber.

Since a float datatype occupies only 4-bytes, we have declared a char array of 4-bytes.

Next we set a floating point value to the float member “voltageReading” inside our “converter” Union data structure.

As both “voltageReading” and “buffer” are occupying the same memory location, the 4 elements of the “buffer” array now also points to the the same 4 bytes of our float variable “voltageReading”, whose value we set earlier.

Now we can simply send the “buffer” variable as an argument to Wire.write() function, as shown in the code snippet below.

On the receiving end the data can be received simply by using the above method in reverse as shown in the code snippet below.

And thats how its done. Hope you found this post useful!

--

--