Blog Datasheets Home About me Clients My work Services Contact

G2Labs Grzegorz Grzęda

MQTT Communication with ESP32 and ESP-IDF

May 23, 2024

MQTT Communication with ESP32 and ESP-IDF

In this blog post, we will explore how to establish MQTT communication between an ESP32 microcontroller and a MQTT broker using the ESP-IDF framework. MQTT (Message Queuing Telemetry Transport) is a lightweight messaging protocol commonly used in IoT applications for efficient and reliable data exchange.

Prerequisites

To follow along with this tutorial, you will need the following:

Setting up the ESP-IDF Project

  1. Start by creating a new ESP-IDF project and navigating into its directory:
1
2
$ idf.py create-project mqtt-esp32
$ cd mqtt-esp32
  1. Open the CMakeLists.txt file and add the following lines to include the MQTT component:
1
2
3
4
idf_component_register(SRCS "main.c"
                    INCLUDE_DIRS "."
                    REQUIRES mqtt
                    )
  1. Create a new file named main.c and open it for editing.

Establishing MQTT Connection

Let’s begin by establishing a connection to the MQTT broker.

  1. Include the necessary ESP-IDF and MQTT header files at the top of the main.c file:
1
2
3
4
5
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "mqtt_client.h"
  1. Define variables required for MQTT connection parameters:
1
2
3
4
#define MQTT_BROKER_URI "mqtt://x.x.x.x"  // Replace with your MQTT broker IP address
#define MQTT_PORT 1883
#define MQTT_USERNAME "your_username"     // Replace with MQTT username
#define MQTT_PASSWORD "your_password"     // Replace with MQTT password
  1. Implement a callback function to handle MQTT events:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event)
{
    esp_mqtt_client_handle_t client = event->client;
    int msg_id;
    
    switch (event->event_id)
    {
        case MQTT_EVENT_CONNECTED:
            printf("MQTT_EVENT_CONNECTED\n");
            // Subscribe to MQTT topics or perform other actions
            break;
        
        case MQTT_EVENT_DISCONNECTED:
            printf("MQTT_EVENT_DISCONNECTED\n");
            // Handle reconnection or other actions
            break;
        
        // Handle other MQTT events here
        
        default:
            break;
    }
    return ESP_OK;
}
  1. Implement a function to initialize and connect to the MQTT broker:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
static esp_err_t mqtt_app_start(void)
{
    esp_mqtt_client_config_t mqtt_cfg = {
        .uri = MQTT_BROKER_URI,
        .port = MQTT_PORT,
        .username = MQTT_USERNAME,
        .password = MQTT_PASSWORD,
        .event_handle = mqtt_event_handler_cb
    };
    
    esp_mqtt_client_handle_t mqtt_client = esp_mqtt_client_init(&mqtt_cfg);
    esp_err_t err = esp_mqtt_client_start(mqtt_client);
    
    return err;
}
  1. Implement the main function to start the MQTT connection:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
void app_main(void)
{
    // Initialize ESP-IDF components
    esp_err_t err = nvs_flash_init();
    
    // Connect to the MQTT broker
    err = mqtt_app_start();
    
    if (err == ESP_OK)
    {
        printf("MQTT initialized successfully\n");
    }
    else
    {
        printf("MQTT initialization failed\n");
    }
}
  1. Save the changes and build the project:
1
$ idf.py build

Subscribing and Publishing MQTT Messages

Now that we have established a connection, let’s subscribe to a topic and publish some messages.

  1. Update the mqtt_event_handler_cb function to handle message reception:
1
2
3
4
5
case MQTT_EVENT_DATA:
    printf("MQTT_EVENT_DATA\n");
    printf("Received data: %.*s\n", event->data_len, event->data);
    // Handle received data here
    break;
  1. Implement a function to publish MQTT messages:
1
2
3
4
5
static void mqtt_publish_message(esp_mqtt_client_handle_t client, const char* topic, const char* data)
{
    int msg_id = esp_mqtt_client_publish(client, topic, data, 0, 1, 0);
    printf("Published message with ID: %d\n", msg_id);
}
  1. Modify the MQTT_EVENT_CONNECTED case in mqtt_event_handler_cb to subscribe to a topic:
1
2
msg_id = esp_mqtt_client_subscribe(client, "my_topic", 0);
printf("Subscribed to topic 'my_topic' with message ID: %d\n", msg_id);
  1. Update the mqtt_publish_message function call in app_main to publish a sample message:
1
mqtt_publish_message(mqtt_client, "my_topic", "Hello, MQTT!");
  1. Save the changes and build the project:
1
$ idf.py build

Running the Application

  1. Flash the ESP32 with the built firmware:
1
$ idf.py -p /dev/ttyUSB0 flash monitor
  1. Check the debug output to ensure the MQTT initialization was successful and the message communication is working as expected.

Congratulations! You have successfully established MQTT communication between an ESP32 microcontroller and an MQTT broker using ESP-IDF. You can now extend this example to suit your specific application needs and explore different MQTT features and functionalities.

Conclusion

MQTT provides a lightweight and efficient way to exchange data between IoT devices and applications. The ESP32, combined with the ESP-IDF framework, offers a powerful platform for implementing MQTT-based solutions. In this blog post, we covered the basics of setting up and communicating with an MQTT broker using an ESP32 microcontroller. I hope this tutorial helps you get started with MQTT communication on the ESP32 platform. Happy coding!


➡️ Linux 'man' command


⬅️ Linux 'mv' command


Go back to Posts.