In this article you will learn how to implement MQTT protocol in ESP32. We will use ESP32 as MQTT client and program our ESP32 in Arduino IDE. We will use the DHT sensor which is temperature and humidity sensor and we will publish that data to our broker and the data can be shown on our MQTT android app which we made using MIT app inventor like our last tutorial with MQTT in ESP8266.This tutorial is helpful for connecting ESP32 with local MQTT broker or cloudMQTT broker. There are number of free MQTT protocols that you can use for this such as HiveMQ free public broker and Mosquitto free MQTT broker.
DHT & LED with ESP32
First lets make the circuit and following is the buying guide for this project,
Buying Guide
Component | Amazon (US) | Aliexpress |
---|---|---|
ESP32 | ||
DHT11 / DHT22 | ||
LED | ||
Resistor | ||
Breadboard | ||
Jumper wires | ||
Micro USB cable |
Disclosure: Some of these links are affiliate links. We may earn commission on you purchase at no extra cost to you. Support us by buying from here .
DHT sensor with ESP32
The thermistor and capacitive humidity sensor are the two components that make up the DHT sensors. A very simple chip that converts analog data to digital data and outputs a digital signal with the temperature and humidity is also included within. Any micro controller can easily read the digital signal. The DHT11 or DHT22 usually have 3 or 4 pins. VCC, GND, Digital output and most of DHT sensor has extra pin which is usually labelled as NC i.e. Not Connected.
As can be seen in the figure, we have connected the VCC with 3.3V of ESP32, GND with GND of ESP32 and Dout or data or SIG pin is connected to pin D12. NC pin as discussed above is not connected.
Adding LED
As we discussed in our previous tutorial, “LED blink in ESP32“, a resistor is needed to stop the LED from burning. GND and D26 are used, respectively, to connect the cathode and anode of an LED.
MQTT in ESP32 Code
Firstly, we will discuss how to use MQTT protocol in ESP32 using Arduino IDE.
MQTT in ESP32 Arduino IDE
Firstly we should discuss the code of DHT sensor in ESP32 in Arduino IDE.
DHT with ESP32 | Arduino IDE Code
There are number of libraries for DHT sensor that can be used in Arduino IDE. For this tutorial, we are using DHT_U library by Adafruit but this also depends on the Adafruit unified sensor library. First thing is to get these two libraries.
Here is the basic code that prints the temperature and humidity on serial monitor followed by its description.
#include <Adafruit_Sensor.h> #include <DHT_U.h> //defining Pins #define DHTPIN 12 //DHT parameters #define DHTTYPE DHT22 // DHT 22 DHT_Unified dht(DHTPIN, DHTTYPE); uint32_t delayMS; //parameters for using non-blocking delay unsigned long previousMillis = 0; const long interval = 5000; float temp, hum; void setup() { Serial.begin(115200); // Initialize device. dht.begin(); // get temperature sensor details. } void loop() { unsigned long currentMillis = millis(); //read current time if (currentMillis - previousMillis >= interval) { //if current time - last time > 5 sec previousMillis = currentMillis; //read temp and humidity sensors_event_t event; dht.temperature().getEvent(&event); if (isnan(event.temperature)) { Serial.println(F("Error reading temperature!")); } else { Serial.print(F("Temperature: ")); temp = event.temperature; Serial.print(temp); Serial.println(F("°C")); } // Get humidity event and print its value. dht.humidity().getEvent(&event); if (isnan(event.relative_humidity)) { Serial.println(F("Error reading humidity!")); } else { Serial.print(F("Humidity: ")); hum = event.relative_humidity; Serial.print(hum); Serial.println(F("%")); } } }
Like discussed, we have imported two libraries , DHT_U and Adafruit sensors. Then we have define the pin number of DHT sensor which is D12 in our case and then we define sensor type i.e. DHT22, you can use DHT11 as well and then calling the function of DHT sensor library we initialized the DHT sensor by telling its pin number and type. Then we have created some variables for time interval that will help us print data every 5 seconds and some variables to store the data of temperature and humidity.
In the setup() function, we initialized the serial communication so we can read data on serial monitor at 115200 baud rate and then we initialized the dht sensor by calling dht.begin() function.
In the loop function, we first read the current time and read the difference between current time and last time data was sent. If the difference is more than interval i.e. in this case 5000 ms or 5 seconds, we read the data of temperature and humidity and print its values on the serial monitor. You will see something like this in serial monitor.
MQTT ESP32 | Arduino IDE code Explained
Now you know, that how we read the DHT sensor in ESP32 using Arduino IDE. For using the MQTT protocol we will need two more libraries WiFi and pubsubclient. The WiFi library is for connecting the ESP32 with a network. The pubsubclient library is for using the MQTT functionalities in the ESP32.
#include <WiFi.h> #include <PubSubClient.h>
Then we need to define some credentials, so we can connect to network using WiFi and MQTT broker. Make sure the client ID is different if you are using multiple devices. The last variable is topic, on which we will publish the data.
//MQTT Credentials const char* ssid = "YOUR_WIFI_SSID";//setting your ap ssid const char* password = "YOUR_WIFI_PASSWORD";//setting your ap psk const char* mqttServer = "MQTT_BROKER_ADDRESS"; const char* mqttUserName = "MQTT_USERNAME"; const char* mqttPwd = "MQTT_PASSWORD"; const char* clientID = "CLIENT_ID"; // client id must be unique const char* topic = "Tempdata"; //publish topic
Then using the following lines, we setup the WiFi and MQTT client.
//setting up wifi and mqtt client WiFiClient espClient; PubSubClient client(espClient);
Then we have a defined a function setup_Wifi that will help us to connect with the WiFi. The SSID and Password of WIFI has already defined in the above snippets. This function tries to connect to WIFI, unless it is not connected, it remains in the same function. Once you are connected, it prints the IP address.
void setup_wifi() { delay(10); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); }
Then in the Setup function, we first call the setup Wifi function and then set the broker of MQTT using the MQTT server and port number. Then we set the callback function, which will be called automatically whenever we will receive any message on the topic that we have subscribed.
void setup() { Serial.begin(115200); setup_wifi(); client.setServer(mqttServer, 1883); //setting MQTT server client.setCallback(callback); //defining function which will be called when message is received. }
The callback function is described as following, Which at the moment just prints the topic and message received. We will write the controlling in this function. For example, we can write using if-else command that if topic is “LED” and message is “ON”, turn on the LED.
void callback(char*topic, byte* payload, unsigned int length) { Serial.print("Message arrived in topic: "); Serial.println(topic); Serial.print("Message:"); }
Then in the loop function, we will see if we are connected to broker, if not , it will call the reconnect function.
void loop() { if (!client.connected()) { //if client is not connected reconnect(); //try to reconnect } }
Following is the reconnect function, in which there is a blocking loop which tries to connect to the MQTT broker and once it is connected it subscribe to the lights topic, if it fails to do so, it will print the failed command and give rc error number, which will help you to debug the reason for not connecting.
void reconnect() { while (!client.connected()) { if (client.connect(clientID, mqttUserName, mqttPwd)) { Serial.println("MQTT connected"); client.subscribe("lights"); Serial.println("Topic Subscribed"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); delay(5000); // wait 5sec and retry } } }
one more thing if you are connecting to insecure MQTT broker that does not have username and password, you can write it in this way.
if (client.connect(clientID)) {
also, we can publish the data using the following function, by passing the topic name and message.
client.publish(topic, msg);
MQTT ESP32 Code
Now, you have understand the code for MQTT in ESP32 in parts. Its time to combine all the snippets and write a fully functional code. The following code reads the DHT data after every 5 seconds and publish it to MQTT broker on topic TempData and whenever we receive the data on our topic Lights, LED will be turned on or off according to the message received.
#include <Adafruit_Sensor.h> #include <DHT_U.h> #include <WiFi.h> #include <PubSubClient.h> //defining Pins #define DHTPIN 12 #define LED 26 //DHT parameters #define DHTTYPE DHT22 // DHT 11 DHT_Unified dht(DHTPIN, DHTTYPE); uint32_t delayMS; //MQTT Credentials const char* ssid = "YOUR_WIFI_SSID";//setting your ap ssid const char* password = "YOUR_WIFI_PASSWORD";//setting your ap psk const char* mqttServer = "MQTT_BROKER_ADDRESS"; const char* mqttUserName = "MQTT_USERNAME"; const char* mqttPwd = "MQTT_PASSWORD"; const char* clientID = "CLIENT_ID"; // client id must be unique const char* topic = "Tempdata"; //publish topic //parameters for using non-blocking delay unsigned long previousMillis = 0; const long interval = 5000; String msgStr = ""; // MQTT message buffer float temp, hum; //setting up wifi and mqtt client WiFiClient espClient; PubSubClient client(espClient); void setup_wifi() { delay(10); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } void reconnect() { while (!client.connected()) { if (client.connect(clientID, mqttUserName, mqttPwd)) { Serial.println("MQTT connected"); client.subscribe("lights"); Serial.println("Topic Subscribed"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); delay(5000); // wait 5sec and retry } } } //subscribe call back void callback(char*topic, byte* payload, unsigned int length) { Serial.print("Message arrived in topic: "); Serial.println(topic); Serial.print("Message:"); String data = ""; for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); data += (char)payload[i]; } Serial.println(); Serial.print("Message size :"); Serial.println(length); Serial.println(); Serial.println("-----------------------"); Serial.println(data); if(data=="ON"){ Serial.println("LED"); digitalWrite(LED, HIGH); } else{ digitalWrite(LED, LOW); } } void setup() { Serial.begin(115200); // Initialize device. dht.begin(); // get temperature sensor details. sensor_t sensor; dht.temperature().getSensor(&sensor); dht.humidity().getSensor(&sensor); pinMode(LED, OUTPUT); digitalWrite(LED, LOW); setup_wifi(); client.setServer(mqttServer, 14614); //setting MQTT server client.setCallback(callback); //defining function which will be called when message is received. } void loop() { if (!client.connected()) { //if client is not connected reconnect(); //try to reconnect } client.loop(); unsigned long currentMillis = millis(); //read current time if (currentMillis - previousMillis >= interval) { //if current time - last time > 5 sec previousMillis = currentMillis; //read temp and humidity sensors_event_t event; dht.temperature().getEvent(&event); if (isnan(event.temperature)) { Serial.println(F("Error reading temperature!")); } else { Serial.print(F("Temperature: ")); temp = event.temperature; Serial.print(temp); Serial.println(F("°C")); } // Get humidity event and print its value. dht.humidity().getEvent(&event); if (isnan(event.relative_humidity)) { Serial.println(F("Error reading humidity!")); } else { Serial.print(F("Humidity: ")); hum = event.relative_humidity; Serial.print(hum); Serial.println(F("%")); } msgStr = String(temp) +","+String(hum)+","; byte arrSize = msgStr.length() + 1; char msg[arrSize]; Serial.print("PUBLISH DATA:"); Serial.println(msgStr); msgStr.toCharArray(msg, arrSize); client.publish(topic, msg); msgStr = ""; delay(50); } }
Results
You can see the results on android app which we built on MQTT MIT APP inventor.
or on python MQTT dashboard.
or in the MQTT web application.
ESP32 for wearable
I would like to take this opportunity to introduce the tiny ESP32C3 by SEEED studio which is the new addition to their XIAO series. Watch the following story to know more about this powerful yet tiny board. This tutorial is valid for ESP32C3 showed in the following story.
Check it out on Amazon.