《ESP8266通信指南》10-MQTT通信(Arduino开发)

本文详细指导了如何在ESP8266模块上实现MQTT通信,包括环境配置、Wi-Fi连接、MQTT概念、相关库安装、MQTTX客户端的使用,以及如何编写代码进行消息上报和接收。
摘要由CSDN通过智能技术生成


往期

《ESP8266通信指南》9-TCP通信(Arudino开发)-CSDN博客

《ESP8266通信指南》8-连接WIFI(Arduino开发)(非常简单)-CSDN博客

《ESP8266通信指南》7-Arduino 开发8266的环境配置与示例代码烧录-CSDN博客

《ESP8266通信指南》6-创建TCP服务器(AT指令)-CSDN博客

《ESP8266通信指南》5-TCP通信透传模式(AT指令)-CSDN博客

《ESP8266通信指南》4-以Client进行TCP通信(AT指令)-CSDN博客

《ESP8266通信指南》3-常用AT指令详解-8266连WIFI-CSDN博客

《ESP8266通信指南》2-ESP8266 AT测试-CSDN博客

《ESP8266通信指南》1-ESP8266 简介-CSDN博客

1. 小节目标

实现 ESP8266 的 MQTT 消息的传送,包括上报消息、接收消息并处理数据等功能。

2. 前言

在实现 ESP8266 进行 MQTT 传输之前,各位读者需要先完成环境搭建WIFI 连接,也就是以下小节的内容:

《ESP8266通信指南》7-Arduino 开发8266的环境配置与示例代码烧录-CSDN博客

《ESP8266通信指南》8-连接WIFI(Arduino开发)(非常简单)-CSDN博客

3. MQTT 简单介绍

(图片来自于网络,侵权联系删除)

当我们谈到MQTT时,可以把它想象成一种特别聪明的通信方式,特别适合物联网这样的场景。想象一下,我们有很多设备,比如智能手机、传感器、智能家居设备,它们需要相互传递信息,但是我们希望这个过程既简单又高效。这时候MQTT就派上了用场。

我们可以将其想象成一种智能的通信方式,特别适合物联网这样的场景。在这个世界里,我们有三个关键角色:发布者、代理和订阅者。

3.1. 发布者

它们就像消息的发起者,生成并发布消息到一个特定的主题(topic),就像是发送一条短信或者邮件通知大家有什么事情要传达。

3.2. 代理

你可以把它想象成一个高效的邮递员,负责接收这些消息,并将它们发送给对这些消息感兴趣的订阅者。代理的作用就是确保消息能够顺利传递,就像是确保信件能够准确送达一样。

3.3. 订阅者

他们就像是等待接收消息的人,他们会在某个主题上订阅,然后就能够收到相关的消息,就像是收到一封信件或者通知一样。

MQTT的优势在于它的简单和高效。它的消息传输速度很快,协议本身也非常简洁,适合在网络带宽有限的情况下使用,比如移动网络或者电池供电的设备。此外,它还可以根据需要提供不同级别的消息传输可靠性,让我们可以根据具体情况选择适合的方案。

4. MQTT 相关包安装

在进行 MQTT 通信之前,需要安装相关的库,PubSubClient,在下图,我已经安装完成,没有安装的读者需要自行安装。

5. MQTT 客户端 MQTTX 安装和使用

5.1. 下载 MQTTX 和安装

官网下载地址:MQTTX:全功能 MQTT 客户端工具

点击这里就可以下载安装了,安装过程非常简单,一直下一步就可以了,这里就不演示了。

5.2. 设置为中文

5.3. 创建一个 MQTT 连接

  1. 点击左侧的“+”号
  2. 输入任意字符的名称,这里的名称只是为了方便我们管理
  3. 点击右上角的“连接”按钮

5.4. 订阅主题

订阅主题分为以下步骤

  1. 点击“添加订阅”
  2. 输入主题的名称
  3. 点击订阅

  • 演示中订阅的主题是“/ct/iot”,读者可以自己自定义主题

5.4.1. 发布消息

发布消息分为以下步骤:

  1. 输入主题名称
  2. 输入消息
  3. 点击发送

因为我们订阅了主题“/ct/iot”,所以我们往主题“/ct/iot”发布的时候,自己也能收到,也就是上图的效果。

6. 进入正题

6.1. 开启移动热点

按照之前章节,在电脑上打开一个移动热点,账号密码自定义,博主的是设置为以下:

  • 账号:ct-iot
  • 密码:111222333

6.2. 完整代码

按照惯例,先上代码,代码的功能是每隔 5 秒钟上报一个数据,到主题(代码中是“/ct/iot/ct_topic”,可以更改为任意内容),在接收到该主题来的数据的时候,会立马打印出来。

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

const char* ssid = "ct-iot"; // Wi-Fi账号
const char* password = "111222333"; // Wi-Fi密码
const char* mqtt_server = "broker.emqx.io"; // MQTT服务器地址
const char* topic = "/ct/iot/ct_topic"; // MQTT主题

WiFiClient espClient;
PubSubClient client(espClient);

long lastMsg = 0;
char msg[50];
int value = 0;
char clientId[10]; // 用于存储生成的随机ID

// 设置Wi-Fi连接
void setup_wifi() {
  delay(10);
  // 连接到Wi-Fi网络
  Serial.println();
  Serial.print("正在连接到 ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  
  Serial.println("");
  Serial.println("Wi-Fi连接成功");
  Serial.println("IP地址: ");
  Serial.println(WiFi.localIP());
}

// 接收到MQTT消息时的回调函数
void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("收到消息 [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
}

// 重新连接到MQTT服务器
void reconnect() {
  // 循环直到重新连接到MQTT
  while (!client.connected()) {
    Serial.print("尝试连接到MQTT服务器...");
    // 尝试连接
    if (client.connect(clientId)) { // 使用生成的随机ID作为客户端ID
      Serial.println("连接成功");
      // 连接成功后订阅我们感兴趣的主题
      client.subscribe(topic);
    } else {
      Serial.print("连接失败, rc=");
      Serial.print(client.state());
      Serial.println(" 5秒后重试");
      // 等待5秒后重试
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  
  // 生成随机ID
  randomSeed(analogRead(0)); // 使用模拟引脚0的读数作为随机数种子
  for (int i = 0; i < 9; ++i) {
    clientId[i] = random(33, 126); // 生成ASCII码为33到126之间的随机数
  }
  clientId[9] = '\0'; // 添加字符串结束符
}

void loop() {
  // 如果需要,重新连接
  if (!client.connected()) {
    reconnect();
  }
  // 确保客户端已连接到MQTT服务器
  client.loop();

  // 每隔5秒发布一次数据
  long now = millis();
  if (now - lastMsg > 5000) {
    lastMsg = now;
    ++value;
    snprintf (msg, 50, "Hello, World! #%ld", value);
    Serial.print("发布消息: ");
    Serial.println(msg);
    // 将消息发布到指定主题
    client.publish(topic, msg);
  }
}

需要各位读者更改的位置:

  1. 移动热点的名称:ssid
  2. 移动热点的密码:password
  3. 如果你也是用 MQTTX,他们是提供一个免费的 MQTT 服务器服务,也就是我代码中写的这个mqtt_server = "broker.emqx.io",读者就不需要更改
  4. 主题topic,建议各位读者在主题里面加入自己的名字或者随机的内容,因为我们是用公共服务器,如果主题跟别人一样的话,会接收到其他数据,这样就不好啦,也有可能导致我们数据泄露~~

6.3. 代码效果

6.3.1. ESP8266 上报数据

我们可以看到,ESP8266 每隔 5 秒钟就会上发一次数据给 MQTT 服务器,MQTTX 客户端接收到就会打印出来。

6.3.2. ESP8266 接收数据

如下图,我们在 MQTTX上发送数据(往 ESP8266 订阅的主题上),ESP8266 就可以接收到接着打印出来。

7. 代码详解

7.1. 包含必要的库文件

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

这里引入了ESP8266WiFi.hPubSubClient.h两个库文件,分别用于ESP8266的Wi-Fi连接和MQTT通信。

7.2. 设置 Wi-Fi 和 MQTT 相关信息

const char* ssid = "ct-iot"; // Wi-Fi账号
const char* password = "111222333"; // Wi-Fi密码
const char* mqtt_server = "broker.emqx.io"; // MQTT服务器地址
const char* topic = "/ct/iot/ct_topic"; // MQTT主题

这里定义了Wi-Fi的账号和密码,以及MQTT服务器的地址和要订阅/发布的主题。

7.3. 全局变量和对象声明

WiFiClient espClient;
PubSubClient client(espClient);

long lastMsg = 0;
char msg[50];
int value = 0;
char clientId[10]; // 用于存储生成的随机ID

声明了一个WiFiClient类型的espClient对象和一个PubSubClient类型的client对象,用于处理Wi-Fi连接和MQTT通信。同时定义了一些全局变量,包括最后一次发送消息的时间、消息内容、计数器和客户端ID。

7.3.1. 设置 Wi-Fi 连接函数

void setup_wifi() {
  // 等待一会儿
  delay(10);
  // 连接到Wi-Fi网络
  Serial.println();
  Serial.print("正在连接到 ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("Wi-Fi连接成功");
  Serial.println("IP地址: ");
  Serial.println(WiFi.localIP());
}

该函数用于连接到Wi-Fi网络,并在连接成功后输出本地IP地址。

7.3.2. 设置 MQTT 回调函数

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("收到消息 [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
}

这个回调函数用于处理接收到的MQTT消息,将收到的消息打印到串行监视器中。

7.3.3. 重新连接到 MQTT 服务器函数

void reconnect() {
  while (!client.connected()) {
    Serial.print("尝试连接到MQTT服务器...");
    if (client.connect(clientId)) { // 使用生成的随机ID作为客户端ID
      Serial.println("连接成功");
      client.subscribe(topic); // 订阅指定主题
    } else {
      Serial.print("连接失败, rc=");
      Serial.print(client.state());
      Serial.println(" 5秒后重试");
      delay(5000); // 5秒后重试
    }
  }
}

这个函数用于重新连接到MQTT服务器,并在连接成功后订阅指定的主题。

7.3.4. setup() 函数

void setup() {
  Serial.begin(115200);
  setup_wifi(); // 设置Wi-Fi连接
  client.setServer(mqtt_server, 1883); // 设置MQTT服务器
  client.setCallback(callback); // 设置回调函数
  
  // 生成随机ID
  randomSeed(analogRead(0)); // 使用模拟引脚0的读数作为随机数种子
  for (int i = 0; i < 9; ++i) {
    clientId[i] = random(33, 126); // 生成ASCII码为33到126之间的随机数
  }
  clientId[9] = '\0'; // 添加字符串结束符
}

setup()函数中,初始化串行通信,设置Wi-Fi连接,设置MQTT服务器,设置回调函数,并生成随机的客户端ID。

7.3.5. 主循环

void loop() {
  if (!client.connected()) {
    reconnect(); // 如果需要,重新连接到MQTT服务器
  }
  client.loop(); // 确保客户端已连接到MQTT服务器

  // 每隔5秒发布一次数据
  long now = millis();
  if (now - lastMsg > 5000) {
    lastMsg = now;
    ++value;
    snprintf (msg, 50, "Hello, World! #%ld", value);
    Serial.print("发布消息: ");
    Serial.println(msg);
    client.publish(topic, msg); // 发布消息到指定主题
  }
}

在主循环中,检查MQTT客户端是否连接到服务器,如果未连接,则调用重新连接函数。然后,确保客户端已连接到MQTT服务器,并通过client.loop()函数处理MQTT消息。最后,每隔5秒发布一条带有计数器的消息到指定主题。

通过以上步骤,我们实现了一个能够通过Wi-Fi和MQTT与远程服务器通信的ESP8266应用程序。

8. 结语


介绍了 ESP8266 使用 MQTT 相关的包和客户端模拟器 MQTTX,接着编写代码,完成以下功能:

  • 设置Wi-Fi连接,连接到指定的Wi-Fi网络后输出IP地址
  • 设置MQTT客户端,并生成一个随机的客户端ID
  • 在主循环中,持续尝试连接到MQTT服务器,如果连接成功则订阅指定的主题
  • 定时发布一条消息到MQTT服务器
  • 在串行监视器中输出接收到的消息


柴头物联网出品

  • 27
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值