Utility Bar

ESP32 MQTT Tutorial – Publish, Subscribe & Control Hardware Over Wi-Fi Using Arduino IDE

ESP32 MQTT Over Cloud

Ethan Zaitchik |

Most modern IoT platforms use a lightweight messaging system to exchange data across a network through a central server, rather than having devices communicate directly with each other. This is commonly implemented using MQTT (Message Queuing Telemetry Transport), a protocol designed specifically for embedded systems and low-bandwidth networks.

What you'll build:
An ESP32 that connects to an MQTT broker over Wi-Fi, publishes messages to a topic, and listens for commands that can control hardware such as an LED. You will also send and receive MQTT messages using a desktop MQTT client.
Table of Contents
    Quick Start Summary 1. Create a free MQTT broker 2. Install the PubSubClient library 3. Upload the ESP32 MQTT example code 4. Publish messages to control the LED Full step-by-step instructions are provided below.

    MQTT Architecture Overview

    Unlike traditional web communication where devices connect directly to each other, MQTT uses a broker-based architecture. All devices send and receive messages through a central server known as the MQTT broker.

    This architecture allows many devices to communicate efficiently without needing direct connections between them.

    Typical Communication Flow:

    ESP32 → MQTT Broker → Other Devices / Applications

    ESP32 MQTT communication architecture diagram

    For example, an ESP32 might publish a temperature reading to the broker. A dashboard application subscribed to that topic would then receive the update and display the data in real time.

    This model allows many devices to exchange information without needing to know about each other directly.

    Why MQTT is widely used in IoT:
    MQTT is designed for low-power devices and unreliable networks. It uses very small messages, maintains persistent connections, and allows systems to efficiently distribute data between large numbers of devices.

    What MQTT Is and How It Works

    MQTT is a messaging protocol built around a publish–subscribe model. Instead of sending data directly to another device, messages are published to a topic on the broker.

    Any device subscribed to that topic automatically receives the message.

    This design allows systems to share data without requiring devices to know where the data will ultimately be used.

    The MQTT ecosystem is built around several core components:

    • Publisher – A device that sends messages to a topic
    • Subscriber – A device that listens for messages on a topic
    • Broker – The central server that receives and distributes messages
    • Topics – Named channels used to organize messages
    • Messages – The actual data being transmitted

    In a simple example, an ESP32 might publish a message containing sensor data.

    The broker receives the message and immediately forwards it to any clients that are subscribed to the same topic.

    Example Message Flow:

    ESP32 publishes message → Broker receives message → Subscribers receive update

    This publish–subscribe model allows large IoT systems to scale efficiently, because devices only communicate with the broker rather than managing direct connections with every other device.

    Because devices only communicate with the broker, a single MQTT server can coordinate communication between hundreds or even thousands of IoT devices.

    Ways the ESP32 Can Use MQTT

    There are several ways an ESP32 can connect to an MQTT broker. The best option depends on the type of project you are building and where the system will run.

    Cloud MQTT Broker

    A cloud MQTT broker runs on a remote server hosted by an online provider.

    This is one of the easiest ways to get started because the server infrastructure is already managed for you.

    Architecture:

    ESP32 → Cloud MQTT Broker → Dashboards / Other Devices

    This approach is commonly used for projects that need remote monitoring, internet access, or devices distributed across multiple networks.

    MQTT Broker on Your Computer

    During development, many engineers run an MQTT broker locally on their own computer using software such as the Mosquitto broker.

    This allows devices on the same network to communicate without relying on an external server.

    Architecture:

    ESP32 → Computer MQTT Broker → Local Applications

    MQTT Broker on a Raspberry Pi

    Another common setup is running an MQTT broker on a Raspberry Pi. This is frequently used in home automation systems where all devices operate inside a local network.

    Architecture:

    ESP32 → Raspberry Pi MQTT Broker → Local IoT Devices

    In this tutorial:
    We will use a free cloud MQTT broker. This avoids installing server software and allows the ESP32 to communicate with MQTT clients from anywhere on the internet.

    Next, we will look at the hardware and software required to connect the ESP32 to an MQTT broker.

    Hardware Required

    This project requires only a few basic components. The ESP32 will connect to an MQTT broker over Wi-Fi and use messages to control a simple LED.

    Get All the Parts You Need

    This tutorial is part of our comprehensive ESP32 learning series. Instead of buying components individually, save time and money with our ESP32 Basic Starter Kit. It includes everything you need for this lesson and 20+ other projects.

    What's Included: ESP32 board, OLED display, sensors (DHT11, PIR, LDR), relay module, buzzers, LEDs, buttons, breadboard, resistors, and all cables, plus access to our complete lesson plans.

    View ESP32 Starter Kit →

      The LED will be used to demonstrate how MQTT messages can control hardware connected to the ESP32.

      The LED is optional for testing MQTT communication. Even without hardware connected, you can still observe messages being published and received through the Serial Monitor.

      Software and Tools Required

      In addition to the ESP32 hardware, we will use several software tools to develop and test the MQTT system.

      • Arduino IDE – Used to write and upload code to the ESP32
      • ESP32 Board Package – Allows the Arduino IDE to compile code for ESP32 boards
      • PubSubClient Library – Provides MQTT functionality
      • MQTT Client Software – Used to send and receive test messages

      MQTT client software allows you to interact with the MQTT broker directly. This makes it easy to test messages being sent from and received by the ESP32.

      Popular MQTT clients include:

      • MQTTX
      • HiveMQ Web Client
      Why an MQTT client is useful:
      It allows you to publish messages manually and monitor topics in real time. This makes debugging MQTT systems much easier during development.

      Creating a MQTT Broker using HiveMQ Cloud

      An MQTT broker is the central server responsible for receiving and distributing messages between devices.

      In this guide we will use HiveMQ Cloud, a free cloud-hosted MQTT broker. This removes the need to install and configure server software while still providing a fully functional MQTT environment.

      To get started, go to console.hivemq.cloud and create a free account.

      Step 1 – Create a Cluster

      After logging in to the HiveMQ Cloud console, you will be prompted to create your first cluster.

      1. Click Cloud ClustersHiveMQ Cloud Clusters
      2. Click Create New ClusterHiveMQ Create New Clusters
      3. Select the Serverless free tierHiveMQ Serverless

      HiveMQ will provision your broker in the cloud. This shouldn't take long.

      Step 2 – Create MQTT Credentials

      Before connecting any devices, you need to create a username and password for authentication.

      1. Open your cluster by clicking Manage ClusterHiveMQ Manage Cluster
      2. Navigate to the Access Management tab
      3. Click Edit next to CredentialsHiveMQ Access Management Edit Credentials
      4. Enter a username and password of your choice. Make sure to remember the credentials.HiveMQ Username & Password
      5. Click Save
      Store your username and password somewhere safe. You will need to enter these into the ESP32 code shortly.

      Step 3 – Copy Your Connection Details

      Once your cluster is running, navigate to the Overview tab of your cluster. You will find the connection details needed to connect the ESP32.

      Take note of the following values:

      • URL – The hostname of your MQTT broker (ends in .s1.eu.hivemq.cloud or similar)
      • Port – Use 8883 for standard connections

      HiveMQ Connection Details

      These values will later be entered into the ESP32 code.

      Installing the MQTT Library

      To allow the ESP32 to communicate using MQTT, we need to install a library that implements the MQTT protocol.

      The most commonly used MQTT library for Arduino and ESP32 projects is PubSubClient.

      This library handles:

      • Connecting to an MQTT broker
      • Publishing messages to topics
      • Subscribing to topics
      • Receiving messages from other clients

      To install the library:

      1. Open the Arduino IDE
      2. Select Sketch → Include Library → Manage Libraries
      3. Search for PubSubClient
      4. Click Install

      Arduino IDE install PubSubClient library

      Library installation:
      For help installing libraries within the Arduino IDE, refer to our tutorial on Installing Libraries and Using the Serial Monitor on ESP32.

      ESP32 MQTT Code Overview

      Before uploading a complete example, it is useful to understand the main components required to connect an ESP32 to an MQTT broker.

      An MQTT-enabled ESP32 program typically includes the following steps:

      • Connecting the ESP32 to a Wi-Fi network
      • Connecting to an MQTT broker
      • Publishing messages to MQTT topics
      • Subscribing to topics to receive messages
      • Handling incoming messages using a callback function

      The ESP32 maintains a persistent connection with the MQTT broker. While connected, it can continuously send and receive messages without needing to reconnect for each transmission.

      Key concept:
      Unlike HTTP communication, which sends individual requests, MQTT keeps a continuous connection open between the device and the broker. This allows messages to be delivered instantly and efficiently.

      To demonstrate how MQTT communication works, the following example program performs three main tasks:

      • Connects the ESP32 to Wi-Fi
      • Connects to the MQTT broker
      • Subscribes to a topic that controls an LED

      The ESP32 will also publish a message when it first connects, confirming that communication with the broker is working.

      Full ESP32 MQTT Example Code

      The complete ESP32 MQTT example code is provided below. This program connects to Wi-Fi, connects to the MQTT broker, subscribes to commands, and publishes status messages using the PubSubClient library.

      Replace the Wi-Fi credentials and MQTT broker details with the values provided by your broker.

      #include <WiFi.h>
      #include <PubSubClient.h>
      #include <WiFiClientSecure.h>
      
      
      /* ===== Wi-Fi Credentials ===== */
      const char* ssid = "YOUR_SSID"; // WiFi name
      const char* password = "YOUR_PASSWORD"; // WiFi password
      
      /* ===== MQTT Broker Settings ===== */
      const char* mqtt_server = "YOUR_BROKER_ADDRESS"; // The URL in HiveMQ
      const int mqtt_port = 8883; // The Port in HiveMQ
      const char* mqtt_user = "YOUR_USERNAME"; // The username set in step 2 of creating a MQTT broker
      const char* mqtt_password = "YOUR_PASSWORD"; // The password set in step 2 of creating a MQTT broker
      
      /* ===== LED Pin ===== */
      const int ledPin = 2;
      
      /* ===== Create WiFi and MQTT Clients ===== */
      WiFiClientSecure espClient;
      PubSubClient client(espClient);
      
      /* ===== Callback Function ===== */
      void callback(char* topic, byte* payload, unsigned int length) {
      
        String message = "";
      
        for (int i = 0; i < length; i++) {
          message += (char)payload[i];
        }
      
        Serial.print("Message received: ");
        Serial.println(message);
      
        if (message == "ON") {
          digitalWrite(ledPin, HIGH);
        }
      
        if (message == "OFF") {
          digitalWrite(ledPin, LOW);
        }
      
      }
      
      /* ===== Connect to MQTT Broker ===== */
      void reconnect() {
      
        while (!client.connected()) {
      
          Serial.print("Connecting to MQTT...");
      
          if (client.connect("ESP32Client", mqtt_user, mqtt_password)) {
      
            Serial.println("connected");
      
            client.subscribe("esp32/led");
            client.publish("esp32/status", "ESP32 connected");
      
          } else {
      
            Serial.print("failed, rc=");
            Serial.print(client.state());
            Serial.println(" retrying in 5 seconds");
      
            delay(5000);
      
          }
      
        }
      
      }
      
      void setup() {
      
        Serial.begin(115200);
      
        pinMode(ledPin, OUTPUT);
      
        espClient.setInsecure();
      
        WiFi.begin(ssid, password);
      
        Serial.print("Connecting to WiFi");
      
        while (WiFi.status() != WL_CONNECTED) {
          delay(500);
          Serial.print(".");
        }
      
        Serial.println("");
        Serial.println("WiFi connected");
      
        client.setServer(mqtt_server, mqtt_port);
        client.setCallback(callback);
      
      }
      
      void loop() {
      
        if (!client.connected()) {
          reconnect();
        }
      
        client.loop();
      
      }
      Important:
      Before uploading the code, replace the Wi-Fi credentials and MQTT broker details with your own connection settings.

      Understanding the Code

      This program combines Wi-Fi networking, secure TLS communication, and MQTT to allow the ESP32 to send and receive messages.

      The first step is including the required libraries.

      #include <WiFi.h>
      #include <PubSubClient.h>
      #include <WiFiClientSecure.h>

      The WiFi library handles network connectivity, PubSubClient implements the MQTT protocol, and WiFiClientSecure enables encrypted TLS connections required by HiveMQ Cloud.

      Next, the Wi-Fi credentials and MQTT broker connection details are defined.

      const char* ssid = "YOUR_SSID";
      const char* password = "YOUR_PASSWORD";

      The ESP32 must first connect to the Wi-Fi network before it can reach the MQTT broker.

      Next, the MQTT broker settings are defined.

      const char* mqtt_server = "YOUR_BROKER_ADDRESS";
      const int mqtt_port = 8883;

      Port 8883 is the standard port for encrypted MQTT connections. This is required by HiveMQ Cloud, which does not accept unencrypted connections on port 1883.

      The program then creates two communication objects.

      WiFiClientSecure espClient;
      PubSubClient client(espClient);

      WiFiClientSecure handles the encrypted network connection, while PubSubClient builds MQTT communication on top of it.

      The callback function is triggered whenever a subscribed MQTT message is received.

      void callback(char* topic, byte* payload, unsigned int length)

      Inside this function, the program reads the incoming message and converts it into a string. If the message contains ON, the LED is turned on. If it contains OFF, the LED is turned off.

      MQTT messages can contain any type of data including commands, sensor readings, or JSON formatted information.

      Before connecting to Wi-Fi, the secure client is configured to skip certificate verification.

      espClient.setInsecure();

      This allows the ESP32 to establish an encrypted TLS connection without needing to store and verify the broker's SSL certificate. It is the standard approach for beginner ESP32 projects connecting to cloud MQTT brokers.

      Next, the program includes a reconnect function. This ensures the ESP32 automatically reconnects if the MQTT connection is lost.

      void reconnect()

      Maintaining a persistent connection is important because MQTT communication depends on the device remaining connected to the broker.

      Finally, the loop() function continuously checks the MQTT connection and processes incoming messages.

      client.loop();

      This function must run continuously so the ESP32 can receive new MQTT messages as they arrive.

      Next, we will test the MQTT system by publishing messages from an MQTT client and observing how the ESP32 responds.

      Testing MQTT Messages

      To test the MQTT system, we will use MQTTX, a free desktop MQTT client that allows you to publish and subscribe to messages manually.

      Download MQTTX from mqttx.app and install it on your computer.

      Step 1 – Connect MQTTX to Your HiveMQ Broker

      1. Open MQTTX and click New ConnectionMQTTX New Connection
      2. Enter a name for the connection, for example HiveMQ Test
      3. Set the Host to mqtts:// and link to your HiveMQ Cluster URL
      4. Set the Port to 8883
      5. Enter your Username and Password
      6. Enable SSL/TLS
      7. Click Connect

      MQTTX Connection Details

      Once connected, MQTTX will show a green indicator confirming the connection to your broker.

      Step 2 – Subscribe to the ESP32 Status Topic

      Before resetting the ESP32, subscribe to the status topic so you can observe the connection message.

      1. In MQTTX, click Add Subscription
      2. Enter in the topic section esp32/status
      3. Click Confirm

      MQTTX enter topic

      Step 3 – Upload the Code and Observe the Connection Message

      1. Upload the ESP32 code with your Wi-Fi and HiveMQ credentials filled in
      2. Open the Serial Monitor and set the baud rate to 115200
      3. Wait for the ESP32 to connect to Wi-Fi and then to the MQTT broker

      The Serial Monitor should display the following:

      Arduino IDE confirm connection

      In MQTTX, you should see a message appear confirming if the ESP32 is connected or not. You can also confirm this within the Log

      MQTTX ESP32 connection confirmation

      What just happened:
      The ESP32 connected to your HiveMQ broker and published a status message. MQTTX received that message because it was subscribed to the same topic.

      Step 4 – Control the LED

      Now test sending commands from MQTTX to the ESP32.

      1. In MQTTX, set the publish topic to esp32/led
      2. Type ON in the message field and click Send
      3. The LED connected to the ESP32 should turn on

      MQTTX enter topic & send command

      Then send:

      OFF

      The LED should turn off.

      Test flow:
      MQTTX → HiveMQ Cloud Broker → ESP32 LED Control

      This confirms that the full MQTT communication pipeline is working correctly. Messages published from your computer travel through the HiveMQ cloud broker and are received by the ESP32 in real time.

      ESP32 MQTT Publish Example

      One of the primary uses of MQTT is sending data from devices to a central system. This process is called publishing.

      When a device publishes a message, it sends data to a specific topic on the MQTT broker. Any devices or applications subscribed to that topic will receive the message.

      In the example code, the ESP32 publishes a message when it successfully connects to the broker.

      client.publish("esp32/status", "ESP32 connected");
      

      This line sends the text message "ESP32 connected" to the topic:

      esp32/status
      

      If an MQTT client is subscribed to this topic, the message will appear immediately.

      Example use cases for MQTT publishing:
      • Sending temperature or humidity sensor data
      • Reporting device status information
      • Sending system alerts or warnings
      • Logging IoT device activity

      For example, a temperature sensor connected to the ESP32 might publish readings like this:

      client.publish("home/livingroom/temperature", "24.6");
      

      A monitoring dashboard subscribed to this topic would immediately receive the new temperature reading.

      ESP32 MQTT Subscribe Example

      In addition to publishing data, MQTT devices can also subscribe to topics. Subscribing allows the ESP32 to receive commands or data from other devices.

      In the example program, the ESP32 subscribes to the following topic:

      client.subscribe("esp32/led");
      

      Whenever a message is published to this topic, the ESP32 receives it through the callback function.

      The callback function reads the message and checks its content.

      if (message == "ON") {
        digitalWrite(ledPin, HIGH);
      }
      
      if (message == "OFF") {
        digitalWrite(ledPin, LOW);
      }
      

      If the message contains ON, the LED turns on. If it contains OFF, the LED turns off.

      This simple example demonstrates how MQTT messages can control hardware connected to the ESP32.

      MQTT commands can control many types of hardware including relays, motors, lights, displays, or entire automation systems.

      Understanding MQTT Topics

      MQTT topics are structured paths used to organize messages between devices.

      Topics can contain multiple levels separated by forward slashes.

      For example:

      home/livingroom/temperature
      home/livingroom/light
      home/kitchen/temperature
      

      This hierarchical structure allows large IoT systems to organize devices and sensors clearly.

      Using structured topics makes it easier to manage and expand IoT systems as more devices are added.

      Common MQTT Problems and Fixes

      When working with MQTT and ESP32 devices, connection issues are usually caused by configuration errors or network problems. Below are some common issues and how to fix them.

      ESP32 Cannot Connect to the MQTT Broker

      If the ESP32 fails to connect to the MQTT broker, the issue is often related to incorrect connection settings.

      Check the following:

      • Broker server address is correct
      • Correct MQTT port is being used
      • Username and password are correct
      • The broker instance is running
      • SSL/TLS is enabled

      If the connection repeatedly fails, check the error code printed in the Serial Monitor.

      MQTT connection errors are usually displayed in the Serial Monitor as return codes. These codes help identify authentication or connection problems.

      ESP32 Cannot Connect to Wi-Fi

      If the ESP32 does not connect to Wi-Fi, verify the following:

      • Wi-Fi network name is spelled correctly
      • Wi-Fi password is correct
      • The ESP32 is within range of the router

      The Serial Monitor should eventually display:

      WiFi connected
      

      If the message never appears, the ESP32 may be stuck trying to connect to the network.

      Messages Are Not Being Received

      If MQTT messages are being published but the ESP32 is not responding, the most common cause is a topic mismatch.

      For example, if the ESP32 subscribes to:

      esp32/led
      

      Then messages must be published to exactly the same topic.

      The following would not match:

      esp32/LED
      esp32/light
      esp32/led/control
      

      MQTT topics are case-sensitive and must match exactly.

      ESP32 Keeps Reconnecting to MQTT

      If the ESP32 repeatedly reconnects to the broker, it usually means the connection is being dropped.

      This can be caused by:

      • Incorrect authentication credentials
      • Network instability
      • Firewall blocking the MQTT port

      The reconnect function in the example code automatically attempts to restore the connection if it is lost.

      Tip:
      Keeping the reconnect logic in your program ensures your IoT devices automatically recover from temporary network interruptions.

      Expanding Your IoT System

      Once you understand how MQTT communication works, it becomes easy to build larger IoT systems using multiple devices.

      For example, several ESP32 boards can publish sensor data to the same MQTT broker while other devices subscribe to those messages.

      This architecture allows devices to communicate indirectly through the broker.

      A typical system might look like this:

      Multiple ESP32 devices → MQTT Broker → Dashboard or automation system

      Possible projects you can build include:

      • Wireless temperature monitoring systems
      • Home automation lighting control
      • Environmental monitoring networks
      • IoT dashboards displaying real-time data
      • Smart relay controllers

      Because MQTT is lightweight and efficient, it can support large numbers of devices communicating simultaneously.

      Many commercial IoT platforms and smart home systems use MQTT as their underlying communication protocol.

      You can also expand this system by adding:

      • Multiple ESP32 sensor nodes
      • Web dashboards for monitoring
      • Automation rules triggered by MQTT messages
      • Data logging systems

      Conclusion

      In this tutorial you learned how to connect an ESP32 to an MQTT broker and exchange messages using the publish and subscribe model.

      You also explored how MQTT systems are structured and how topics allow devices to communicate through a central broker.

      The example project demonstrated how MQTT messages can control hardware connected to an ESP32, such as turning an LED on and off.

      You also learned how to test MQTT communication using a client application and how to troubleshoot common connection problems.

      ESP32 IoT Systems Pathway

      Leave a comment