Site icon techtutorialsx

ESP32: serializing DS18B20 temperature measurement to MessagePack format

In this tutorial we will check how to obtain a temperature measurement from the DS18B20 sensor and serialize it using the MessagePack format. The tests were performed using a DFRobot’s ESP32 module integrated in a ESP32 development board and a waterproof version of the sensor.

Introduction

In this tutorial we will check how to obtain a temperature measurement from the DS18B20 sensor and serialize it using the MessagePack format.

For the MessagePack serialization, we will use the ArduinoJson library. We have already covered in detail how to serialize content to this format on this post.

For a detailed tutorial on how to obtain temperature measurements from the DS18B20 sensor, please check here. The mentioned tutorial has the electric diagram of the connection between the sensor and the ESP32 and covers the installation of all the libraries we are going to need.

The tests were performed using a DFRobot’s ESP32 module integrated in a ESP32 development board and a waterproof version of the sensor.

The code

We will start our code by the library includes. We will need the following libraries:

#include <ArduinoJson.h>
#include "OneWire.h"
#include "DallasTemperature.h"

Next we will need to instantiate an object of class OneWire. The constructor of this class receives as input the number of the microcontroller pin that will be connected to the temperature sensor. For this tutorial I’ve used pin 22.

OneWire oneWire(22);

After this, we will instantiate an object of class DallasTemperature, which will expose the higher level methods needed to obtain the measurements from the sensor.

The constructor of this class receives as input the address of a OneWire object. We will pass the address of the object we have just created. The OneWire object will be used under the hood to exchange data with the sensor.

DallasTemperature tempSensor(&oneWire);

Moving on the setup function, we will start by opening a serial connection, so we can output the results of the program.

After that we will call the begin method on the DallasTemperature object. This method takes no arguments and it will initialize the OneWire bus.

void setup(void)
{
  
  Serial.begin(115200);
  tempSensor.begin();
}

We will write the rest of the code in the Arduino loop function, so it runs periodically.

We will start by declaring a StaticJsonDocument object, which will hold the in memory representation of our object. We will declare a capacity of 100 bytes for our object, which is more than enough to hold the data. You can use this assistant for a more accurate estimation.

StaticJsonDocument<100> testDocument;

After this we will obtain a temperature measurement. First we call the requestTemperaturesByIndex method of our DallasTemperature object, in order for the sensor to start doing a temperature conversion.

Since the OneWire protocol supports having multiple devices connected simultaneously to the same bus, we need to pass as input of this method the index of the device we want to use. Since we just have one device connected, we pass the index 0.

Note that, by default, this function call will block until the conversion is performed.

tempSensor.requestTemperaturesByIndex(0);

Once the conversion is finished, we can obtain the temperature value by calling the getTempCByIndex method. As input, we pass again the device index, which should be 0.

float temperature = tempSensor.getTempCByIndex(0);

Next we will set the values in our StaticJsonDocument, using the [] operator. To have a slightly more complex data structure, we will first set a key called “sensorType” that will have the value “Temperature“.

We will then add a key called “sensorValue” that will hold the value of our previously obtained measurement.

testDocument["sensorType"] = "Temperature";
testDocument["sensorValue"] = temperature;

We will now print the temperature value we obtained from the sensor. That way, we can later compare it with was serialized to the MessagePack payload.

Note that, by default, the print method will only output 2 decimal places of float values. Thus, our temperature will only display 2 decimal places when we are checking the result in the serial monitor, whereas it can have more decimal places when we deserialize the MessagePack payload.

Serial.println("Temperature: ");
Serial.print(temperature);
Serial.println(" C");

To finalize, we will now serialize our data to the MessagePack format and print the result. We will first declare a buffer to hold the resulting data and then perform the serialization by calling the serializeMsgPack function.

char buffer[100];

int bytesWritten = serializeMsgPack(testDocument, buffer);

Then we will iterate through all the bytes of the payload and print them to the serial port, in hexadecimal format.

for(int i = 0; i<bytesWritten; i++){
    Serial.printf("%02X ",buffer[i]);
}

The final code can be seen below. We have introduced a small delay of 5 seconds between each iteration of the loop.

Note that using a delay is a simplification to make our code simpler. For more accurate periodic measurements, we should use timer interrupts instead, as covered here.

#include <ArduinoJson.h>
#include "OneWire.h"
#include "DallasTemperature.h"
  
OneWire oneWire(22);
DallasTemperature tempSensor(&oneWire);
  
void setup(void)
{
  
  Serial.begin(115200);
  tempSensor.begin();
}
  
void loop(void)
{
  StaticJsonDocument<100> testDocument;
     
  tempSensor.requestTemperaturesByIndex(0);
  float temperature = tempSensor.getTempCByIndex(0);

  testDocument["sensorType"] = "Temperature";
  testDocument["sensorValue"] = temperature;
  
  Serial.println("Temperature: ");
  Serial.print(temperature);
  Serial.println(" C");

  Serial.println("Serialized message: ");

  char buffer[100];
   
  int bytesWritten = serializeMsgPack(testDocument, buffer);
  
  for(int i = 0; i<bytesWritten; i++){
    Serial.printf("%02X ",buffer[i]);
  }

  Serial.println("\n------------");
  
  delay(5000);
}

Testing the code

To test the code, simply compile and upload it to your ESP32 device, after all the connections to the sensor are done. When the procedure is finished, you should obtain a result like the one shown in figure 1.

Figure 1 – Output of the program on the Arduino IDE serial monitor.

To test if the encoded message has the expected temperature value, we can use this online tool, which allows to perform the decoding. As can be seen in figure 2, the message correctly decodes to the data structure we defined in our program.

Figure 2 – Decoding the message on an online tool.

Related Posts

Exit mobile version