Send and Receive Integers and Floats with Arduino over MQTT

arduino-integers-floatsArduino can be equipped with various sensors like temperature and humidity and you will have a need to send these sensor values over MQTT.

In this tutorial we will look at sending and receiving integer and float data over MQTT using string data and buffer data.

Sending string Data

Sending the data using strings is probably the most common and the easiest.

To send integer data as a string we use the sprintf() function to do the conversion.

As an example to send a temp reading er would use the following code:

int temp=20;
 boolean rc;
char msg_out[20];
sprintf(msg_out, "%d",temp);
 rc = mqttClient.publish("test/temp", msg_out );

sprintf converts the integer and places it in the array msg_out which we pass to the publish method.

To send a float we would logically use the sprinf function but if we try we get a ? as it doesn’t support floats in Arduino. If you want to understand more about this then see this article.

The solution is to use the dtostrf() function The code below shows how to send a float humidity reading

float humidity =60.11;
dtostrf(humidity,2,2,msg_out);
Serial.println(humidity);
 rc = mqttClient.publish("test/humidity", msg_out );

I’ve included the line:

Serial.println(humidity);

which works OK as pointed out in the referenced article.

Also in the dtostrf() function the first 2 is the digits before the decimal point and the second the digits after the decimal point.

Sending Data in Buffers

Program Logic controllers typically send data in binary buffers. So, for example the number 23567 is sent as a 16nit binary number (2 bytes) rather than 5 characters (5 bytes).

Although it saves on network data it is a little trickier to do.

On Arduino an integer is 16 bits (2 bytes) and a float is 32 bits (4 bytes) and the encoding in memory is little Endiness.

Using our temperature example to send as a 2 byte integer we use the following code.

int temp=20;
boolean rc;
byte buf[2];
buf[0] = (temp >> 8) & 0xFF;
buf[1] = temp & 0xFF;
rc = mqttClient.publish("test/buffer_int",buf,2 );

Notice the 2 at the end of the publish. As we are sending a byte buffer we need to tell the publish how many bytes there are.

To send a float e.g our humidity reading we use the following code.

//taken from stackoverflow
void float2Bytes(float val,byte* bytes_array){
  // Create union of shared memory space
  union {
    float float_variable;
    byte temp_array[4];
  } u;
  // Overite bytes of union with float variable
  u.float_variable = val;
  // Assign bytes to input array
  memcpy(bytes_array, u.temp_array, 4);
}

float humidity =60.11;
boolean rc;
byte bytes[4];
float2Bytes(f,&bytes[0]);
rc = mqttClient.publish("test/buffer_float",bytes,4 );

In this case it is more complex and requires a separate function. Again notice the 4 at the end of the publish as we are sending 4 bytes.

Note: I do not take credit for the code as it was gleaned from answers to questions on stackoverflow.

With the float The Endiness is the Endiness of the stored data which appears to be little. I discovered this as I create a node-red flow to decode the buffer and had to use Little. The code for the function node is shown below:

let buf=msg.payload;
msg.payload=buf.readFloatLE();
return msg;

Demo code. The download is an Arduino sketch that illustrate the above.

Demo Sketch

Sends integer,long integer,float and double as strings and
sends integer and float as buffer subscribe to test/# to view.

download

The results are shown in the screen shot below which is obtained by using the mosquitto_sub tool to subscribe to the topic.

You should notice that when using buffers the displayed message looks like gibberish as it is not text data and so cannot be displayed correctly.

arduino-publish

arduino

Receiving integers and Floats

In addition to receiving text data in Arduino we need to be able to receive both integers and floats and use them.

Again as in the sending tutorial the integers/floats may be represented as strings or as buffer data.

So we will need to decode the received data and store it in a variable

Receiving integers and Floats as Strings

In this case our integer arrives as a series of numbers e.g 200 and then needs to be converted into an Integer.

To convert a string number into Integer we use the built in function atoi(). The code is simply

int num =atoi(number_as_string)

Example:

int num =atoi(200);

To convert a string float into a float that we can use in Arduino we use the atof() function.

float num =atof(float_as_string)

Example:

float num =atof(260.21);

The demo sketch below accepts humidity(float) and temperature(integer) readings and multiplies them together and displays the result.

You send data using the mosquitto_pub tool on topics test/demo/temp and test/demo/humidity.

Below is a screen shot of the result.

arduino-receive-data

Receiving Integers and Floats as Buffers

To convert a 2 byte integer buffer into a 16 bit integer we use:

temp=(payload[0] << 8) + payload[1];

where  payload is a byte buffer.

To convert a4 byte float buffer into a 32 bit float we use a function :

float bytesToFloat( unsigned char b0, unsigned  char b1, unsigned  char b2, unsigned  char b3)
{
    float output;
//may need to reverse these
    *((unsigned  char*)(&output) + 3) = b3;
    *((unsigned  char*)(&output) + 2) = b2;
    *((unsigned  char*)(&output) + 1) = b1;

  *((unsigned char*)(&output) + 0) = b0;

    return output;
}
and we call it passing in the bytes from the payload
hum = bytesToFloat(payload[0],payload[1],payload[2],payload[3]);

Where the payload contains the input bytes.

Depending on the Endiness we may need to change the order and use:

hum = bytesToFloat(payload[3],payload[2],payload[1],payload[0]);

Demo Sketch

The download contains two sketches

1-Accepts float and int as text string on topics test/demo/humidity and test/demo/temp and multiples the values and displays the result to prove they are numbers.

2- Accepts float and int as  buffer on topics test/demo/humidity and test/demo/temp and multiples the values and displays the result to prove they are numbers.

download

Related Tutorials and resources.

Please rate? And use Comments to let me know more

2 comments

Leave a Reply

Your email address will not be published. Required fields are marked *