ESP8266 连接到免费的公共 MQTT 服务器

MQTT 是轻量级的、灵活的物联网消息交换和数据传递协议,致力于为 IoT 开发人员实现灵活性与硬件/网络资源的平衡。

ESP8266 提供了⼀套⾼度集成的 Wi-Fi SoC 解决⽅案,其低功耗、 紧凑设计和⾼稳定性可以满⾜⽤户的需求。ESP8266 拥有完整的且⾃成体系的 Wi-Fi ⽹络功能,既能够独⽴应⽤,也可以作为从机搭载于其他主机 MCU 运⾏。

在此项目中我们将实现 ESP8266 连接到 EMQ X MQTT Cloud 运营和维护的 免费公共 MQTT 服务器,并使用 Arduino IDE 来对 ESP8266 进行编程。 EMQ X Cloud 是由 EMQ 推出的安全的 MQTT 物联网云服务平台,它提供一站式运维代管、独有隔离环境的 MQTT 5.0 接入服务。

所需物联网组件

  • ESP8266
  • Arduino IDE
  • MQTT X: 优雅的跨平台 MQTT 5.0 客户端工具
  • 免费的公共 MQTT 服务器
    • Broker: broker.emqx.io
    • TCP Port: 1883
    • Websocket Port: 8083

ESP8266 Pub/Sub 示意图

project.png

ESP8266 代码编写

  1. 首先我们将导入 ESP8266WiFiPubSubClient 库,ESP8266WiFi 库能够将 ESP8266 连接到 Wi-Fi 网络,PubSubClient 库能使 ESP8266 连接到 MQTT 服务器发布消息及订阅主题。

    #include <ESP8266WiFi.h>
    #include <PubSubClient.h>
    
  2. 设置 Wi-Fi 名称和密码,以及 MQTT 服务器连接地址和端口

    // WiFi
    const char *ssid = "mousse"; // Enter your WiFi name
    const char *password = "qweqweqwe";  // Enter WiFi password
    
    // MQTT Broker
    const char *mqtt_broker = "broker.emqx.io";
    const char *topic = "esp8266/test";
    const char *mqtt_username = "emqx";
    const char *mqtt_password = "public";
    const int mqtt_port = 1883;
    
  3. 打开一个串行连接,以便于输出程序的结果并且连接到 Wi-Fi 网络

    // Set software serial baud to 115200;
    Serial.begin(115200);
    // connecting to a WiFi network
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
       delay(500);
       Serial.println("Connecting to WiFi..");
    }
    
  4. 设置 MQTT 服务器,并编写回调函数,同时将连接信息打印到串口监视器上

    client.setServer(mqtt_broker, mqtt_port);
    client.setCallback(callback);
    while (!client.connected()) {
       String client_id = "esp8266-client-";
       client_id += String(WiFi.macAddress());
       Serial.printf("The client %s connects to the public mqtt broker\n", client_id.c_str());
       if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {
     Serial.println("Public emqx mqtt broker connected");
       } else {
           Serial.print("failed with state ");
           Serial.print(client.state());
           delay(2000);
       }
    }
    
    void callback(char *topic, byte *payload, unsigned int length) {
       Serial.print("Message arrived in topic: ");
       Serial.println(topic);
       Serial.print("Message:");
       for (int i = 0; i < length; i++) {
           Serial.print((char) payload[i]);
       }
       Serial.println();
       Serial.println("-----------------------");
    }
    
  5. MQTT 服务器连接成功后,ESP8266 将向 MQTT 服务器发布消息和订阅主题

    // publish and subscribe
    client.publish(topic, "hello emqx");
    client.subscribe(topic);
    
  6. 将主题名称打印到串行端口,然后打印收到消息的每个字节

    void callback(char *topic, byte *payload, unsigned int length) {
       Serial.print("Message arrived in topic: ");
       Serial.println(topic);
       Serial.print("Message:");
       for (int i = 0; i < length; i++) {
           Serial.print((char) payload[i]);
       }
       Serial.println();
       Serial.println("-----------------------");
    }
    
  7. 完整代码

    #include <ESP8266WiFi.h>
    #include <PubSubClient.h>
    
    // WiFi
    const char *ssid = "mousse"; // Enter your WiFi name
    const char *password = "qweqweqwe";  // Enter WiFi password
    
    // MQTT Broker
    const char *mqtt_broker = "broker.emqx.io";
    const char *topic = "esp8266/test";
    const char *mqtt_username = "emqx";
    const char *mqtt_password = "public";
    const int mqtt_port = 1883;
    
    WiFiClient espClient;
    PubSubClient client(espClient);
    
    void setup() {
       // Set software serial baud to 115200;
       Serial.begin(115200);
       // connecting to a WiFi network
       WiFi.begin(ssid, password);
       while (WiFi.status() != WL_CONNECTED) {
           delay(500);
           Serial.println("Connecting to WiFi..");
       }
       Serial.println("Connected to the WiFi network");
       //connecting to a mqtt broker
       client.setServer(mqtt_broker, mqtt_port);
       client.setCallback(callback);
       while (!client.connected()) {
           String client_id = "esp8266-client-";
           client_id += String(WiFi.macAddress());
           Serial.printf("The client %s connects to the public mqtt broker\n", client_id.c_str());
           if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {
               Serial.println("Public emqx mqtt broker connected");
           } else {
               Serial.print("failed with state ");
               Serial.print(client.state());
               delay(2000);
           }
       }
       // publish and subscribe
       client.publish(topic, "hello emqx");
       client.subscribe(topic);
    }
    
    void callback(char *topic, byte *payload, unsigned int length) {
       Serial.print("Message arrived in topic: ");
       Serial.println(topic);
       Serial.print("Message:");
       for (int i = 0; i < length; i++) {
           Serial.print((char) payload[i]);
       }
       Serial.println();
       Serial.println("-----------------------");
    }
    
    void loop() {
       client.loop();
    }
    

运行和测试

  1. 请使用 Arduino IDE 将完整代码上传到 ESP8266,并打开串口监视器

    esp_con.png

  2. 建立 MQTT X 客户端 与 MQTT 服务器的连接, 并向 ESP8266 发送消息

    mqttx_pub.png

  3. 在串口监视器查看 ESP8266 接收到的消息

    esp_msg.png

总结

至此,我们已成功使 ESP8266 连接到 EMQ X Cloud 提供的公共 MQTT 服务器。 在本项目中我们简单的将 ESP8266 连接到 MQTT 服务器,这只是 ESP8266 较为基础的能力之一,ESP8266 其实还能与各类物联网传感器相连,并将传感器数据上报至 MQTT 服务器。

接下来我们将会陆续发布更多关于物联网开发及 ESP8266 的相关文章,敬请关注。

为流式数据存储和实时处理而生的流数据库

全托管的 MQTT 云服务,开始 180 天免费试用

推荐阅读

Python MQTT 异步框架 —— HBMQTT

本文我们将演示如何使用 Python MQTT 异步框架 - HBMQTT,轻松实现一个具备 MQTT 发布、订阅功能的异步 Demo。

MQTT 和 CoAP 在 EMQ X 世界的一次「约会」

本文将向你展示,MQTT 客户端和 CoAP 客户端,在 EMQ X World 的一次「约会」。

Haskell 中的流处理 - Open Day 回顾

HStreamDB 团队于上周日举办了线上 Open Day,HStreamDB CTO 韩冬在会中与大家分享了有关 Haskell 中流处理解决方案的一些思考。