Welcome to ESP32 Core Board repository
10. MQTT
MQTT Communication Experiment
MQTT Communication Experiment1. MQTT Overview2. Core Concepts2.1 Publish/Subscribe Model2.2 Configuration Parameters2.3 Core API2.4 Topics and Messages3. Hardware Dependencies4. Project Architecture and Flow5. Source Code Explained5.1 Creating the MQTT Client5.2 Message Callback5.3 Main Loop6. Operating Procedures6.1 Flashing and Running6.2 Serial Output Example6.3 Verification Methods7. Common Problems
1. MQTT Overview
MQTT (Message Queuing Telemetry Transport) is the most mainstream lightweight publish/subscribe messaging protocol in the IoT field. It is based on TCP and uses the publish/subscribe (Pub/Sub) mode instead of the traditional client-server direct connection mode, achieving temporal and spatial decoupling between producers and consumers.
In this experiment the ESP32-S3 connects to the public Broker broker.emqx.io, publishes messages to the test/esp32/send topic, and subscribes to the test/esp32/recv topic.
Typical application scenarios:
| Application Type | Example |
|---|---|
| Sensor reporting | Temperature/humidity published to the cloud periodically |
| Remote control | Phone App publishes control commands, ESP32 subscribes and receives |
| Multi-device linkage | Door magnet sensor triggers -> alarm responds |
| Smart home | Manage devices through platforms such as Home Assistant / EMQX |
This experiment depends on the
umqtt.simplelibrary (built into MicroPython or uploaded separately). Using a public Broker requires no self-built server.
2. Core Concepts
2.1 Publish/Subscribe Model
x┌──────────┐ publish("test/topic", msg) ┌──────────┐│ ESP32-S3 │ ───────────────────────────→ │ Broker ││ │ ←─────────────────────────── │ (EMQX) ││ │ subscribe("test/topic") └────┬─────┘└──────────┘ │pushed to all subscribers on publish┌────┴───────┐│ Phone APP │└────────────┘
- Broker: the message relay station, responsible for receiving publishes and pushing to subscribers
- Topic: the message topic, e.g.
home/livingroom/temperature - Publish: publish a message to a specified topic
- Subscribe: subscribe to a topic; the Broker pushes messages on that topic to you
2.2 Configuration Parameters
| Parameter | Description | Value Used in This Experiment |
|---|---|---|
| BROKER | MQTT broker address | broker.emqx.io (public) |
| TOPIC_PUB | Publish topic | test/esp32/send |
| TOPIC_SUB | Subscribe topic | test/esp32/recv |
| CLIENT_ID | Client identifier (must be unique) | esp32s3_mqtt |
2.3 Core API
xxxxxxxxxxfrom umqtt.simple import MQTTClient# createclient = MQTTClient("client_id", "broker.emqx.io", port=1883)client.set_callback(on_message) # set callbackclient.connect() # connect Brokerclient.subscribe("topic/sub") # subscribeclient.publish("topic/pub", "hello") # publishclient.check_msg() # check for subscribed messages2.4 Topics and Messages
This experiment defines two topics; the ESP32 uses them to interact with external clients (such as MQTTX):
| Topic | Direction | QoS | Message Content | Period |
|---|---|---|---|---|
test/esp32/send | ESP32 -> Broker | 0 | "Hello ESP32 MQTT" | Every 3s |
test/esp32/recv | Broker -> ESP32 | 0 | Any text (sent by MQTTX) | Determined by the other side |
QoS 0 (At most once): the message is delivered at most once and delivery is not guaranteed. Suitable for lightweight periodic sensor reporting.
Message flow:
xxxxxxxxxxESP32-S3 --publish("test/esp32/send", "Hello ESP32 MQTT")--> Broker --forward--> MQTTX (subscriber)ESP32-S3 <--subscribe("test/esp32/recv")---------------- Broker <--publish-- MQTTX (publisher)
The ESP32 publishes and subscribes to separate topics to avoid receiving its own messages. If you want a self-send/self-receive loopback test, set
TOPIC_PUBandTOPIC_SUBto the same topic.
3. Hardware Dependencies
The ESP32-S3 has built-in WiFi and needs access to the public Broker (broker.emqx.io). No PC or self-built server is required.
4. Project Architecture and Flow
xxxxxxxxxxScript execution (single-file .py)||- wifi_init(): connect to WiFi (STA mode)|- create MQTTClient -> connect() -> subscribe()|`- while True:|- publish(TOPIC_PUB, "Hello ESP32 MQTT") // publish|- check_msg() // check subscription`- sleep(3s)
5. Source Code Explained
Full source code: Source Code -> MicroPython -> 4.Network Protocols -> MQTT -> MQTT.py
5.1 Creating the MQTT Client
Use the umqtt.simple library to connect to the public Broker broker.emqx.io:1883, set the callback, and subscribe to the target topic.
xxxxxxxxxxfrom umqtt.simple import MQTTClientBROKER = "broker.emqx.io" # public brokerTOPIC_PUB = "test/esp32/send" # publish topicTOPIC_SUB = "test/esp32/recv" # subscribe topicCLIENT_ID = "esp32s3_mqtt" # unique client IDclient = MQTTClient(CLIENT_ID, BROKER, port=1883)client.set_callback(on_message) # callback on messageclient.connect()client.subscribe(TOPIC_SUB)5.2 Message Callback
Automatically called when the Broker pushes a subscribed message; the parameters are topic and msg (both bytes).
xxxxxxxxxxdef on_message(topic, msg): """received subscribed message""" print(f"[Received] {topic.decode()} -> {msg.decode()}")5.3 Main Loop
Publishes one message every 3s -> check_msg() checks whether any subscribed message has arrived.
xxxxxxxxxxwhile True: msg = "Hello ESP32 MQTT" client.publish(TOPIC_PUB, msg) # publish print(f"[Sent] {msg}") client.check_msg() # check for messages time.sleep(3)6. Operating Procedures
6.1 Flashing and Running
Thonny IDE steps: See MicroPython -> 1. Before Development -> 3.Thonny IDE.
Modify
WIFI_SSID/WIFI_PASS
Run
MQTT.py(Optional) Install an MQTT debugging tool (such as MQTTX) on the PC
- Create a new connection with
broker.emqx.io:1883(the public Broker requires no username/password), - Subscribe to
test/esp32/sendto see the messages published by the ESP32, - Publish a message to
test/esp32/recvand the ESP32 will receive it.


- Create a new connection with
6.2 Serial Output Example
xxxxxxxxxx========== MQTT CLIENT ==========[WiFi] Connecting to 'Yahboom2' ...[WiFi] Connected! IP: 192.168.11.229[MQTT] Connected to broker.emqx.io[MQTT] Subscribed: test/esp32/recv[Sent] Hello ESP32 MQTT[Sent] Hello ESP32 MQTT[Recv] test/esp32/recv -> "msg": "hello"[Recv] test/esp32/recv -> "msg": "hello"[Recv] test/esp32/recv -> "msg": "hello"[Sent] Hello ESP32 MQTT[Sent] Hello ESP32 MQTT

6.3 Verification Methods
| Operation | Expected Result |
|---|---|
Subscribe to test/esp32/send with MQTTX | Receives "Hello ESP32 MQTT" every 3s |
Use MQTTX to send hello to test/esp32/recv | The ESP32 serial prints [Received] test/esp32/recv -> hello |
7. Common Problems
| Symptom | Cause | Solution |
|---|---|---|
ImportError: no module named 'umqtt' | Firmware does not include the umqtt library | Upload umqtt/simple.py to the ESP32 manually |
| Timeout connecting to Broker | Network unreachable or Broker unreachable | ping broker.emqx.io to test reachability |
check_msg() has no callback | set_callback() or subscribe() not called | Confirm all three steps in section 5.1 are complete |
| Client ID conflict | Two devices use the same ID | Use a unique ID, e.g. esp32s3_mqtt_<last 4 of MAC> |
| No auto-reconnect after Broker disconnect | umqtt.simple has no built-in reconnect mechanism | Detect OSError in try/except; after disconnect, call connect() + subscribe() again |