Learn how to publish DS18B20 temperature readings via MQTT with the ESP32 to any platform that supports MQTT or any other MQTT client. As an example, we’ll publish sensor readings to Node-RED Dashboard and the ESP32 will be programmed using Arduino IDE.
Recommended reading: What is MQTT and How It Works
Project Overview
The following diagram shows a high-level overview of the project we’ll build.
- The ESP32 request temperature readings from the DS18B20 sensor. The readings are published in the esp32/ds18b20/temperature topic;
- Node-RED is subscribed to the esp32/ds18b20/temperature topic. So, it receives the DS18B20 temperature readings and displays the readings in a gauge/chart;
- You can receive the readings in any other platform that supports MQTT and handle the readings as you want.
Prerequisites
Before proceeding with this tutorial, make sure you check the following prerequisites.
Arduino IDE
We’ll program the ESP32 using Arduino IDE, so make sure you have the ESP32 add-on installed.
MQTT Broker
To use MQTT, you need a broker. We’ll be using Mosquitto broker installed on a Raspberry Pi. Read How to Install Mosquitto Broker on Raspberry Pi.
You can use any other MQTT broker, including a cloud MQTT broker. We’ll show you how to do that in the code later on.
If you’re not familiar with MQTT make sure you read our introductory tutorial: What is MQTT and How It Works.
MQTT Libraries
To use MQTT with the ESP32 we’ll use the Async MQTT Client Library.
Installing the Async MQTT Client Library
- Click here to download the Async MQTT client library. You should have a .zip folder in your Downloads folder
- Unzip the .zip folder and you should get async-mqtt-client-master folder
- Rename your folder from
async-mqtt-client-masterto async_mqtt_client - Move the async_mqtt_client folder to your Arduino IDE installation libraries folder
- Finally, re-open your Arduino IDE
Alternatively, you can go to Sketch > Include Library > Add . ZIP library and select the library you’ve just downloaded.
Installing the Async TCP Library
To use MQTT with the ESP, you also need the Async TCP library.
- Click here to download the Async TCP client library. You should have a .zip folder in your Downloads folder
- Unzip the .zip folder and you should get AsyncTCP-master folder
- Rename your folder from
AsyncTCP-masterto AsyncTCP - Move the AsyncTCP folder to your Arduino IDE installation libraries folder
- Finally, re-open your Arduino IDE
Alternatively, you can go to Sketch > Include Library > Add . ZIP library and select the library you’ve just downloaded.
DS18B20 Temperature Sensor Libraries
To interface with the DS18B20 temperature sensor, you need to install the One Wire library by Paul Stoffregen and the Dallas Temperature library. Follow the next steps to install those libraries.
1. Open your Arduino IDE and go to Sketch > Include Library > Manage Libraries. The Library Manager should open.
2. Type “onewire” in the search box and install OneWire library by Paul Stoffregen.
3. Then, search for “Dallas” and install DallasTemperature library by Miles Burton.
After installing the libraries, restart your Arduino IDE.
To learn more about the DS18B20 temperature sensor, read our guide: ESP32 DS18B20 Temperature Sensor with Arduino IDE (Single, Multiple, Web Server).
Parts Required
For this tutorial you need the following parts:
- ESP32 (read Best ESP32 development boards)
- DS18B20 Temperature Sensor – DS18B20 with ESP32 Guide
- 4.7k Ohm resistor
- Raspberry Pi board (read Best Raspberry Pi Starter Kits)
- MicroSD Card – 16GB Class10
- Raspberry Pi Power Supply (5V 2.5A)
- Jumper wires
- Breadboard
You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!
Schematic Diagram
Wire the DS18B20 to the ESP32 as shown in the following schematic diagram with the DS18B20 data pin connected to GPIO 4.
Code
Copy the following code to your Arduino IDE. To make it work for you, you need to insert your network credentials as well as the MQTT broker details.
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp32-mqtt-publish-ds18b20-temperature-arduino/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
#include <WiFi.h>
extern "C" {
#include "freertos/FreeRTOS.h"
#include "freertos/timers.h"
}
#include <AsyncMqttClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define WIFI_SSID "REPLACE_WITH_YOUR_SSID"
#define WIFI_PASSWORD "REPLACE_WITH_YOUR_PASSWORD"
// Raspberry Pi Mosquitto MQTT Broker
#define MQTT_HOST IPAddress(192, 168, 1, XXX)
// For a cloud MQTT broker, type the domain name
//#define MQTT_HOST "example.com"
#define MQTT_PORT 1883
// Temperature MQTT Topic
#define MQTT_PUB_TEMP "esp32/ds18b20/temperature"
// GPIO where the DS18B20 is connected to
const int oneWireBus = 4;
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(oneWireBus);
// Pass our oneWire reference to Dallas Temperature sensor
DallasTemperature sensors(&oneWire);
// Temperature value
float temp;
AsyncMqttClient mqttClient;
TimerHandle_t mqttReconnectTimer;
TimerHandle_t wifiReconnectTimer;
unsigned long previousMillis = 0; // Stores last time temperature was published
const long interval = 10000; // Interval at which to publish sensor readings
void connectToWifi() {
Serial.println("Connecting to Wi-Fi...");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
}
void connectToMqtt() {
Serial.println("Connecting to MQTT...");
mqttClient.connect();
}
void WiFiEvent(WiFiEvent_t event) {
Serial.printf("[WiFi-event] event: %d\n", event);
switch(event) {
case ARDUINO_EVENT_WIFI_STA_GOT_IP:
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
connectToMqtt();
break;
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
Serial.println("WiFi lost connection");
xTimerStop(mqttReconnectTimer, 0); // ensure we don't reconnect to MQTT while reconnecting to Wi-Fi
xTimerStart(wifiReconnectTimer, 0);
break;
}
}
void onMqttConnect(bool sessionPresent) {
Serial.println("Connected to MQTT.");
Serial.print("Session present: ");
Serial.println(sessionPresent);
}
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
Serial.println("Disconnected from MQTT.");
if (WiFi.isConnected()) {
xTimerStart(mqttReconnectTimer, 0);
}
}
/*void onMqttSubscribe(uint16_t packetId, uint8_t qos) {
Serial.println("Subscribe acknowledged.");
Serial.print(" packetId: ");
Serial.println(packetId);
Serial.print(" qos: ");
Serial.println(qos);
}
void onMqttUnsubscribe(uint16_t packetId) {
Serial.println("Unsubscribe acknowledged.");
Serial.print(" packetId: ");
Serial.println(packetId);
}*/
void onMqttPublish(uint16_t packetId) {
Serial.println("Publish acknowledged.");
Serial.print(" packetId: ");
Serial.println(packetId);
}
void setup() {
// Start the DS18B20 sensor
sensors.begin();
Serial.begin(115200);
Serial.println();
Serial.println();
mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToMqtt));
wifiReconnectTimer = xTimerCreate("wifiTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToWifi));
WiFi.onEvent(WiFiEvent);
mqttClient.onConnect(onMqttConnect);
mqttClient.onDisconnect(onMqttDisconnect);
//mqttClient.onSubscribe(onMqttSubscribe);
//mqttClient.onUnsubscribe(onMqttUnsubscribe);
mqttClient.onPublish(onMqttPublish);
mqttClient.setServer(MQTT_HOST, MQTT_PORT);
// If your broker requires authentication (username and password), set them below
//mqttClient.setCredentials("REPlACE_WITH_YOUR_USER", "REPLACE_WITH_YOUR_PASSWORD");
connectToWifi();
}
void loop() {
unsigned long currentMillis = millis();
// Every X number of seconds (interval = 10 seconds)
// it publishes a new MQTT message
if (currentMillis - previousMillis >= interval) {
// Save the last time a new reading was published
previousMillis = currentMillis;
// New temperature readings
sensors.requestTemperatures();
// Temperature in Celsius degrees
temp = sensors.getTempCByIndex(0);
// Temperature in Fahrenheit degrees
//temp = sensors.getTempFByIndex(0);
// Publish an MQTT message on topic esp32/ds18b20/temperature
uint16_t packetIdPub1 = mqttClient.publish(MQTT_PUB_TEMP, 1, true, String(temp).c_str());
Serial.printf("Publishing on topic %s at QoS 1, packetId: ", MQTT_PUB_TEMP);
Serial.println(packetIdPub1);
Serial.printf("Message: %.2f /n", sensors.getTempCByIndex(0));
}
}
How the Code Works
The following section imports all the required libraries.
#include <WiFi.h>
extern "C" {
#include "freertos/FreeRTOS.h"
#include "freertos/timers.h"
}
#include <AsyncMqttClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>
Include your network credentials on the following lines.
#define WIFI_SSID "REPLACE_WITH_YOUR_SSID"
#define WIFI_PASSWORD "REPLACE_WITH_YOUR_PASSWORD"
Insert the Raspberry Pi IP address, so that the ESP32 connects to your broker.
#define MQTT_HOST IPAddress(192, 168, 1, 106)
If you’re using a cloud MQTT broker, insert the broker domain name, for example:
#define MQTT_HOST "example.com"
Define the MQTT port.
#define MQTT_PORT 1883
We’ll publish the temperature on the esp32/ds18b20/temperature topic. If you want to change the topic, change it on the following line.
#define MQTT_PUB_TEMP "esp32/ds18b20/temperature"
You can create more topics if you want.
Setup your DS18B20 on the following lines. In our case, it is connected to GPIO 4. You can connect it to any other GPIO.
// GPIO where the DS18B20 is connected to
const int oneWireBus = 4;
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(oneWireBus);
// Pass our oneWire reference to Dallas Temperature sensor
DallasTemperature sensors(&oneWire);
The temp variable will hold the temperature value from the DS18B20 temperature sensor.
float temp;
Create an AsyncMqttClient object called mqttClient to handle the MQTT client and timers to reconnect to your MQTT broker and router when it disconnects.
AsyncMqttClient mqttClient;
TimerHandle_t mqttReconnectTimer;
TimerHandle_t wifiReconnectTimer;
Then, create some auxiliary timer variables to publish the readings every 10 seconds. You can change the delay time on the interval variable.
unsigned long previousMillis = 0; // Stores last time temperature was published
const long interval = 10000; // Interval at which to publish sensor readings
MQTT functions: connect to Wi-Fi, connect to MQTT, and Wi-Fi events
We haven’t added any comments to the functions defined in the next code section. Those functions come with the Async Mqtt Client library. The function’s names are pretty self-explanatory.
For example, the connectToWifi() connects your ESP32 to your router:
void connectToWifi() {
Serial.println("Connecting to Wi-Fi...");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
}
The connectToMqtt() connects your ESP32 to your MQTT broker:
void connectToMqtt() {
Serial.println("Connecting to MQTT…");
mqttClient.connect();
}
The WiFiEvent() function is responsible for handling the Wi-Fi events. For example, after a successful connection with the router and MQTT broker, it prints the ESP32 IP address. On the other hand, if the connection is lost, it starts a timer and tries to reconnect.
void WiFiEvent(WiFiEvent_t event) {
Serial.printf("[WiFi-event] event: %d\n", event);
switch(event) {
case ARDUINO_EVENT_WIFI_STA_GOT_IP:
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
connectToMqtt();
break;
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
Serial.println("WiFi lost connection");
xTimerStop(mqttReconnectTimer, 0);
xTimerStart(wifiReconnectTimer, 0);
break;
}
}
The onMqttConnect() function runs after starting a session with the broker.
void onMqttConnect(bool sessionPresent) {
Serial.println("Connected to MQTT.");
Serial.print("Session present: ");
Serial.println(sessionPresent);
}
MQTT functions: disconnect and publish
If the ESP32 loses connection with the MQTT broker, calls the onMqttDisconnect function that prints that message in the serial monitor.
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
Serial.println("Disconnected from MQTT.");
if (WiFi.isConnected()) {
xTimerStart(mqttReconnectTimer, 0);
}
}
When you publish a message to an MQTT topic, the onMqttPublish() function is called. It prints the packet id in the Serial Monitor.
void onMqttPublish(uint16_t packetId) {
Serial.println("Publish acknowledged.");
Serial.print(" packetId: ");
Serial.println(packetId);
}
Basically, all these functions that we’ve just mentioned are callback functions. So, they are executed asynchronously.
setup()
Now, let’s proceed to the setup(). Initialize the DS18B20 sensor and start the serial communication.
sensors.begin();
Serial.begin(115200);
The next two lines create timers that will allow both the MQTT broker and Wi-Fi connection to reconnect, in case the connection is lost.
mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToMqtt));
wifiReconnectTimer = xTimerCreate("wifiTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToWifi));
The following line assigns a callback function, so when the ESP32 connects to your Wi-Fi, it will execute the WiFiEvent() function to print the details described earlier.
WiFi.onEvent(WiFiEvent);
Finally, assign all the callbacks functions. This means that these functions will be executed automatically when needed. For example, when the ESP32 connects to the broker, it automatically calls the onMqttConnect() function, and so on.
mqttClient.onConnect(onMqttConnect);
mqttClient.onDisconnect(onMqttDisconnect);
//mqttClient.onSubscribe(onMqttSubscribe);
//mqttClient.onUnsubscribe(onMqttUnsubscribe);
mqttClient.onPublish(onMqttPublish);
mqttClient.setServer(MQTT_HOST, MQTT_PORT);
Broker Authentication
If your broker requires authentication, uncomment the following line and insert your credentials (username and password).
mqttClient.setCredentials("REPlACE_WITH_YOUR_USER", "REPLACE_WITH_YOUR_PASSWORD");
Finally, connect to Wi-Fi.
connectToWifi();
loop()
In the loop(), you create a timer that will allow you to publish new temperature readings in the esp32/d18b20/temperature topic every 10 seconds.
unsigned long currentMillis = millis();
// Every X number of seconds (interval = 10 seconds)
// it publishes a new MQTT message
if (currentMillis - previousMillis >= interval) {
// Save the last time a new reading was published
previousMillis = currentMillis;
// New temperature readings
sensors.requestTemperatures();
// Temperature in Celsius degrees
temp = sensors.getTempCByIndex(0);
If you prefer the temperature in Fahrenheit, uncomment the following line:
//temp = sensors.getTempFByIndex(0);
Learn more about the DS18B20 temperature sensor: ESP32 with DS18B20 Temperature Sensor Guide.
Publishing to topics
To publish a message on an MQTT topic, use the next line:
uint16_t packetIdPub1 = mqttClient.publish(MQTT_PUB_TEMP, 1, true, String(temp).c_str());
If you would like to publish more readings on different topics, you can duplicate this previous line the loop().
Basically, use the publish() method on the mqttClient object to publish data on a topic. The publish() method accepts the following arguments, in order:
- MQTT topic (const char*)
- QoS (uint8_t): quality of service – it can be 0, 1 or 2
- retain flag (bool): retain flag
- payload (const char*)
The QoS (quality of service) is a way to guarantee that the message is delivered. It can be one of the following levels:
- 0: the message will be delivered once or not at all. The message is not acknowledged. There is no possibility of duplicated messages;
- 1: the message will be delivered at least once, but may be delivered more than once;
- 2: the message is always delivered exactly once;
- Learn about MQTT QoS.
Uploading the code
With your Raspberry Pi powered on and running the Mosquitto MQTT broker, upload the code to your ESP32.
Open the Serial Monitor at a baud rate of 115200 and you’ll see that the ESP32 starts publishing messages.
Preparing Node-RED Dashboard
The ESP32 is publishing temperature readings every 10 seconds on the esp32/ds18b20/temperature topic. Now, you can use any dashboard that supports MQTT or any other device that supports MQTT to subscribe to that topic and receive the readings.
As an example, we’ll create a simple flow using Node-RED to subscribe to that topic and display the readings on a gauge or chart.
If you don’t have Node-RED installed, follow the next tutorials:
- Getting Started with Node-RED on Raspberry Pi
- Installing and Getting Started with Node-RED Dashboard
Having Node-RED running on your Raspberry Pi, go to your Raspberry Pi IP address followed by :1880.
http://raspberry-pi-ip-address:1880
The Node-RED interface should open. Drag an MQTT in node, a chart node and a gauge node to the flow.
Click the MQTT node and edit its properties as follows:
The Server field refers to the MQTT broker. In our case, the MQTT broker is the Raspberry Pi, so it is set to localhost:1883. If you’re using a Cloud MQTT broker, you should change that field. Insert the topic you want to be subscribed to and the QoS.
Set the following properties for the gauge node.
Edit the chart node as follows:
Wire your nodes as shown below:
Finally, deploy your flow (press the button on the upper right corner).
Alternatively, you can go to Menu > Import and copy the following to your Clipboard to create your Node-RED flow.
[{"id":"5a45b8da.52b0d8","type":"mqtt in","z":"b01416d3.f69f38","name":"","topic":"esp32/ds18b20/temperature","qos":"1","datatype":"auto","broker":"8db3fac0.99dd48","x":380,"y":280,"wires":[["3042e15e.80a4ee","4c53cb0f.3e6084"]]},{"id":"3042e15e.80a4ee","type":"ui_gauge","z":"b01416d3.f69f38","name":"","group":"2b7ac01b.fc984","order":0,"width":0,"height":0,"gtype":"gage","title":"Temperature","label":"ºC","format":"{{value}}","min":0,"max":"40","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":650,"y":240,"wires":[]},{"id":"4c53cb0f.3e6084","type":"ui_chart","z":"b01416d3.f69f38","name":"","group":"2b7ac01b.fc984","order":1,"width":0,"height":0,"label":"Temperature","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"outputs":1,"x":650,"y":320,"wires":[[]]},{"id":"8db3fac0.99dd48","type":"mqtt-broker","z":"","name":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"2b7ac01b.fc984","type":"ui_group","z":"","name":"DS18B20 Temperature Sensor","tab":"99ab8dc5.f435c","disp":true,"width":"6","collapse":false},{"id":"99ab8dc5.f435c","type":"ui_tab","z":"","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]
Demonstration
Go to your Raspberry Pi IP address followed by :1880/ui.
http://raspberry-pi-ip-address:1880/ui
You should get access to the current sensor readings on the Dashboard (gauge and chart).
That’s it! You have your ESP32 board publishing sensor readings to Node-RED via MQTT.
Wrapping Up
MQTT is a great communication protocol to exchange small amounts of data between devices. In this tutorial you’ve learned how to publish DS18B20 temperature readings with the ESP32 on an MQTT topic. Then, you can use any device or home automation platform to subscribe to that topic and receive the readings.
Instead of a DS18B20 temperature sensor, you can use any other sensor and you can also publish on multiple topics at the same time.
We hope you’ve found this tutorial useful. If you want to learn more about the ESP32, take a look at our resources:
Thanks for reading.
Thanks for great tutorial and mqtt knowledge too.
Your RNT resources are very useful for me.
I am thinking how I can do this with the domoticz.
I used sonoff-tasmota for my applications.
Hi.
At the moment, we don’t have any tutorials about that and I’m not familiar with domoticz.
However, if you search for “domoticz MQTT subscribe” you should be able to find out.
Thanks for following our work.
Regards,
Sara
Hi Sara,
Could you help me to find coding for the combination of temperature sensor and TDS sensor. I have tried but still not working.
This idea can be made really useful when coupled with a smartphone app. I made a ‘sous vide’ controller in roughly the same way (PID code working on an ESP8266 with the MQTT broker hosted (for convenience) on my Linux server) by installing MQTT Dash on my Android phone. It can both monitor and change the values used by the PID temperature controller. There are other apps that would likely work as well.
excellent tutorial
thanks and keep on the good work
rgds
Carlos Frondizi
My mosquitto broker requires username and password. Any change you indicate where to put this in the code
Hi.
In the code there’s a line that allows you to set the username and password.
Search for the following line and uncomment it:
mqttClient.setCredentials(“REPlACE_WITH_YOUR_USER”, “REPLACE_WITH_YOUR_PASSWORD”);
Regards,
Sara
Hi, nice tutorial,
I didn’t have a ds18b20, so altered for a bme280. The serial output looks like the MQTT doesn’t really connect and I get no packet acks back. I only changed the mechanism for the temperature readings, not the MQTT connects. packet id is 0 not 1. Mosquitto supposedly runs at boot time.
Node red on my PI looks dead. Also tried to set credentials.
Google app MQTTLens gives a quick and dirty way of monitoring the Mosquitto broker if that is any help.
Red faced, works better when you don’t mistype the brokers IP.
Hi.
Meanwhile, we’ve published a similar tutorial for the BME280: https://randomnerdtutorials.com/esp32-mqtt-publish-bme280-arduino/
Regards,
Sara
Congratulations – this is an excellent tutorial, I think the best I have seen so far. Using this as a basis you can create an unlimited number of ESP32 MQTT applications.
If you could add TLS using a self signed certificate then it could be used for even more applications.
Very well done – Keep up the good work!
Nice project, thank you!
Something does no work at my end
My situation
Local network (IPs 192.168.0.1….255)
RPi MQTT broker 192.168.0.28(:1880)
I did copy the sketch, adjusted the SSID and Passwd data
After successfully compiling the sketch I see among other text in the serial monitor:
confirmation of wifi connection,
connecting to MQTT directly followed by:
Publishing on topic esp32/etc at QoS 1, packetId 0 Message: 23.88 /nDisconnected from MQTT.
The code:
void onMqttConnect(bool sessionPresent) {
Serial.println(“Connected to MQTT.”);
Serial.print(“Session present: “);
Serial.println(sessionPresent);
}
Has not been executed. (NO confirmation of connection)
In the MQTT dashboard the temperature gauge remains 0
Can you give me a direction where to look for a solution?
Thank you for an answer
Hi.
Can you double-check the broker IP address? Also, make sure that the Raspberry Pi is currently running.
It is very difficult to find out what might be wrong without further information.
Regards,
Sara
This is great. Would like to see tutorial/example of subscribing (ei: to a cmd) and doing something (ei: light led or relay)
Joe
Ok, I give up. What is the syntax to get data from a subscription with this library?
Hi.
Example to subscribe to topics:
void onMqttConnect(bool sessionPresent) {
Serial.println("Connected to MQTT.");
Serial.print("Session present: ");
Serial.println(sessionPresent);
uint16_t packetIdSub = mqttClient.subscribe("esp32/temperature", 0);
Serial.print("Subscribing at QoS 0, packetId: ");
Serial.println(packetIdSub);
}
Example to receive message on a subscribed topic:
void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) {
String messageTemp;
for (int i = 0; i < len; i++) {
//Serial.print((char)payload[i]);
messageTemp += (char)payload[i];
}
if (strcmp(topic, "esp32/temperature") == 0) {
lcd.clear();
lcd.setCursor(1, 0);
lcd.write(0);
lcd.print(" Temperature");
lcd.setCursor(0, 1);
lcd.print(messageTemp);
}
}
I hope this helps.
Regards,
Sara
Thank you! Will try soon.
Joe
Hi,
Following everything and failing a lot of times I got the next thing working:
Node Red can read 3x DS18B20 Temp Sensors and one logic input from an ESP-8266 on the network.
However I also need a Push Button in Node red to give a logic pulse to an output pin of the ESP-8266. So I can’t figure out the Subscribe part on the side of ESP.
Even with your Subscribe Receive examples above I can’t figure out or modify a code that works for my application. Any useful tip?
Thanks,
Carlo
Hi Joseph.
We’re planning to write some tutorials about subscribing.
Meanwhile, you can take a look at this project that contains an example of subscribing (however, it doesn’t use the same library).
https://randomnerdtutorials.com/esp32-mqtt-publish-subscribe-arduino-ide/
Regards,
Sara
I have a simple question – where do I find the AsyncMqttClient library? Looked in github but all I saw was to source code to build it. Don’t feel like compiling the source if I can avoid it.
Hi.
You just need to follow the instructions on the tutorial. See the “MQTT Libraries” heading. Everything is explained there. You just need to download the library and then, include it in the libraries folder.
Regards,
Sara
Hi,
I would like to control my device, e.g. ESP32/ESP8266 from any network or anywhere in the world e.g. by installing a webpage on the client side. I still don’t see any tutorial or I may have over seen it.
I am not sure if it is part of a tutorial in one of the books. Please advise.
thank you.
Hi.
Take a look at the following tutorial:
https://randomnerdtutorials.com/control-esp32-esp8266-gpios-from-anywhere/
Or this:
https://randomnerdtutorials.com/access-node-red-dashboard-anywhere-digital-ocean/
Regards,
Sara
Hello
how can i add freertos librery for arduino ide
( #include “freertos/FreeRTOS.h”
#include “freertos/timers.h” )
Hello
how can i add freertos librery for arduino ide
( #include “freertos/FreeRTOS.h”
#include “freertos/timers.h” )
d
Sara,
Thanks for the tutorial. There are several others you have written that are also very useful. Nice work.
If you are still following up on this older tutorial…
I am trying to receive and send several messages from each of the esp32s in my network of esp32s and a pi zero-w broker. With the asyncMQTT library, I am unclear about a few details.
1) Are the “mqttReconnectTimer” and “wifiReconnectTimer” only used if a disconnection occurs, or are they more important that I should adjust them if I am trying to have fast messaging (preferably within a couple hundred milliseconds or less for around 6 topics)?
2) Does there need to be any time delay between publish events in my loop?
3) When receiving and parsing the various topics and messages, can I use the “strcmp” to determine which topic is coming in and process, or do I need to use “strstr”? I am not yet clear if they library is already breaking the messages into single messages or if I need to parse out the string for the relevant topic and work with the pointers like what I think may be done with pubsubclient library (just started with this so I may be very wrong with my assumption).
I am asking since I am having some sort of assumed timing or overlapping data issue on the receiving end. I have to really slow down the publish rate to several seconds to avoid having the receiving being confused with the other topics. I understand MQTT to be very fast so I could have maybe 100ms delay between publish sequences, but that makes my receiver mash everything together. I read a couple posts that suggest I may be having multi core issues with the esp32.
Any suggestions would be appreciated. Thanks again.
OK, I am still interested in questions 1,2,&3 for clarification, but I did find the source of my seemingly overlapping data issue.
I was using “atoi(payload)” directly to the payload to get the int value I needed. That is giving bad results. It does not seem to catch the end of the char array. I am sure I am not using atoi correctly, but I do not understand how to here. My solution was to use the payload to string as written in your original example then use “messageTemp.toInt()” to get the int value I was trying to read. This is a bit of extra work for the processor, but it is allowing me to have 10ms publish increments for integer messages without any delay between publishes in my loop. The results for Qos2 messages seems solid.
If you get around to looking into my initial questions, I would very much appreciate it.
Happy New Year!
I try to get QoS =2 working on an ESP32 with this library.
I can see the data coming in with mosquitto_sub, no problem.
But I cannot see the data in Telegraf, the debugger indicates it wants a ClientID.
How can I set a ClientID in my ESP32 code?
Thank you
Hi.
What project are you following?
Regards,
Sara
Hi Sara,
I am monitoring the weight and temperature of my beehives, so my interest is in making an end node that is in deep sleep most of the time and every 15 minutes or so publishes a few bytes to a Mosquitto broker.
If I do this over WiFi at QoS=0, I have to wait about 1s after publishing to get 99% of the data to the broker. At QoS=1 the node waits for confirmation that the data has reached the broker, and then goes to deep sleep. This takes on average 0.5s, which is clearly better.
What puzzles me is that time from deep sleep to getting an IP address is pretty constant near 175ms, but that the MQTT broker needs anything between 100ms and sometimes a few seconds to complete on a Raspberry Pi that has ‘nothing else to do’.
So I am following your blogs on these subjects. Just to learn and have fun because my current solution at QoS=1 is fit for purpose.
Regards, Rob
Hi all,
The AsyncMqttClient.h library needs the dependencies AsyncTCP for ESP32 and ESPAsyncTCP for ESP8266 but when I try to compile the arduino project it tries to use both.
Everything I could read is about solving this problem in PlatformIO instead of Arduino IDE. How can I avoid this?
Thanks.
Hi.
What is the exact error that you’re getting?
Regards,
Sara
Hello Rui. This is a great tutorial. Thank you.
How could a variable be coded into the mqtt line to change the topic based on the sensor number/ device number? From your code:
// Publish an MQTT message on topic esp32/ds18b20/temperature
uint16_t packetIdPub1 = mqttClient.publish(MQTT_PUB_TEMP, 1, true, String(temp).c_str());
For example, using 2 sensors, MQTT_PUB_TEMP would send “Sensor 0” and the temperature, for 1 sensor; and send “Sensor 1” and the temperature for the other.
Possible?
Best regards
Hi guys, I remember seeing in one of your tutorials about adding network credentials for more than one network, but I can’t find it after searching your site. I’d like to set up my esp device for one network in location 1, then when I move it to another location 2, I can have the sssid and pw included in the code to automatically connect to the network available. Sorry if this isn’t the best place to post this but if not let me know.
Thanks
Terry
Hi, i have a question, when i wanna connect to raspberry pi throught putty, it pop up a message that they cant find host, what can be the problem?
Hi.
Make sure your raspberry pi is on the same network.
Make sure you’re using the right raspberry pi hostname.
If you didn’t change it, it should be the default name: raspberrypi
Regards,
Sara
Hi. Thank for this useful tutorial. But could you help with code when i need add two or more sensors ds18b20?
Alex, good question, as I wondered how one wire works too. I googled “using 2 one wire devices” and found some good info. Not sure if that was your question, but it’s a good place to start, check this out. https://forum.arduino.cc/t/multiple-ds18b20-temperature-sensors-on-one-bus/139955
I used 3 sensors in my design. In the next link you can download my code:
https://we.tl/t-8nNwh8b6Ra
Guess with this you can figure it out. It has been to long for me to remember all the details of this code. So hopefully this helps.
Thank you so much for your help, I managed to solve my problem!
Thank you so much for your help, I managed to solve my problem
Hello Sara and Rui,
Thank you for the beautiful examples and explanations!
I have multiple DS18b20 sensor on 1 wire.
I followed the above example. However, I only get the readout of 1 sensor.
Ideally I would like to control my sensors by their address. (not on their index).
But I am not getting out of it.
Can you help me on my way with a small example?
How to have multiple sensors each read out to 1 Topic?
Kind regards
Tony Gruwez
Hi.
this tutorial shows how to get the temperature from different sensors from its address: https://randomnerdtutorials.com/esp32-multiple-ds18b20-temperature-sensors/
Then, you just need to publish each reading on a different topic.
Regards,
Sara
Hallo Sara,
ich habe folgende Fehler beim Kompilieren:
In file included from C:\Users\Martin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.6\cores\esp32/Arduino.h:36,
from C:\Users\Martin\Documents\Arduino\libraries\OneWire\OneWire.cpp:142:
C:\Users\Martin\Documents\Arduino\libraries\OneWire\util/OneWire_direct_gpio.h: In function ‘void directModeInput(uint32_t)’:
C:\Users\Martin\Documents\Arduino\libraries\OneWire\util/OneWire_direct_gpio.h:191:38: error: ‘esp32_gpioMux’ was not declared in this scope
ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = pinFunction;
^~~~~~~~~~~~~
C:\Users\Martin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.6\cores\esp32/esp32-hal.h:73:47: note: in definition of macro ‘ESP_REG’
#define ESP_REG(addr) *((volatile uint32_t *)(addr))
^~~~
C:\Users\Martin\Documents\Arduino\libraries\OneWire\util/OneWire_direct_gpio.h: In function ‘void directModeOutput(uint32_t)’:
C:\Users\Martin\Documents\Arduino\libraries\OneWire\util/OneWire_direct_gpio.h:232:38: error: ‘esp32_gpioMux’ was not declared in this scope
ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = pinFunction;
^~~~~~~~~~~~~
C:\Users\Martin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.6\cores\esp32/esp32-hal.h:73:47: note: in definition of macro ‘ESP_REG’
#define ESP_REG(addr) *((volatile uint32_t *)(addr))
^~~~
Mehrere Bibliotheken wurden für “WiFi.h” gefunden
Benutzt: C:\Users\Martin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.6\libraries\WiFi
Nicht benutzt: C:\Program Files (x86)\Arduino\libraries\WiFi
Nicht benutzt: C:\Users\Martin\Documents\Arduino\libraries\WiFiEspAT
Nicht benutzt: C:\Users\Martin\Documents\Arduino\libraries\WiFiNINA
exit status 1
Fehler beim Kompilieren für das Board ESP32 Dev Module.
Warum erscheinen die vielen Meldungen ?
Hi.
Did you install the recommended onewire library mentioned in the tutorial?
Regards,
Sara
Hi,
how can a disconnect of the whole client be monitored by the broker?
Is there an implementation of LWT or something else?
Hello, How is the async mqtt library different from the pubsubclient library? In terms of function, what does it do or allow you to do differently? Thanks.
Hello, I am following the course :
1. https://randomnerdtutorials.com/esp32-wi-fi-manager-asyncwebserver/
2. https://randomnerdtutorials.com/esp32-web-server-sent-events-sse/
3. https://randomnerdtutorials.com/esp32-websocket-server-arduino/
4. https://randomnerdtutorials.com/esp32-ota-over-the-air-arduino/
5. https://randomnerdtutorials.com/esp32-mqtt-publish-bme680-arduino/
My MQTT_HOST is “https://www.emqx.com/en”
But when I used AsyncMqttClient, I found that disconnection and reconnection would always fail.
This is the case even if I delete AsyncMqttClient and re-create it,
It wasn’t until I restarted my device that I could connect normally,
Do you know the reason and can you give me some suggestions?
Hi.
Can you better explain the issue you’re facing?
Regards,
Sara
Hi.
Currently I rely on ESPAsyncWebServer,
No problem until step 4,
But after adding the AsyncMqttClient part, there is no problem with communication.
But as long as the connection is interrupted due to unknown reasons of mqttHost,
At this time, I will fall into the event of infinite connection [onMqttConnect] and connection interruption [onMqttDisconnect]. Until the watchdog crashes or I manually restart the ESP32, the AsyncMqttClient connection can resume normal communication.
Because this message contains watchdog and CPU crashes,
So I removed mqttReconnectTimer and changed it to AsyncMqttClient connection in loop(), but the problem was not solved.
So I completely released the ~AsyncMqttClient object and re-created it.
But the connection still fails. The strange thing is that when I restart the ESP32, the AsyncMqttClient connection works fine.
Hi.
Add the following line
xTimerStop(wifiReconnectTimer, 0);
In this section (see newline in bold):
Serial.printf(“[WiFi-event] event: %d\n”, event);
switch(event) {
case ARDUINO_EVENT_WIFI_STA_GOT_IP:
Serial.println(“WiFi connected”);
Serial.println(“IP address: “);
Serial.println(WiFi.localIP());
xTimerStop(wifiReconnectTimer, 0);
connectToMqtt();
break;
Let me know if this fixes the issue…
Regards,
Sara
Hi.
After the reference modification, the situation is still the same and nothing has changed.
The relevant function libraries I use include:
1-a. github.com/mathieucarbou/AsyncTCP/tree/main
-b. github.com/me-no-dev/AsyncTCP
2. github.com/khoih-prog/AsyncTCP_SSL
3. github.com/khoih-prog/AsyncMQTT_Generic
ps: async-mqtt-client-master, Because this library cannot use 8883 port