- ESP32物联网教程
- 首页
- 物联网简述
- ESP32简介
- 在Arduino IDE中安装ESP32开发板
- 设置RTOS进行双核和多线程操作
- ESP32与MPU6050接口连接
- ESP32与模拟传感器的接口连接
- ESP32首选项
- ESP32 SPIFFS存储(芯片自带的迷你SD卡)
- ESP32与OLED显示屏接口连接
- ESP32上的WiFi
- 使用HTTP通过WiFi传输数据
- 使用HTTPS通过WiFi传输数据
- 使用MQTT通过WiFi传输数据
- 通过蓝牙传输数据
- 使用NTP客户端获取当前时间
- 执行ESP32固件的(OTA)更新
- ESP32的应用
- 开发者后续步骤
- ESP32物联网实用资源
- 快速指南
- 实用资源
- 讨论
使用MQTT通过WiFi传输数据
MQTT(消息队列遥测传输)在物联网设备中获得了广泛的关注。它是一个通常在TCP/IP上运行的协议。与我们之前看到的HTTP的服务器-客户端模型不同,MQTT使用代理-客户端模型。维基百科将MQTT代理和客户端定义为:
MQTT代理是接收来自所有客户端的所有消息,然后将消息路由到相应的目标客户端的服务器。MQTT客户端是任何运行MQTT库并通过网络连接到MQTT代理的设备(从微控制器到功能齐全的服务器)。
将代理想象成类似Medium的服务。主题就是Medium上的出版物,客户端就是Medium的用户。用户(客户端)可以向出版物发布内容,订阅该出版物(主题)的另一个用户(客户端)将被告知有新的帖子可供阅读。到目前为止,您应该已经理解了HTTP和MQTT之间的一个主要区别。在HTTP中,您的消息直接发送到目标服务器,您甚至会以状态代码的形式获得确认。在MQTT中,您只是将消息发送到代理,希望您的目标服务器能够从中获取信息。如果您资源受限,MQTT的几个特性将成为一大福音。它们列在下面:
使用MQTT,报头开销非常短,吞吐量很高。这有助于节省时间和电池电量。
MQTT将信息发送为字节数组,而不是文本格式。这使消息更轻量级。
因为MQTT不依赖于服务器的响应,客户端是独立的,并且可以在传输消息后进入睡眠状态(节省电池电量)。
这些只是一些导致MQTT流行的原因。您可以在这里找到MQTT和HTTP之间更详细的比较这里。
代码演练
通常,测试MQTT需要您在代理商注册免费/付费帐户。AWS IoT和Azure IoT是非常流行的提供MQTT代理服务的平台,但它们需要冗长的注册和配置过程。幸运的是,有一个来自HiveMQ的免费代理服务,可用于在无需注册或配置的情况下测试MQTT。它非常适合那些MQTT新手,只想动手实践的人,并且还可以让您更专注于ESP32的固件。因此,我们将在此章节中使用该代理。当然,因为它是一项免费服务,所以会有一些限制。您不能共享敏感信息,因为所有消息都是公开的,任何人都可以订阅您的主题。当然,对于测试目的,这些限制无关紧要。
代码可在GitHub上找到
我们将使用PubSubClient库。您可以从工具->管理库中安装它。
安装库后,我们包含WiFi和PubSubClient库。
#include <WiFi.h> #include <PubSubClient.h>
接下来,我们将定义一些常量。请记住替换WiFi凭据。mqttServer和mqttPort是由http://www.mqtt−dashboard.com/强制规定的。mqtt_client_name、mqtt_pub_topic和mqtt_sub_topic可以是您选择的任何字符串。只需确保您更改了它们的值。如果多个用户从本教程复制相同的代码,您将在测试时收到许多来自未知客户端的消息。
我们还定义了WiFiClient和mqttClient对象。MQTTClient对象需要网络客户端作为参数。如果您使用以太网,则会提供以太网客户端作为参数。由于我们使用的是WiFi,因此我们提供了WiFi客户端作为参数。
const char* ssid = "YOUR_SSID"; const char* password = "YOUR_PASSWORD"; //The broker and port are provided by http://www.mqtt−dashboard.com/ char *mqttServer = "broker.hivemq.com"; int mqttPort = 1883; //Replace these 3 with the strings of your choice const char* mqtt_client_name = "ESPYS2111"; const char* mqtt_pub_topic = "/ys/testpub"; //The topic to which our client will publish const char* mqtt_sub_topic = "/ys/testsub"; //The topic to which our client will subscribe WiFiClient client; PubSubClient mqttClient(client);
接下来,我们定义回调函数。回调函数是一个中断函数。每当从订阅的主题接收到新消息时,都会触发此函数。它有三个参数:接收消息的主题、作为字节数组的消息以及消息的长度。您可以对该消息执行任何操作(将其存储在SPIFFS中,发送到另一个主题等)。在这里,我们只是打印主题和消息。
void callback(char* topic, byte* payload, unsigned int length) { Serial.print("Message received from: "); Serial.println(topic); for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println(); Serial.println(); }
在setup中,我们像其他每个草图一样连接到WiFi。最后两行与MQTT有关。我们设置MQTT的服务器和端口,以及回调函数。
void setup() { // put your setup code here, to run once: Serial.begin(115200); WiFi.mode(WIFI_STA); //The WiFi is in station mode WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.print("WiFi connected to: "); Serial.println(ssid); Serial.println("IP address: "); Serial.println(WiFi.localIP()); delay(2000); mqttClient.setServer(mqttServer, mqttPort); mqttClient.setCallback(callback); }
在循环中,我们执行以下操作
如果客户端未连接到代理,我们使用客户端名称连接它。
连接后,我们还将客户端订阅到mqtt_sub_topic。
然后,我们将消息发布到mqtt_pub_topic
然后我们运行**mqttClient.loop()**。此loop()函数应定期调用。它维护客户端与代理的连接,并帮助客户端处理传入的消息。如果您没有这行**mqttClient.loop()**代码,您将能够发布到mqtt_pub_topic,但不会收到来自mqtt_sub_topic的消息,因为只有调用此行时才会处理传入的消息。
最后,我们等待5秒钟,然后再次启动此循环。
void loop() { // put your main code here, to run repeatedly: if (!mqttClient.connected()){ while (!mqttClient.connected()){ if(mqttClient.connect(mqtt_client_name)){ Serial.println("MQTT Connected!"); mqttClient.subscribe(mqtt_sub_topic); } else{ Serial.print("."); } } } mqttClient.publish(mqtt_pub_topic, "TestMsg"); Serial.println("Message published"); mqttClient.loop(); delay(5000); }
测试代码
为了测试上述代码,您需要访问www.hivemq.com
在该网页上之后,请按照以下步骤操作:
单击“连接”
单击“添加新的主题订阅”,然后输入ESP32将发布到的主题名称(在本例中为/ys/testpub)
刷新ESP32后,您将每5秒开始接收该主题上的消息。
- 接下来,要测试ESP32上的消息接收,请输入ESP32订阅的主题名称(在本例中为ys/testsub),然后在消息框中键入消息并单击发布。您应该在串口监视器上看到该消息。
恭喜!!您已在ESP32上使用MQTT测试了发布和订阅。