当前位置:网站首页>学习太极创客 — MQTT(八)ESP8266订阅MQTT主题
学习太极创客 — MQTT(八)ESP8266订阅MQTT主题
2022-06-27 02:10:00 【xuechanba】

1、订阅单个主题
/********************************************************************** 项目名称/Project : 零基础入门学用物联网 程序名称/Program name : subscribe_ranye_url 团队/Team : 太极创客团队 / Taichi-Maker (www.taichi-maker.com) 作者/Author : CYNO朔 日期/Date(YYYYMMDD) : 20200708 程序目的/Purpose : 本程序旨在演示如何使用PubSubClient库使用ESP8266向MQTT服务器订阅信息。 ----------------------------------------------------------------------- 本示例程序为太极创客团队制作的《零基础入门学用物联网》中示例程序。 该教程为对物联网开发感兴趣的朋友所设计和制作。如需了解更多该教程的信息,请参考以下网页: http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-nodemcu-web-client/http-request/ ***********************************************************************/
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
// 设置wifi接入信息(请根据您的WiFi信息进行修改)
const char* ssid = "FAST_153C80";
const char* password = "123456798";
const char* mqttServer = "test.ranye-iot.net";
// 如以上MQTT服务器无法正常连接,请前往以下页面寻找解决方案
// http://www.taichi-maker.com/public-mqtt-broker/
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // 设置板上LED引脚为输出模式
digitalWrite(LED_BUILTIN, HIGH); // 启动后关闭板上LED
Serial.begin(9600); // 启动串口通讯
//设置ESP8266工作模式为无线终端模式
WiFi.mode(WIFI_STA);
// 连接WiFi
connectWifi();
// 设置MQTT服务器和端口号
mqttClient.setServer(mqttServer, 1883);
// 设置MQTT订阅回调函数
mqttClient.setCallback(receiveCallback);
// 连接MQTT服务器
connectMQTTserver();
}
void loop() {
if (mqttClient.connected()) {
// 如果开发板成功连接服务器
mqttClient.loop(); // 处理信息以及心跳
} else {
// 如果开发板未能成功连接服务器
connectMQTTserver(); // 则尝试连接服务器
}
}
// 连接MQTT服务器并订阅信息
void connectMQTTserver(){
// 根据ESP8266的MAC地址生成客户端ID(避免与其它ESP8266的客户端ID重名)
String clientId = "esp8266-" + WiFi.macAddress();
// 连接MQTT服务器
if (mqttClient.connect(clientId.c_str())) {
Serial.println("MQTT Server Connected.");
Serial.println("Server Address:");
Serial.println(mqttServer);
Serial.println("ClientId: ");
Serial.println(clientId);
subscribeTopic(); // 订阅指定主题
} else {
Serial.print("MQTT Server Connect Failed. Client State:");
Serial.println(mqttClient.state());
delay(5000);
}
}
// 收到信息后的回调函数
void receiveCallback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message Received [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println("");
Serial.print("Message Length(Bytes) ");
Serial.println(length);
if ((char)payload[0] == '1') {
// 如果收到的信息以“1”为开始
digitalWrite(BUILTIN_LED, LOW); // 则点亮LED。
Serial.println("LED ON");
} else {
digitalWrite(BUILTIN_LED, HIGH); // 否则熄灭LED。
Serial.println("LED OFF");
}
}
// 订阅指定主题
void subscribeTopic(){
// 建立订阅主题。主题名称以Taichi-Maker-Sub为前缀,后面添加设备的MAC地址。
// 这么做是为确保不同设备使用同一个MQTT服务器测试消息订阅时,所订阅的主题名称不同
String topicString = "Taichi-Maker-Sub-" + WiFi.macAddress();
char subTopic[topicString.length() + 1];
strcpy(subTopic, topicString.c_str());
// 通过串口监视器输出是否成功订阅主题以及订阅的主题名称
if(mqttClient.subscribe(subTopic)){
Serial.println("Subscrib Topic:");
Serial.println(subTopic);
} else {
Serial.print("Subscribe Fail...");
}
}
// ESP8266连接wifi
void connectWifi(){
WiFi.begin(ssid, password);
//等待WiFi连接,成功连接后输出成功信息
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi Connected!");
Serial.println("");
}
程序运行结果如下,
下面再来尝试使用 MQTT.fx 这个软件向 Taichi-Maker-Sub-EC:FA:BC:40:6F:5B 这个主题发布信息,同时观察串口监视器的输出。


当 LED ON 时,ESP8266 的板载 LED 也被点亮。
下面,来讲解下程序的重点。
// 设置MQTT订阅回调函数
mqttClient.setCallback(receiveCallback);
此处的 ESP8266 开发板的作用是订阅 MQTT 主题,它在订阅 MQTT 主题以后,每当收到该主题信息后,他就会调用一个回调函数 receiveCallback ,以此来处理收到的信息。
2、订阅指定主题
// 通过串口监视器输出是否成功订阅主题以及订阅的主题名称
if(mqttClient.subscribe(subTopic)){
Serial.println("Subscrib Topic:");
Serial.println(subTopic);
} else {
Serial.print("Subscribe Fail...");
}
mqttClient.subscribe(subTopic) 将会尝试订阅一个主题,主题名为 “Taichi-Maker-Sub-” + WiFi.macAddress(),
如果订阅成功将返回 1 。
3、收到信息后的回调函数
void receiveCallback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message Received [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println("");
Serial.print("Message Length(Bytes) ");
Serial.println(length);
if ((char)payload[0] == '1') {
// 如果收到的信息以“1”为开始
digitalWrite(BUILTIN_LED, LOW); // 则点亮LED。
Serial.println("LED ON");
} else {
digitalWrite(BUILTIN_LED, HIGH); // 否则熄灭LED。
Serial.println("LED OFF");
}
}
注意三个参数,三个参数是固定格式。
topic 是主题名
payload 是具体信息的内容,是一个数组类型
length 是具体信息的长度
2、订阅多个主题
/********************************************************************** 项目名称/Project : 零基础入门学用物联网 程序名称/Program name : subscribe_multitopic_ranye_url 团队/Team : 太极创客团队 / Taichi-Maker (www.taichi-maker.com) 作者/Author : CYNO朔 日期/Date(YYYYMMDD) : 20201125 程序目的/Purpose : 本程序旨在演示如何使用PubSubClient库使用ESP8266向MQTT服务器订阅多个主题 ----------------------------------------------------------------------- 本示例程序为太极创客团队制作的《零基础入门学用物联网》中示例程序。 该教程为对物联网开发感兴趣的朋友所设计和制作。如需了解更多该教程的信息,请参考以下网页: http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-nodemcu-web-client/http-request/ ***********************************************************************/
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
// 设置wifi接入信息(请根据您的WiFi信息进行修改)
const char* ssid = "FAST_153C80";
const char* password = "123456798";
const char* mqttServer = "test.ranye-iot.net";
// 如以上MQTT服务器无法正常连接,请前往以下页面寻找解决方案
// http://www.taichi-maker.com/public-mqtt-broker/
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // 设置板上LED引脚为输出模式
digitalWrite(LED_BUILTIN, HIGH); // 启动后关闭板上LED
Serial.begin(9600); // 启动串口通讯
//设置ESP8266工作模式为无线终端模式
WiFi.mode(WIFI_STA);
// 连接WiFi
connectWifi();
// 设置MQTT服务器和端口号
mqttClient.setServer(mqttServer, 1883);
mqttClient.setCallback(receiveCallback);
// 连接MQTT服务器
connectMQTTserver();
}
void loop() {
if (mqttClient.connected()) {
// 如果开发板成功连接服务器
mqttClient.loop(); // 处理信息以及心跳
} else {
// 如果开发板未能成功连接服务器
connectMQTTserver(); // 则尝试连接服务器
}
}
// 连接MQTT服务器并订阅信息
void connectMQTTserver(){
// 根据ESP8266的MAC地址生成客户端ID(避免与其它ESP8266的客户端ID重名)
String clientId = "esp8266-" + WiFi.macAddress();
// 连接MQTT服务器
if (mqttClient.connect(clientId.c_str())) {
Serial.println("MQTT Server Connected.");
Serial.println("Server Address:");
Serial.println(mqttServer);
Serial.println("ClientId: ");
Serial.println(clientId);
subscribeTopic(); // 订阅指定主题
} else {
Serial.print("MQTT Server Connect Failed. Client State:");
Serial.println(mqttClient.state());
delay(5000);
}
}
// 收到信息后的回调函数
void receiveCallback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message Received [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println("");
Serial.print("Message Length(Bytes) ");
Serial.println(length);
if ((char)payload[0] == '1') {
// 如果收到的信息以“1”为开始
digitalWrite(BUILTIN_LED, LOW); // 则点亮LED。
} else {
digitalWrite(BUILTIN_LED, HIGH); // 否则熄灭LED。
}
}
// 订阅指定主题
void subscribeTopic(){
// 建立订阅主题1。主题名称以Taichi-Maker-Sub为前缀,后面添加设备的MAC地址。
// 这么做是为确保不同设备使用同一个MQTT服务器测试消息订阅时,所订阅的主题名称不同
String topicString = "Taichi-Maker-Sub-" + WiFi.macAddress();
char subTopic[topicString.length() + 1];
strcpy(subTopic, topicString.c_str());
// 建立订阅主题2
String topicString2 = "Taichi-Maker-Sub2-" + WiFi.macAddress();
char subTopic2[topicString2.length() + 1];
strcpy(subTopic2, topicString2.c_str());
// 通过串口监视器输出是否成功订阅主题1以及订阅的主题1名称
if(mqttClient.subscribe(subTopic)){
Serial.println("Subscrib Topic:");
Serial.println(subTopic);
} else {
Serial.print("Subscribe Fail...");
}
// 通过串口监视器输出是否成功订阅主题2以及订阅的主题2名称
if(mqttClient.subscribe(subTopic2)){
Serial.println("Subscrib Topic:");
Serial.println(subTopic2);
} else {
Serial.print("Subscribe Fail...");
}
}
// ESP8266连接wifi
void connectWifi(){
WiFi.begin(ssid, password);
//等待WiFi连接,成功连接后输出成功信息
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi Connected!");
Serial.println("");
}
运行代码如下,
下面再来尝试使用 MQTT.fx 这个软件分别向 Taichi-Maker-Sub-EC:FA:BC:40:6F:5B 和 Taichi-Maker-Sub2-EC:FA:BC:40:6F:5B 这两个主题发布信息,同时观察串口监视器的输出。


不管通过哪个主题发布消息,只要信息的第一个字符为 1 ,那么就点亮板载 LED 。
3、使用单级通配符订阅主题
/********************************************************************** 项目名称/Project : 零基础入门学用物联网 程序名称/Program name : subscribe_single_level_wildcard_ranye 团队/Team : 太极创客团队 / Taichi-Maker (www.taichi-maker.com) 作者/Author : CYNO朔 日期/Date(YYYYMMDD) : 20200813 程序目的/Purpose : 本程序旨在演示ESP8266订阅信息时的单极通配符+应用。 ----------------------------------------------------------------------- 本示例程序为太极创客团队制作的《零基础入门学用物联网》中示例程序。 该教程为对物联网开发感兴趣的朋友所设计和制作。如需了解更多该教程的信息,请参考以下网页: http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-nodemcu-web-client/http-request/ ***********************************************************************/
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
// 设置wifi接入信息(请根据您的WiFi信息进行修改)
const char* ssid = "taichi-maker";
const char* password = "12345678";
const char* mqttServer = "test.ranye-iot.net";
// 如以上MQTT服务器无法正常连接,请前往以下页面寻找解决方案
// http://www.taichi-maker.com/public-mqtt-broker/
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // 设置板上LED引脚为输出模式
digitalWrite(LED_BUILTIN, HIGH); // 启动后关闭板上LED
Serial.begin(9600); // 启动串口通讯
//设置ESP8266工作模式为无线终端模式
WiFi.mode(WIFI_STA);
// 连接WiFi
connectWifi();
// 设置MQTT服务器和端口号
mqttClient.setServer(mqttServer, 1883);
mqttClient.setCallback(receiveCallback);
// 连接MQTT服务器
connectMQTTserver();
}
void loop() {
if (mqttClient.connected()) {
// 如果开发板成功连接服务器
mqttClient.loop(); // 处理信息以及心跳
} else {
// 如果开发板未能成功连接服务器
connectMQTTserver(); // 则尝试连接服务器
}
}
// 连接MQTT服务器并订阅信息
void connectMQTTserver(){
// 根据ESP8266的MAC地址生成客户端ID(避免与其它ESP8266的客户端ID重名)
String clientId = "esp8266-" + WiFi.macAddress();
// 连接MQTT服务器
if (mqttClient.connect(clientId.c_str())) {
Serial.println("MQTT Server Connected.");
Serial.println("Server Address:");
Serial.println(mqttServer);
Serial.println("ClientId: ");
Serial.println(clientId);
subscribeTopic(); // 订阅指定主题
} else {
Serial.print("MQTT Server Connect Failed. Client State:");
Serial.println(mqttClient.state());
delay(5000);
}
}
// 收到信息后的回调函数
void receiveCallback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message Received [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println("");
Serial.print("Message Length(Bytes) ");
Serial.println(length);
if ((char)payload[0] == '1') {
// 如果收到的信息以“1”为开始
digitalWrite(BUILTIN_LED, LOW); // 则点亮LED。
} else {
digitalWrite(BUILTIN_LED, HIGH); // 否则熄灭LED。
}
}
// 订阅指定主题
void subscribeTopic(){
// 建立订阅主题。主题名称以Taichi-Maker-Sub为前缀,后面添加设备的MAC地址。
// 这么做是为确保不同设备使用同一个MQTT服务器测试消息订阅时,所订阅的主题名称不同
String topicString = "Taichi-Maker-Sub-" + WiFi.macAddress()+"/+/data";
char subTopic[topicString.length() + 1];
strcpy(subTopic, topicString.c_str());
// 通过串口监视器输出是否成功订阅主题以及订阅的主题名称
if(mqttClient.subscribe(subTopic)){
Serial.println("Subscrib Topic:");
Serial.println(subTopic);
} else {
Serial.print("Subscribe Fail...");
}
}
// ESP8266连接wifi
void connectWifi(){
WiFi.begin(ssid, password);
//等待WiFi连接,成功连接后输出成功信息
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi Connected!");
Serial.println("");
}
与第一个程序大同小异。
4、使用多级通配符订阅主题
/********************************************************************** 项目名称/Project : 零基础入门学用物联网 程序名称/Program name : subscribe_multi_level_wildcard_ranye 团队/Team : 太极创客团队 / Taichi-Maker (www.taichi-maker.com) 作者/Author : CYNO朔 日期/Date(YYYYMMDD) : 20200813 程序目的/Purpose : 本程序旨在演示ESP8266订阅信息时的多极通配符#应用。 ----------------------------------------------------------------------- 本示例程序为太极创客团队制作的《零基础入门学用物联网》中示例程序。 该教程为对物联网开发感兴趣的朋友所设计和制作。如需了解更多该教程的信息,请参考以下网页: http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-nodemcu-web-client/http-request/ ***********************************************************************/
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
// 设置wifi接入信息(请根据您的WiFi信息进行修改)
const char* ssid = "taichi-maker";
const char* password = "12345678";
const char* mqttServer = "test.ranye-iot.net";
// 如以上MQTT服务器无法正常连接,请前往以下页面寻找解决方案
// http://www.taichi-maker.com/public-mqtt-broker/
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // 设置板上LED引脚为输出模式
digitalWrite(LED_BUILTIN, HIGH); // 启动后关闭板上LED
Serial.begin(9600); // 启动串口通讯
//设置ESP8266工作模式为无线终端模式
WiFi.mode(WIFI_STA);
// 连接WiFi
connectWifi();
// 设置MQTT服务器和端口号
mqttClient.setServer(mqttServer, 1883);
mqttClient.setCallback(receiveCallback);
// 连接MQTT服务器
connectMQTTserver();
}
void loop() {
if (mqttClient.connected()) {
// 如果开发板成功连接服务器
mqttClient.loop(); // 处理信息以及心跳
} else {
// 如果开发板未能成功连接服务器
connectMQTTserver(); // 则尝试连接服务器
}
}
// 连接MQTT服务器并订阅信息
void connectMQTTserver(){
// 根据ESP8266的MAC地址生成客户端ID(避免与其它ESP8266的客户端ID重名)
String clientId = "esp8266-" + WiFi.macAddress();
// 连接MQTT服务器
if (mqttClient.connect(clientId.c_str())) {
Serial.println("MQTT Server Connected.");
Serial.println("Server Address:");
Serial.println(mqttServer);
Serial.println("ClientId: ");
Serial.println(clientId);
subscribeTopic(); // 订阅指定主题
} else {
Serial.print("MQTT Server Connect Failed. Client State:");
Serial.println(mqttClient.state());
delay(5000);
}
}
// 收到信息后的回调函数
void receiveCallback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message Received [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println("");
Serial.print("Message Length(Bytes) ");
Serial.println(length);
if ((char)payload[0] == '1') {
// 如果收到的信息以“1”为开始
digitalWrite(BUILTIN_LED, LOW); // 则点亮LED。
} else {
digitalWrite(BUILTIN_LED, HIGH); // 否则熄灭LED。
}
}
// 订阅指定主题
void subscribeTopic(){
// 建立订阅主题。主题名称以Taichi-Maker-Sub为前缀,后面添加设备的MAC地址。
// 这么做是为确保不同设备使用同一个MQTT服务器测试消息订阅时,所订阅的主题名称不同
String topicString = "Taichi-Maker-Sub-" + WiFi.macAddress()+"/sensor/#";
char subTopic[topicString.length() + 1];
strcpy(subTopic, topicString.c_str());
// 通过串口监视器输出是否成功订阅主题以及订阅的主题名称
if(mqttClient.subscribe(subTopic)){
Serial.println("Subscrib Topic:");
Serial.println(subTopic);
} else {
Serial.print("Subscribe Fail...");
}
}
// ESP8266连接wifi
void connectWifi(){
WiFi.begin(ssid, password);
//等待WiFi连接,成功连接后输出成功信息
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi Connected!");
Serial.println("");
}
与第一个程序大同小异。
边栏推荐
猜你喜欢

宁愿去996也不要待业在家啦!24岁,失业7个月,比上班更惨的,是没班可上

Cvpr2022 | pointdistiller: structured knowledge distillation for efficient and compact 3D detection

平均风向风速计算(单位矢量法)

Consumers pursue the iPhone because its cost performance exceeds that of domestic mobile phones

three. JS domino JS special effect

Canvas particles: mouse following JS effect

Flink learning 5: how it works

Flink Learning 2: Application Scenarios

C语言--职工信息管理系统设计

pytorch 22 8种Dropout方法的简介 及 基于Dropout用4行代码快速实现DropBlock
随机推荐
mmdetection 用yolox训练自己的coco数据集
Oracle/PLSQL: Substr Function
Oracle/PLSQL: Soundex Function
为什么传递SPIF_SENDCHANGE标志SystemParametersInfo会挂起?
three.js多米诺骨牌js特效
mmdetection ValueError: need at least one array to concatenate解决方案
“所有专业都在劝退”,对大学生最友好的竟然是它?
Oracle/PLSQL: Translate Function
Oracle/PLSQL: Translate Function
memcached基础9
Precautions for using sneakemake
memcached基础14
C language -- Design of employee information management system
Cvpr2022 | pointdistiller: structured knowledge distillation for efficient and compact 3D detection
速看!2022年6月编程语言排行榜出炉!第一名太牛啦
Oracle/PLSQL: Cast Function
Installing the Damon database using the command line
YaLM 100B:来自俄罗斯Yandex的1000亿参数开源大模型,允许商业用途
perl语言中 fork()、exec()、waitpid() 、 $? >> 8 组合
Addition, deletion, modification and query of ymal file