• 学习太极创客 — MQTT(八)ESP8266订阅MQTT主题


    视频链接:https://www.bilibili.com/video/BV1Wz4y1k7Fs/?spm_id_from=333.788.recommend_more_video.-1&vd_source=b91967c499b23106586d7aa35af46413

    资料链接:http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-tuttorial/mqtt-tutorial/esp8266-subscribe-mqtt/

    在这里插入图片描述

    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(""); 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127

    程序运行结果如下,
    在这里插入图片描述

    下面再来尝试使用 MQTT.fx 这个软件向 Taichi-Maker-Sub-EC:FA:BC:40:6F:5B 这个主题发布信息,同时观察串口监视器的输出。

    在这里插入图片描述
    在这里插入图片描述
    当 LED ON 时,ESP8266 的板载 LED 也被点亮。

    下面,来讲解下程序的重点。

      // 设置MQTT订阅回调函数
      mqttClient.setCallback(receiveCallback);
    
    • 1
    • 2

    此处的 ESP8266 开发板的作用是订阅 MQTT 主题,它在订阅 MQTT 主题以后,每当收到该主题信息后,他就会调用一个回调函数 receiveCallback ,以此来处理收到的信息。

    2、订阅指定主题

    // 通过串口监视器输出是否成功订阅主题以及订阅的主题名称
      if(mqttClient.subscribe(subTopic)){
        Serial.println("Subscrib Topic:");
        Serial.println(subTopic);
      } else {
        Serial.print("Subscribe Fail...");
      }  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    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");
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    注意三个参数,三个参数是固定格式。

    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(""); 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137

    运行代码如下,
    在这里插入图片描述
    下面再来尝试使用 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(""); 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125

    与第一个程序大同小异。

    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(""); 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124

    与第一个程序大同小异。

  • 相关阅读:
    图解LeetCode——面试题 17.19. 消失的两个数字(难度:困难)
    【STM32】OLED
    vr航空博物馆综合展馆趣味VR科普体验
    Android Service异常销毁处理(START_NOT_STICKY、START_STICKY和START_REDELIVER_INTENT)
    [附源码]java毕业设计“拥抱爱心”公益网站管理系统
    PyG学习 - DATA(torch_geometric.data.Data )
    JAVA多线程
    34.【C/C++ string大汇总,不看定后悔】
    springboot的缓存和redis缓存,入门级别教程
    毕设-基于SpringBoot西餐厅点餐系统
  • 原文地址:https://blog.csdn.net/xuechanba/article/details/125471723