MQTT服务端使用的是EMQX开源版本,此处使用docker搭建,docker-compose文件如下:

docker-compose.yaml

version: '3'
services:
  emqx:
    restart: always
    image: emqx/emqx:4.4.3
    container_name: emqx
    ports:
      - 1883:1883
      - 8081:8081
      - 8083:8083
      - 8084:8084
      - 8883:8883
      - 18083:18083

安装完EMQX之后,就可以编写arduino代码了,以下代码参考于EMQX官方文档

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

// WiFi 账号密码
const char *ssid = "Hello-World"; // wifi名称
const char *password = "wifipassword";  // Wifi密码

// MQTT 连接信息
const char *mqtt_broker = "192.168.1.109"; // 上面安装的mqtt(emqx)服务器的ip
const char *topic = "esp8266/test"; // 消息主题,自己指定
const char *mqtt_username = "emqx"; // mqtt 用户名
const char *mqtt_password = "public"; // mqtt 密码
const int mqtt_port = 1883; // mqtt通信端口号

// 继电器脚位,改成自己的开发板的引脚位
#define PIN_ELC 4

WiFiClient espClient;
PubSubClient client(espClient);

void setup() {
    // 设置串口波特率为 115200;
    Serial.begin(115200);
    // 连接 wifi
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.println("Connecting to WiFi..");
    }
    Serial.println("Connected to the WiFi network");
    // 连接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);
        }
    }
    // 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:");
    String msg = String(*payload);
    for (int i = 0; i < length; i++) {
        Serial.print((char) payload[i]);
        //msg += (char) payload[i];
    }
    Serial.println();
    Serial.println("-----------------------");
    Serial.println(msg);
    if(msg=="open"){
      Serial.println("msg: open");
      digitalWrite(PIN_ELC, HIGH);  
    }else if(msg=="close"){
      Serial.println("msg: close");
      digitalWrite(PIN_ELC, LOW);  
    }
}

void loop() {
    client.loop();
}

将代码烧录到开发板之后,打开串口调试工具,可以看到连接wifi和mqtt服务器时打印的信息,随后使用emqx官方提供的MQTT调试工具 MQTT X 客户端连接到上述代码中配置的MQTT服务地址和主题,向主题中推送消息open可以打开继电器连接,推送close可以关闭继电器连接。