基于NodeMCU板通过MQTT Broker订阅多发布者的技术问询
Hey there, let’s break down the core logic and address the most common questions you’ll run into when setting up your NodeMCU subscriber to listen to four other NodeMCU publishers via MQTT Box.
Topic Structure: Organizing Messages from Multiple Publishers
This is one of the first things to get right to avoid confusion. A clean topic hierarchy makes it easy to filter and identify which publisher a message comes from.
Recommended Topic Format:nodemcu/sensor/<device-id>/<reading-type>
device-id: Unique identifier for each of your 4 NodeMCUs (likedevice01,device02, or their MAC addresses)reading-type: What data they’re sending (e.g.,temperature,humidity,motion)
Example topics:
nodemcu/sensor/device01/temperaturenodemcu/sensor/device03/motion
On your subscriber NodeMCU, you can either:
- Subscribe to individual topics for each device/reading, or
- Use a wildcard to listen to all relevant messages at once:
nodemcu/sensor/#(the#wildcard matches any subtopic under the parent)
Setting Up the Subscriber NodeMCU Connection
Here’s a minimal, practical code snippet using the standard PubSubClient library to connect your subscriber to MQTT Box and start listening:
#include <ESP8266WiFi.h> #include <PubSubClient.h> // WiFi credentials const char* ssid = "YOUR_WIFI_SSID"; const char* password = "YOUR_WIFI_PASSWORD"; // MQTT Broker details (MQTT Box) const char* mqtt_server = "MQTT_BROKER_IP"; // e.g., "192.168.1.100" const int mqtt_port = 1883; // Default MQTT port const char* mqtt_client_id = "subscriber_nodemcu"; // Unique ID for your subscriber const char* mqtt_topic = "nodemcu/sensor/#"; // Wildcard to listen to all sensor messages WiFiClient espClient; PubSubClient client(espClient); // Callback function to handle incoming messages void callback(char* topic, byte* payload, unsigned int length) { Serial.print("Message from topic: "); Serial.println(topic); Serial.print("Payload: "); for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println("\n-----------------------"); } void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("\nWiFi connected"); client.setServer(mqtt_server, mqtt_port); client.setCallback(callback); // Connect to MQTT Broker while (!client.connected()) { Serial.print("Attempting MQTT connection..."); if (client.connect(mqtt_client_id)) { Serial.println("connected"); client.subscribe(mqtt_topic); // Subscribe to your target topic(s) } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" | retrying in 5s"); delay(5000); } } } void loop() { if (!client.connected()) { reconnect(); // Auto-reconnect if connection drops } client.loop(); // Keep MQTT connection alive and process incoming messages } void reconnect() { while (!client.connected()) { Serial.print("Reconnecting to MQTT..."); if (client.connect(mqtt_client_id)) { Serial.println("connected"); client.subscribe(mqtt_topic); // Re-subscribe after reconnection } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" | retrying in 5s"); delay(5000); } } }
Distinguishing Messages from Each Publisher
Since your topic includes a unique device-id, you can parse the topic string in the callback function to identify which NodeMCU sent the message. Add this to your callback function:
// Split the topic to extract device ID char* token = strtok(topic, "/"); token = strtok(NULL, "/"); // Skip "nodemcu" token = strtok(NULL, "/"); // Skip "sensor" char* device_id = strtok(NULL, "/"); // This gives you the unique device ID Serial.print("Message from device: "); Serial.println(device_id);
Ensuring Reliable Message Reception
- QoS Levels: Use QoS 1 for sensor data—it ensures the broker receives the message at least once. Specify QoS when subscribing:
client.subscribe(mqtt_topic, 1);(publishers should also send with QoS 1). - Reconnection Logic: The
reconnect()function above automatically restores the connection and re-subscribes if WiFi/MQTT drops out. - Avoid Blocking Code: Don’t use long
delay()calls in yourloop()—it will cause missed messages. Use non-blocking timing withmillis()instead.
Troubleshooting Quick Wins
- Unique Client IDs: Every NodeMCU (publishers and subscriber) needs a distinct
mqtt_client_id—duplicates will cause disconnections. - Broker Access: Ensure MQTT Box is on the same WiFi network as your NodeMCUs, and port 1883 is open.
- Serial Debugging: Use
Serial.print()to monitor connection status, incoming topics, and payloads—it’s the fastest way to spot issues.
content的提问来源于stack exchange,提问作者Wan Street

