项目概述
MQTT(Message Queuing Telemetry Transport)是一种轻量级的消息传递协议,特别适用于低带宽、高延迟或不可靠网络的环境。它被广泛应用于物联网(IoT)设备中,因其高效性和低功耗特性。本项目旨在实现一个基于MQTT协议的嵌入式系统,利用树莓派作为MQTT代理,ESP8266作为客户端,实现传感器数据的发布和订阅。
项目目标
- 实现MQTT协议的基本功能: 连接、发布、订阅、断开。
- 数据传输: 传感器数据通过MQTT进行实时传输。
- 用户界面: 提供简单的Web界面监控传感器数据。
系统设计
硬件设计
- 树莓派:作为MQTT代理,负责接收和转发消息。
- ESP8266:作为客户端,连接到WiFi网络,读取传感器数据并通过MQTT发布。
- 传感器:如DHT11温湿度传感器,用于获取环境数据。
硬件连接示意图
软件设计
- MQTT代理:使用Mosquitto作为MQTT代理服务器。
- 客户端程序:在ESP8266上编写Arduino代码,利用
PubSubClient
库实现MQTT功能。
代码实现
环境准备
-
安装Mosquitto MQTT代理:
sudo apt update sudo apt install mosquitto mosquitto-clients
-
在ESP8266上安装Arduino IDE,并添加ESP8266开发板支持。
树莓派MQTT代理配置
-
启动Mosquitto服务:
sudo systemctl start mosquitto sudo systemctl enable mosquitto
-
测试MQTT代理:
mosquitto_sub -h localhost -t test/topic
ESP8266代码实现
1. 引入库文件
#include <ESP8266WiFi.h> // ESP8266 WiFi库
#include <PubSubClient.h> // MQTT客户端库
// WiFi和MQTT代理的配置信息
const char* ssid = "your_SSID"; // WiFi名称
const char* password = "your_PASSWORD"; // WiFi密码
const char* mqtt_server = "192.168.0.100"; // MQTT代理地址
2. 初始化WiFi和MQTT客户端
WiFiClient espClient; // 创建WiFi客户端
PubSubClient client(espClient); // 创建MQTT客户端
// 连接WiFi
void setup_wifi() {
delay(10);
WiFi.begin(ssid, password); // 连接到WiFi
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
}
// 连接MQTT代理
void reconnect() {
while (!client.connected()) {
if (client.connect("ESP8266Client")) { // 使用唯一ID连接
client.subscribe("sensor/data"); // 订阅主题
} else {
delay(5000);
}
}
}
3. 读取传感器数据并发布
#include <DHT.h> // 引入DHT传感器库
#define DHTPIN 2 // DHT传感器连接引脚
#define DHTTYPE DHT11 // 定义传感器类型
DHT dht(DHTPIN, DHTTYPE); // 初始化DHT传感器
void setup() {
Serial.begin(115200);
setup_wifi(); // 设置WiFi
client.setServer(mqtt_server, 1883); // 设置MQTT代理
dht.begin(); // 启动DHT传感器
}
void loop() {
if (!client.connected()) { // 如果未连接,尝试重新连接
reconnect();
}
client.loop(); // 保持MQTT连接
float h = dht.readHumidity(); // 读取湿度
float t = dht.readTemperature(); //读取温度
// 检查读取是否成功
if (isnan(h) || isnan(t)) {
Serial.println("读取失败!");
return; // 如果读取失败,则返回
}
// 将数据格式化为字符串
String payload = "温度: " + String(t) + " °C, 湿度: " + String(h) + " %";
// 发布传感器数据到MQTT主题
client.publish("sensor/data", payload.c_str());
// 打印到串口监视器
Serial.println(payload);
// 每10秒发布一次数据
delay(10000);
}
代码结构说明
- 头文件:引入了ESP8266的WiFi库和MQTT客户端库,以及DHT传感器库。
- WiFi连接:
setup_wifi()
函数用于连接到指定的WiFi网络,reconnect()
函数确保MQTT客户端能够连接到MQTT代理。 - 循环函数:在
loop()
中,首先检查MQTT连接状态,然后读取DHT传感器的数据,发布到"sensor/data"
主题,并每隔10秒发布一次数据。
整个代码实现
以下是完整的代码实现,方便读者参考:
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
const char* ssid = "your_SSID"; // WiFi名称
const char* password = "your_PASSWORD"; // WiFi密码
const char* mqtt_server = "192.168.0.100"; // MQTT代理地址
WiFiClient espClient;
PubSubClient client(espClient);
#define DHTPIN 2 // DHT传感器连接引脚
#define DHTTYPE DHT11 // 定义传感器类型
DHT dht(DHTPIN, DHTTYPE); // 初始化DHT传感器
// 连接WiFi
void setup_wifi() {
delay(10);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
}
// 连接MQTT代理
void reconnect() {
while (!client.connected()) {
if (client.connect("ESP8266Client")) {
client.subscribe("sensor/data");
} else {
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
dht.begin();
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(h) || isnan(t)) {
Serial.println("读取失败!");
return;
}
String payload = "温度: " + String(t) + " °C, 湿度: " + String(h) + " %";
client.publish("sensor/data", payload.c_str());
Serial.println(payload);
delay(10000);
}
项目总结
本项目实现了一个基于MQTT协议的嵌入式系统,利用树莓派作为MQTT代理,ESP8266作为客户端发布温湿度数据。通过MQTT协议,设备能够在低功耗和低带宽的环境下高效地进行数据传输。这一系统不仅可以用于家庭环境监控,也可以扩展到工业自动化、农业监测等多个领域。
项目亮点
- 高效的数据传输:MQTT协议的轻量级特性使得设备能够在不稳定的网络环境中保持连接。
- 扩展性:可以添加更多的传感器和设备,支持更多主题的发布和订阅。
- 易于监控:通过串口监视器,可以实时查看传感器数据。
参考文献
- MQTT.org. (n.d.). MQTT - The Standard for IoT Messaging. Retrieved from https://mqtt.org
- Eclipse Mosquitto. (n.d.). Mosquitto: an open source MQTT broker. Retrieved from https://mosquitto.org