LOADING

Type to search

Computers Electronics

ESP32 Subscribing and Publishing Data to MQTT broker hosted in Raspberry Pi, Displaying on Node-Red Dashboard

Setting up the Mosquito MQTT Broker in Raspberry Pi

If you want to learn about from to setup the Raspberry Pi, check out this video and come back to continue from this step. Installing the Raspberry Pi.

Please follow the below commands

Step 1: The command mentioned below is used in Linux-based operating systems like Ubuntu to update the package list and upgrade installed packages to their latest versions.

sudo apt update && sudo apt upgrade

Explanation about the command for beginners

sudo : This command allows you to run other commands with superuser (administrative) privileges.

apt : This is the Advanced Package Tool, a package management system used in Debian-based Linux distributions.

update : This sub-command updates the local package database with information about available packages and their versions from the repositories configured on your system.

&& : This means that the second command will only run if the first command (sudo apt update) is successful.

upgrade : This sub-command is used to upgrade installed packages to their latest available versions.

The above command is the mode common command in linux based systems.

Step 2: The Command for installing the Mosquitto MQTT Broker

sudo apt install -y mosquitto mosquitto-clients

Explanation about the above command for the beginners

install : This is the sub-command used to install packages

-y : This is used to automatically confirm and proceed with the installation without requiring manual confirmation. It’s a convenient way to install packages non-interactively.

mosquitto : This is the package name for the Mosquitto MQTT broker, which will be installed.

mosquitto-clients : This is the package name for the Mosquitto MQTT client tools, including mosquitto_pub and mosquitto_sub, which will be installed.

Step 3: The command for making the Mosquitto MQTT start when you boot/Start the Raspberry Pi

sudo systemctl enable mosquitto.service

Explanation about the above command for the beginners

systemctl : This is the systemd command-line tool used for managing services and units in Linux.

enable : This sub-command is used to enable a service or unit, allowing it to start automatically during system boot.

mosquitto.service : This is the name of the systemd service unit for the Mosquitto MQTT broker.

// Tasty Tech Harbour
// MQTT is a lightweight messaging protocol often used for IoT applications. ( MQTT - Message Queuing Telemetry Transport)
// This code was tested in ESP32-WROOM-32. 

// Below are the libraries which are used for this project.
#include <WiFi.h> // WiFi Library to connect the ESP32 to Wifi
#include <PubSubClient.h> // MQTT Subscribe and Publish Library. This library provides a client (In our case its ESP32) for doing simple publish/subscribe messaging with a server that supports MQTT
#include <DHT.h> // DHT Temperature and humidity sensor Library for sensors like DHT11, DHT22 etc.

// WiFi and MQTT Broker details below.
const char* ssid = "EnterYourWiFiNamehere"; // Enter the WiFi name to which you want to connect the ESP32, Enter in between 
const char* password = "EnterYourPasswordHere"; // Password of the WiFi 
const char* mqtt_server = "EnterTheIPAddressoftheMQTTServer"; //Enter the IP address of the MQTT Broker, this is the IP of the device in which the MQTT broker is running, CHeck out the complete video where I show you how to know these information
const int mqtt_port = 1883; // MQTT TCP/IP port 1883 is reserved for unencrypted. TCP/IP port 8883 is reserved for using MQTT over SSL.
const char* mqtt_username = "EntertheConfiguredUsernameofMQTTBroker"; //This is the username which is configured in the MQTT broker
const char* mqtt_password = "EntertheConfiguredPasswordofMQTTBroker"; //This is the password which is configured in the MQTT broker, please watch the complete video to understand 
const char* client_id = "ESP32Client"; 

// Below is the topic to which sensor data is published from the ESP32 which is received from the Temperature and Humidity Sensor, please mention the topic to which the data has to be published.
const char* tempHum_Topic = "homeautomation/outside-temperature";
// Below is the topic to which the ESP32 is subscribed to, control the relay. Please mention the topic from which the data has to be fetched, meaning to which you want to subscribe.
const char* relay_Switch = "homeautomation/shutter";

// Defining the pins for the sensors
const int DHTPIN = 32;  // Define the pin where the DHT sensor is connected
const int RELAY_PIN = 2; // Define the pin where the relay is connected

// We have to create an instance of 'WiFiClient' class.
WiFiClient espClient; // Here we created an instance with name 'espClient'. This is used to establish and manage connection to the WiFi Networks in library compatible device like ESP32, ESP8266 etc.
// Now its time to create the instance for MQTT from '<PubSubClient.h>' library and pass the 'espClient' from above instance as parameter.
// The 'PubSubClient' library is commonly used to implement MQTT (Message Queuing Telemetry Transport) communication in Arduino-based projects.
PubSubClient client(espClient); // This line creates an instance of the PubSubClient class named 'client' (Instance of the class is also know as an object), and it takes the 'espClient' instance as a parameter.
// By initializing PubSubClient with espClient, you're setting up MQTT communication using the Wi-Fi client for network connectivity.

// Initialising the DHT temperature and humidty sensor
DHT dht(DHTPIN, DHT11); // Initialize DHT sensor, 'DHT' is a class representing the DHT series of temperature and humnidity sensor
                        // 'dht' is an instance of the DHT class that you are creating.
                        // 1st parameter which has to be passed to 'dht' is (Pin and Type of Sensor). 'DHTPIN' is a variable that should specify the pin to which the DHT sensor is connected, which is defined above. 
                        // and 2nd parameter is the type of DHT sensor which is 'DHT11'.
                        // DHT11 is an argument that specifies the type of DHT sensor you're using. In this case, it's the 'DHT11' sensor. There are other variants like DHT22 and DHT21, which have different capabilities and accuracy levels.
                        // This line of code initializes the 'dht' object with the necessary information to communicate with the DHT11 sensor

// In the below code you can observe that, After you've set up these instances, you would typically proceed to configure your Wi-Fi connection and MQTT broker details and then use the 'client' object to publish and subscribe to MQTT topics.
void setup() {
  Serial.begin(115200);
  setupWiFi(); // Here we are calling the function which is defined below. Not all the function take parameters as input, so here we are just calling the function. This function set up and configure the Wi-Fi connection.
  client.setServer(mqtt_server, mqtt_port); // Configuring the server details, "mqtt_server" and "mqtt_port" are the variable which are defined above in the "WiFi and MQTT broker details". We are passing 2 parameters to the method.
  client.setCallback(callback); // This is a method of the PubSubClient class. It is used to specify a callback function that will be invoked whenever a message is received from the MQTT broker.
                                // 'callback' mentioned above is a function which we want to use as callback. This function is defined below.
                                // When we set the callback function using the above line, we are essentially telling the function 'PubSubClient' library that, this should be executed when a message is received from the MQTT broker.
  pinMode(RELAY_PIN, OUTPUT); // PinMode is the function used in arduino to define what the pin on the arduino is used as.
  digitalWrite(RELAY_PIN, LOW); // Initialize the relay as OFF. 

  dht.begin();  // The '.begin()' method is called on the 'dht' object to initialize the sensor. This method sets up the necessary communication with the DHT sensor and prepares it for data readings.
}

// Now we will create a function named setupWiFi() to set up and configure the Wi-Fi connection in this code. This function doesn't return any value hence its setup as 'void' otherwise we usually use the type of the returned data
void setupWiFi() {
  WiFi.begin(ssid, password); // the WiFi.begin(), 'WiFi' is the object and .begin is the method which is used to initiate a connection to the specified Wi-Fi network using the provided 'SSID' and 'password'.
  // Now we create a loop to wait for the WiFi Connection to be established. During this time, it prints 'Connecting to WiFi......" on the serial monitor to indicate the progress
  while (WiFi.status() != WL_CONNECTED) { // here we are checking if the WiFi.status is "WL_Connected" which is once of the Status from the library.
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("Connected to WiFi"); // Once connected it exits the While loop and prints the WiFi Connection status as Connected.
}

// The below function is very commonly used in the MQTT communication
// The purpose of this callback function is to handle incoming MQTT messages. When a message is received from the MQTT broker on a subscribed topic, the PubSubClient library (or similar MQTT libraries) 
// will call this function, passing in the topic, payload, and length as arguments. 
// You can now define the behavior you want to perform when a specific message is received on a particular topic.
void callback(char* topic, byte* payload, unsigned int length) {
  Serial.println("Message arrived in topic: " + String(topic));
  // Below code is to checck the topic and also the value in the payload and control the relay.
  if (String(topic) == relay_Switch) {
    if (payload[0] == '1') {
      digitalWrite(RELAY_PIN, HIGH); // Turn on the relay
      Serial.println("Relay turned ON");
    } else {
      digitalWrite(RELAY_PIN, LOW); // Turn off the relay
      Serial.println("Relay turned OFF");
    }
  }
}

// This  reconnect() function is typically used in MQTT (Message Queuing Telemetry Transport) client code to handle reconnecting to the MQTT broker when the connection is lost or when the client initially connects to the broker.
void reconnect() {
  while (!client.connected()) {
    Serial.println("Attempting MQTT connection...");
    if (client.connect(client_id, mqtt_username, mqtt_password)) { // Mentioning the Client ID as mentioned in the begining, also the username and password which was used to configure the MQTT broker.
      Serial.println("Connected to MQTT Broker");
      client.subscribe(relay_Switch); // Here we subcribe to the relay topic
    } else {
      Serial.print("MQTT connection failed, rc=");
      Serial.print(client.state()); // client.state() method is used to check the current state of the MQTT client's connection to the broker. This method returns an integer that represents the client's state,
                                    // Please check out by blog to know about the states www.tastytechharbour.com
      Serial.println(" Retrying in 5 seconds...");
      delay(5000);
    }
  }
}

void loop() {
  if (!client.connected()) {
    reconnect(); // This is the function which is defined above, is called here.
  }
  client.loop(); // This has to be called in the void loop becasue this mantain the MQTT connection, it handles the incoming messages, process the incoming messages and also the timings. This is one of the important in MQTT.

  // Read sensor data
  float humidity = dht.readHumidity();
  float temperature = dht.readTemperature();

  // Check if any reads failed or wrong read values
  // isNaN() function determines whether a value is NaN, first converting the value to a number if necesary. This function is also used in different language like javascript.
  // In this code we are checking if either the humidity or temperature is NaN.
  if (isnan(humidity) || isnan(temperature)) {
    Serial.println("Failed to read from DHT sensor!");
    delay(2000);
    return;
  }

  // Publish sensor data to MQTT
  String sensorData = " Room Temperature: " + String(temperature) + "°C, Room Humidity: " + String(humidity) + "%"; // Here we are using 'String(temperature)' because we want to use the numerical as string to print in text,
                                                                                                                    // hence we use the string() function to convert.
  client.publish(tempHum_Topic, sensorData.c_str()); // Here we are publishing data using the pubSubClient library. To Publish to MQTT it considers or have to  pass two parameters. 1. Sensor topic 2.the content of the message.
  // The above sensorData variable is convertede to C-Style string which is the format expected by the Publish method. '.C_Str()' is this returns cons char* that points to a null terminated strings. Means this returns  arrays of characters terminated by a null character ('\0').
}

Download the Arduino File

Tags:

You Might also Like

Leave a Comment

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