一、MQTT服务器安装

要在 Ubuntu 中安装 MQTT 服务器,您可以按照以下步骤进行操作:

1. 打开终端运行以下命令:

   sudo apt update

3. 安装 Mosquitto,它是一个流行的 MQTT 服务器实现。运行以下命令进行安装:

sudo apt install mosquitto

4. 安装 Mosquitto 的客户端工具,以便进行测试和管理。运行以下命令进行安装:

sudo apt install mosquitto-clients

5. 安装完成后,Mosquitto MQTT 服务器将自动启动,并在后台运行。

6. 您可以使用以下命令检查 Mosquitto 服务器的运行状态:

   sudo systemctl status mosquitto

   如果服务器正在运行,将显示 "active (running)"如下图:

7. 默认情况下,Mosquitto 服务器监听 TCP 端口 1883,用于 MQTT 通信。您可以使用其他 MQTT 客户端工具或代码连接到服务器并进行通信。还可以使用 Mosquitto 的配置文件 `/etc/mosquitto/mosquitto.conf` 进行进一步的自定义配置,例如更改监听端口、启用身份验证等。这里不做展开讲解。

二、MQTT.fx安装及使用

MQTT.fx是一款基于Eclipse Paho,使用Java语言编写的MQTT客户端工具。支持通过Topic订阅和发布消息,用来前期和物理云平台调试非常方便。

访问官网下载即可:www.softblade.de安装过程全程下一步即可。

安装完成之后打开软件,如下图配置MQTT服务器连接。

点击右下角加号,在Newprofile中Broker Address填写旭日x3派的ip地址,点击右下角 OK。

点击Connect连接MQTT服务器,可以看到右侧灰色圆圈变绿

在Publish选项卡中输入话题名light发布话题,并在下方空白区域输入话题内容,(1开灯、0关灯)

在Subscribe可以查看话题内容发布情况

三、ESP32接线及程序编写

 接线:LED灯正极接5号引脚,负极接GND,所以希望实现远程开关灯只需实现通过MQTT话题控制5号引脚电平高低即可。

ESP32完整程序:

#include <WiFi.h>
#include <PubSubClient.h>

// WiFi网络参数
const char* ssid = "809";
const char* password = "809809809";

// MQTT服务器参数
const char* mqttServer = "192.168.3.123";
const int mqttPort = 1883;
const char* mqttTopic = "light";

// 引脚配置
const int ledPin = 5;

// WiFi客户端和MQTT客户端
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);

// MQTT消息回调函数
void mqttCallback(char* topic, byte* payload, unsigned int length) {
  // 将payload转换为字符串
  char receivedMessage = (char)payload[0];

  // 根据收到的消息设置引脚电平
  if (receivedMessage == '1') {
    digitalWrite(ledPin, HIGH);
  } else if (receivedMessage == '0') {
    digitalWrite(ledPin, LOW);
  }
}

// 连接到WiFi网络
void connectToWiFi() {
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("\nConnected to WiFi");
}

// 连接到MQTT服务器
void connectToMQTT() {
  mqttClient.setServer(mqttServer, mqttPort);
  mqttClient.setCallback(mqttCallback);
  
  while (!mqttClient.connected()) {
    if (mqttClient.connect("ESP32Client")) {
      Serial.println("Connected to MQTT server");
      mqttClient.subscribe(mqttTopic);
    } else {
      Serial.print("Failed to connect to MQTT server, rc=");
      Serial.print(mqttClient.state());
      Serial.println(" Retrying in 5 seconds...");
      delay(5000);
    }
  }
}

// 初始化引脚
void setup() {
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);

  connectToWiFi();
  connectToMQTT();
}

// 主循环
void loop() {
  if (!mqttClient.connected()) {
    connectToMQTT();
  }
  mqttClient.loop();
}

程序解析:

    引入所需的库:

    #include <WiFi.h>
    #include <PubSubClient.h>



    这里引入了 `WiFi` 库和 `PubSubClient` 库,用于处理 WiFi 网络连接和 MQTT 通信。

    定义 WiFi 和 MQTT 参数:

    const char* ssid = "809";
    const char* password = "809809809";
    const char* mqttServer = "192.168.3.123";
    const int mqttPort = 1883;
    const char* mqttTopic = "light";


    这些变量存储了连接到 WiFi 网络所需的 SSID 和密码,以及 MQTT 服务器的 IP 地址、端口和订阅的 MQTT 话题。

    定义引脚配置:

    const int ledPin = 5;

    这里定义了一个整数变量 `ledPin`,用于存储连接 LED 灯的引脚号。

    创建 WiFi 客户端和 MQTT 客户端实例:

    WiFiClient wifiClient;
    PubSubClient mqttClient(wifiClient);

    这里创建了一个 WiFi 客户端对象 `wifiClient` 和一个 MQTT 客户端对象 `mqttClient`。

    定义 MQTT 消息回调函数:

    void mqttCallback(char* topic, byte* payload, unsigned int length) {
      // 将 payload 转换为字符串
      char receivedMessage = (char)payload[0];
    
      // 根据收到的消息设置引脚电平
      if (receivedMessage == '1') {
        digitalWrite(ledPin, HIGH);
      } else if (receivedMessage == '0') {
        digitalWrite(ledPin, LOW);
      }
    }


    这个回调函数会在接收到 MQTT 消息时被调用。它将接收到的消息转换为字符,并根据消息的内容设置引脚 `ledPin` 的电平状态。

    定义连接到 WiFi 网络的函数:

    void connectToWiFi() {
      WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED) {
        delay(1000);
        Serial.print(".");
      }
      Serial.println("\nConnected to WiFi");
    }


    这个函数使用提供的 SSID 和密码连接到指定的 WiFi 网络,并等待连接成功。

    定义连接到 MQTT 服务器的函数:

    void connectToMQTT() {
      mqttClient.setServer(mqttServer, mqttPort);
      mqttClient.setCallback(mqttCallback);
      
      while (!mqttClient.connected()) {
        if (mqttClient.connect("ESP32Client")) {
          Serial.println("Connected to MQTT server");
          mqttClient.subscribe(mqttTopic);
        } else {
          Serial.print("Failed to connect to MQTT server, rc=");
          Serial.print(mqttClient.state());
          Serial.println(" Retrying in 5 seconds...");
          delay(5000);
        }
      }
    }


    这个函数通过调用 `setServer` 方法设置 MQTT 服务器的地址和端口,然后将回调函数 `mqttCallback` 设置为处理接收到的消息。接着,它尝试连接到 MQTT 服务器,并在连接成功后订阅指定的 MQTT 话题。

    初始化引脚和连接到 WiFi 和 MQTT 服务器:

    void setup() {
      Serial.begin(115200);
      pinMode(ledPin, OUTPUT);
    
      connectToWiFi();
      connectToMQTT();
    }


    这个函数在启动时被调用,它初始化串口通信,并将引脚 `ledPin` 设置为输出模式。然后,它调用 `connectToWiFi` 和 `connectToMQTT` 函数以连接到 WiFi 和 MQTT 服务器。

    主循环:

    void loop() {
      if (!mqttClient.connected()) {
        connectToMQTT();
      }
      mqttClient.loop();
    }


    这个函数在主循环中被调用。它检查 MQTT 客户端是否已连接,如果未连接,则调用 `connectToMQTT` 函数进行重新连接。然后,它调用 `mqttClient.loop()` 来处理 MQTT 客户端的网络通信。

    四、结语

    经过MQTT服务器的搭建、网络配置、ESP32程序编写,我们已经完成了一个基本的物联网台灯的主要实现流程。我们通过MQTT.fx发布MQTT话题内容,通过旭日X3派搭建MQTT服务器完成话题内容在终端之间的通信。同样的,基于上述程序进行一些改动我们也可以实现传感器信息收集通过MQTT服务器,实现一些智能花盆,环境监测系统之类简单的物联网系统。再进一步也行可以与ROS相互联系,做机器人的物联网系统。