ESP32 Arduino开发 MQTT
ESP32 Arduino开发 MQTT
目录
1. 安装程序库
- 打开库管理工具
工具 -> 管理库...
- 查找所需要的程序库
安装PubSubClient
2. 编写相关程序
2.1. 引入头文件
在保证网络连接的前提之下,才可以连接MQTT。
所以需要引入<WiFi.h>
的库。
#include <WiFi.h>
#include <PubSubClient.h>
2.2. 定义MQTT相关参数
MQTT相关参数可以分为3个部分:一是方便开发所设计的宏定义参数,二是网络连接所需要的信息,三是MQTT连接所需要的信息。
MQTT连接所需要的信息包括:
- MQTT服务器(选用EMQX的开源测试服务器)
- MQTT主题
- 用户名
- 密码
- 端口号
- 服务器ID
#define MAX_RETRIES 20 // 网络最大连接次数
#define MQTT_CALLBACK 1 // 是否开启MQTT回调函数
const char* ssid="HTB"; // 网络信息
const char* pass="htb66666666";
// 设置MQTT borker信息
const char *mqtt_broker = "broker-cn.emqx.io";
const char *topic = "mqtt_hbb_example";
const char *mqtt_username = "emqx";
const char *mqtt_password = "public";
const int mqtt_port = 1883;
const char *client_id = "mqtt-client-hbb-example";
2.3. 创建对象
创建MQTT服务器对象
WiFiClient espClient;
PubSubClient client(espClient);
2.4. 连接网络
网络连接函数是在之前的教程《ESP32 Arduino开发 网络连接》的基础上进行了小部分的修改,将其封装成函数,返回值表示网络是否连接成功。
// 网络连接函数
bool connectWifi(){
Serial.println("调用WiFi连接函数");
WiFi.begin(ssid, pass);
for(int i=0; i<MAX_RETRIES; i++){
delay(500);
if(WiFi.status()==WL_CONNECTED){
Serial.println("网络连接成功");
return true;
}
}
if(WiFi.status()!=WL_CONNECTED){
Serial.println("网络连接超时");
return false;
}
}
2.5. 连接MQTT服务器
- 通过
setServer
函数设置服务器地址及端口号 #if
、#endif
是预处理命令,跟if语句的作用类似,如果宏为真,则执行其中的语句,如果宏为假,则其中的语句不编译- 先要保证Wi-Fi连接处于正常状态,再执行MQTT的连接函数。MQTT连接整体的程序设计思路与Wi-Fi连接是一致的。
// MQTT服务器连接函数
bool connectMqtt(){
Serial.println("调用MQTT连接函数");
client.setServer(mqtt_broker, mqtt_port);
#if MQTT_CALLBACK
Serial.println("调用MQTT回调函数");
client.setCallback(mqttCallback);
#endif
if(WiFi.status()==WL_CONNECTED){
for(int i=0; i<MAX_RETRIES; i++){
delay(1000);
if(client.connect(client_id, mqtt_username, mqtt_password)){
Serial.println("MQTT服务器连接成功");
return true;
}
}
if(!client.connected()){
Serial.println("MQTT服务器连接超时");
return false;
}
}else{
Serial.println("网络连接失败");
return false;
}
}
2.6. MQTT回调函数
未完待续
3. 完整的代码例程
#include <WiFi.h>
#include <PubSubClient.h>
#define MAX_RETRIES 20 // 网络最大连接次数
#define MQTT_CALLBACK 1 // 是否开启MQTT回调函数
const char* ssid="HTB"; // 网络信息
const char* pass="htb66666666";
const char *mqtt_broker = "broker-cn.emqx.io"; // 设置MQTT borker信息
const char *topic = "mqtt_hbb_example";
const char *mqtt_username = "emqx";
const char *mqtt_password = "public";
const int mqtt_port = 1883;
const char *client_id = "mqtt-client-hbb-example";
// String client_id = "esp32-client-" + String(WiFi.macAddress()); // 服务器id设置为wifi的物理地址
WiFiClient espClient;
PubSubClient client(espClient);
// MQTT监听函数
void mqttCallback(char *topic, byte *payload, unsigned int length) {
Serial.print("Message arrived in topic: ");
Serial.println(topic);
Serial.print("Message:");
String charPayload;
for (int i = 0; i < length; i++) {
charPayload += (char) payload[i];
}
Serial.println(charPayload);
Serial.println("-----------------------");
}
// 网络连接函数
bool connectWifi(){
Serial.println("调用WiFi连接函数");
WiFi.begin(ssid, pass);
for(int i=0; i<MAX_RETRIES; i++){
delay(500);
if(WiFi.status()==WL_CONNECTED){
Serial.println("网络连接成功");
return true;
}
}
if(WiFi.status()!=WL_CONNECTED){
Serial.println("网络连接超时");
return false;
}
}
// MQTT服务器连接函数
bool connectMqtt(){
Serial.println("调用MQTT连接函数");
client.setServer(mqtt_broker, mqtt_port);
#if MQTT_CALLBACK
Serial.println("调用MQTT回调函数");
client.setCallback(mqttCallback);
#endif
if(WiFi.status()==WL_CONNECTED){
for(int i=0; i<MAX_RETRIES; i++){
delay(1000);
if(client.connect(client_id, mqtt_username, mqtt_password)){
Serial.println("MQTT服务器连接成功");
return true;
}
}
if(!client.connected()){
Serial.println("MQTT服务器连接超时");
return false;
}
}else{
Serial.println("网络连接失败");
return false;
}
}
void setup() {
Serial.begin(115200);
if(connectWifi()){
connectMqtt();
};
}
void loop() {
// put your main code here, to run repeatedly:
}
4. MQTT连接测试
未完待续