一、库介绍
Arduino常用的MQTT库主要有PubSubClient。
PubSubClient库是一个广泛使用的MQTT客户端库,它基于MQTT 3.1.1版本,并且支持ESP8266和ESP32等Arduino兼容的硬件平台。PubSubClient库允许Arduino设备连接到MQTT服务器,发布和订阅MQTT主题,实现与其他设备或服务的通信。
在使用PubSubClient库时,需要将其包含在Arduino项目中,并配置MQTT服务器的地址、端口、客户端ID等参数。然后可以使用库提供的函数来建立MQTT连接、发布消息到特定的主题,以及订阅并处理接收到的消息。
除了PubSubClient库之外,还有其他一些MQTT库可供选择,但PubSubClient因其易用性和稳定性而广受欢迎。需要根据具体需求和项目环境选择适合的MQTT库。
安装完库,可查看官方的示例代码,查看方法如下:
官方示例代码如下:
/*Basic ESP8266 MQTT exampleThis sketch demonstrates the capabilities of the pubsub library in combinationwith the ESP8266 board/library.It connects to an MQTT server then:- publishes "hello world" to the topic "outTopic" every two seconds- subscribes to the topic "inTopic", printing out any messagesit receives. NB - it assumes the received payloads are strings not binary- If the first character of the topic "inTopic" is an 1, switch ON the ESP Led,else switch it offIt will reconnect to the server if the connection is lost using a blockingreconnect function. See the 'mqtt_reconnect_nonblocking' example for how toachieve the same result without blocking the main loop.To install the ESP8266 board, (using Arduino 1.6.4+):- Add the following 3rd party board manager under "File -> Preferences -> Additional Boards Manager URLs":http://arduino.esp8266.com/stable/package_esp8266com_index.json- Open the "Tools -> Board -> Board Manager" and click install for the ESP8266"- Select your ESP8266 in "Tools -> Board"
*/#include <ESP8266WiFi.h>
#include <PubSubClient.h>// Update these with values suitable for your network.const char* ssid = "........";
const char* password = "........";
const char* mqtt_server = "broker.mqtt-dashboard.com";WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE (50)
char msg[MSG_BUFFER_SIZE];
int value = 0;void setup_wifi() {delay(10);// We start by connecting to a WiFi networkSerial.println();Serial.print("Connecting to ");Serial.println(ssid);WiFi.mode(WIFI_STA);WiFi.begin(ssid, password);while (WiFi.status() != WL_CONNECTED) {delay(500);Serial.print(".");}randomSeed(micros());Serial.println("");Serial.println("WiFi connected");Serial.println("IP address: ");Serial.println(WiFi.localIP());
}void callback(char* topic, byte* payload, unsigned int length) {Serial.print("Message arrived [");Serial.print(topic);Serial.print("] ");for (int i = 0; i < length; i++) {Serial.print((char)payload[i]);}Serial.println();// Switch on the LED if an 1 was received as first characterif ((char)payload[0] == '1') {digitalWrite(BUILTIN_LED, LOW); // Turn the LED on (Note that LOW is the voltage level// but actually the LED is on; this is because// it is active low on the ESP-01)} else {digitalWrite(BUILTIN_LED, HIGH); // Turn the LED off by making the voltage HIGH}}void reconnect() {// Loop until we're reconnectedwhile (!client.connected()) {Serial.print("Attempting MQTT connection...");// Create a random client IDString clientId = "ESP8266Client-";clientId += String(random(0xffff), HEX);// Attempt to connectif (client.connect(clientId.c_str())) {Serial.println("connected");// Once connected, publish an announcement...client.publish("outTopic", "hello world");// ... and resubscribeclient.subscribe("inTopic");} else {Serial.print("failed, rc=");Serial.print(client.state());Serial.println(" try again in 5 seconds");// Wait 5 seconds before retryingdelay(5000);}}
}void setup() {pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an outputSerial.begin(115200);setup_wifi();client.setServer(mqtt_server, 1883);client.setCallback(callback);
}void loop() {if (!client.connected()) {reconnect();}client.loop();unsigned long now = millis();if (now - lastMsg > 2000) {lastMsg = now;++value;snprintf (msg, MSG_BUFFER_SIZE, "hello world #%ld", value);Serial.print("Publish message: ");Serial.println(msg);client.publish("outTopic", msg);}
}
二、代码设计
代码设计思路:
1.包含库:在Arduino项目中,包含必要的库文件,特别是MQTT库(如pubsubclient)。
2.WiFi设置:设置ESP8266连接到指定的WiFi网络所需的SSID和密码。
3.MQTT服务器设置:配置MQTT服务器的地址、端口以及任何必要的认证信息(如用户名和密码)。
4.回调函数:设置MQTT连接、发布和订阅的回调函数,以便处理与MQTT服务器的通信。
5.初始化和连接:在setup()函数中初始化MQTT客户端,并尝试连接到MQTT服务器。
6.消息处理:在loop()函数中处理MQTT消息,例如发布消息到特定的主题或响应订阅的主题消息。
测试代码如下:
#include <ESP8266WiFi.h>
#include <PubSubClient.h> // WiFi设置
const char* ssid = "yourSSID";
const char* password = "yourPASSWORD"; // MQTT服务器设置
const char* mqtt_server = "yourMQTTServer";
const int mqtt_port = 1883;
const char* mqtt_client_id = "ESP8266Client";
const char* mqtt_topic = "your/topic"; //
unsigned long lastMsg = 0;WiFiClient espClient;
PubSubClient client(espClient); void setup_wifi() { delay(10); // 连接到WiFi网络 Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.print("IP address: "); Serial.println(WiFi.localIP());
} void reconnect() { // Loop until we're reconnected while (!client.connected()) { Serial.print("Attempting MQTT connection..."); // 连接到MQTT服务器 if (client.connect(mqtt_client_id)) { Serial.println("connected"); // 一旦连接,订阅主题 client.subscribe(mqtt_topic); } else { delay(5000); } }
} void callback(char* topic, byte* payload, unsigned int length) { // 处理接收到的消息 Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println();
} void setup() { Serial.begin(115200); setup_wifi(); client.setServer(mqtt_server, mqtt_port); client.setCallback(callback);
} void loop() { if (!client.connected()) { reconnect(); } client.loop(); // 每隔一段时间发布一条消息到MQTT主题 long now = millis(); if (now - lastMsg > 2000) { lastMsg = now; char msg[50]; snprintf(msg, 50, "hello world at %ld", now); client.publish(mqtt_topic, msg); }
}
请确保上述代码中的yourSSID、yourPASSWORD、yourMQTTServer、your/topic替换为实际的SSID、密码、MQTT服务器地址和主题。
这个示例代码首先设置了WiFi连接,然后连接到MQTT服务器。一旦连接成功,它将订阅一个MQTT主题。在loop()函数中,它周期性地发布消息到该主题,并处理从该主题接收到的任何消息。
此外,MQTT服务器的地址、端口和凭据(如果需要的话)应根据实际的MQTT服务器配置进行调整。如MQTT服务器需要用户名和密码,PubSubClient库也提供了设置这些的方法。
上传成功后,打开串口监视器来查看ESP8266与MQTT服务器的通信日志。
三、测试结果
MQTT的参数配置如下:
// MQTT服务器设置
const char* mqtt_server = "broker.mqtt-dashboard.com";
const int mqtt_port = 1883;
const char* mqtt_client_id = "ESP8266Client0326";
const char* mqtt_topic = "test/topic";
esp8266模块运行串口打印如下:
更换其它服务器进行测试,如下: