1695浏览
查看: 1695|回复: 0

[讨论] ESP8266 采集 DHT11 和 DS18B20 温湿度数据 MQTT 上传至 Home Ass...

[复制链接]
本帖最后由 无垠的广袤 于 2025-4-14 14:43 编辑

ESP8266 采集 DHT11 和 DS18B20 温湿度数据 MQTT 上传至 Home Assistant

本文介绍了 ESP8266 开发板实现 DHT11 温湿度传感器和 DS18B20 温度传感器实现远程温度监测,通过 MQTT 协议上传至 EMQX 平台,发送 JSON 代码实现 HomeAssistant 智能家居平台数据收集和历史数据查看等功能。

硬件平台

开发板基于 ESP-12E/12F 设计,管脚功能示意图如下
ESP8266 采集 DHT11 和 DS18B20 温湿度数据 MQTT 上传至 Home Ass...图1

实物图
ESP8266 采集 DHT11 和 DS18B20 温湿度数据 MQTT 上传至 Home Ass...图2
原理图
ESP8266 采集 DHT11 和 DS18B20 温湿度数据 MQTT 上传至 Home Ass...图3

MQTT

消息队列遥测传输协议(Message Queuing Telemetry Transport,MQTT)是一种基于发布/订阅(publish/subscribe)模式的轻量级通讯协议。

Docker
Docker 是一个开源的应用容器引擎,它允许开发者将应用及其依赖打包到一个轻量级、可移植的容器中,可以在任何流行操作系统中发布和运行。

安装 Docker Desktop
下载和安装 Docker Desktop .

EMQX
EMQX 是一款完全开源,高度可伸缩,高可用的分布式MQTT 消息服务器。

部署流程
  • 运行以下命令获取 Docker 镜像:
    1. docker pull emqx/emqx:5.8.6
    复制代码

  • 运行以下命令启动 Docker 容器。
    1. docker run -d --name emqx -p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 emqx/emqx:5.8.6
    复制代码

点击 EMQX 容器后的端口链接,登录 EMQX 后台,初始账号和密码分别为 admin 和 public

  • 依次打开 访问控制 - 客户端认证 - 创建 - Password-Based - 内置数据库 - (默认配置)- 创建 ;
  • 用户管理 - 新建用户 - 自定义用户名和密码;

回到平台主界面,可观察节点和连接数目等信息

Home Assistant
Home Assistant ,简称 HA,是一款基于 Python 的智能家居开源系统,支持众多品牌的智能家居设备,可以轻松实现硬件物联网、自动化等。

Docker 部署 Home Assistant 的主要流程

部署流程
下载 Home Assistant 镜像文件
硬盘根目录新建文件夹 homeassistant ,解压 HA 镜像文件,得到 docker-compose.yml ;
当前目录下打开命令行终端,执行安装指令
  1. cd C:\homeassistant
  2. docker-compose.yml
  3. docker-compose up
复制代码

浏览器输入 http://homeassistant:8123/ 即可进入 Home Assistant 系统界面

添加 MQTT 集成
依次点击 设置 - 设备与服务 - 添加集成 - 搜索 MQTT - 填写代理信息;

创建成功后,可在 设备与服务 选项下看到 MQTT 应用图标;

根据开发板蓝牙发送的信息格式,配置 YAML 参数

打开 Home Assistant 安装根目录下的 configuration.yaml 文件,并添加如下代码

  1. mqtt:
  2.   sensor:
  3.     - name: "Temperature"
  4.       state_topic: "home/sensor/"
  5.       suggested_display_precision: 2
  6.       unit_of_measurement: "C"
  7.       value_template: "{{ value_json.temperature }}"
  8.     - name: "Humidity"
  9.       state_topic: "home/sensor/"
  10.       suggested_display_precision: 2
  11.       unit_of_measurement: "%"
  12.       value_template: "{{ value_json.humidity }}"
复制代码

需要注意主题 state_topic 和 value_template 的定义。

开发者工具 界面 重新加载 YAML 所有配置 并刷新浏览器界面,即可看到传感器选项。

DHT11

采集 DHT11 温湿度数据并通过 MQTT 联网上传至 Home Assistant 智能家居平台;

Arduino Code
  1. #include <ESP8266WiFi.h>
  2. #include <PubSubClient.h>
  3. #include <ArduinoJson.h>
  4. #include <DHT.h>
  5. // WiFi Configuration
  6. const char* ssid = "xxx";
  7. const char* password = "xxx";
  8. // MQTT Configuration
  9. const char* mqtt_server = "192.168.1.121";
  10. const int mqtt_port = 1883;
  11. const char* mqtt_user = "admin";
  12. const char* mqtt_password = "admin";
  13. // Device Configuration
  14. const char* device_name = "esp8266_dht11";
  15. const char* device_id = "livingroom_sensor";
  16. // Topics
  17. const char* state_topic = "home/sensor/";
  18. const char* temp_config_topic = "home/sensor/";
  19. const char* hum_config_topic = "home/sensor/";
  20. // DHT Sensor
  21. #define DHTPIN 5
  22. #define DHTTYPE DHT11
  23. DHT dht(DHTPIN, DHTTYPE);
  24. WiFiClient espClient;
  25. PubSubClient client(espClient);
  26. void setup_wifi() {
  27.   delay(10);
  28.   Serial.println();
  29.   Serial.print("Connecting to ");
  30.   Serial.println(ssid);
  31.   WiFi.begin(ssid, password);
  32.   while (WiFi.status() != WL_CONNECTED) {
  33.     delay(500);
  34.     Serial.print(".");
  35.   }
  36.   Serial.println("");
  37.   Serial.println("WiFi connected");
  38.   Serial.println("IP address: ");
  39.   Serial.println(WiFi.localIP());
  40. }
  41. void reconnect() {
  42.   while (!client.connected()) {
  43.     Serial.print("Attempting MQTT connection...");
  44.     if (client.connect(device_name, mqtt_user, mqtt_password)) {
  45.       Serial.println("connected");
  46.       // Send Home Assistant auto-discovery config
  47.       sendAutoDiscoveryConfig();
  48.     } else {
  49.       Serial.print("failed, rc=");
  50.       Serial.print(client.state());
  51.       Serial.println(" try again in 5 seconds");
  52.       delay(5000);
  53.     }
  54.   }
  55. }
  56. void sendAutoDiscoveryConfig() {
  57.   // Configuration for temperature sensor
  58.   DynamicJsonDocument temp_config(512);
  59.   temp_config["name"] = "Living Room Temperature";
  60.   temp_config["device_class"] = "temperature";
  61.   temp_config["state_topic"] = state_topic;
  62.   temp_config["unit_of_measurement"] = "°C";
  63.   temp_config["value_template"] = "{{ value_json.temperature }}";
  64.   temp_config["unique_id"] = String(device_id) + "_temperature";
  65.   temp_config["device"]["identifiers"] = device_id;
  66.   temp_config["device"]["name"] = "Living Room Sensor";
  67.   temp_config["device"]["manufacturer"] = "DIY";
  68.   temp_config["device"]["model"] = "ESP8266+DHT11";
  69.   
  70.   char temp_config_message[512];
  71.   serializeJson(temp_config, temp_config_message);
  72.   client.publish(temp_config_topic, temp_config_message, true);
  73.   // Configuration for humidity sensor
  74.   DynamicJsonDocument hum_config(512);
  75.   hum_config["name"] = "Living Room Humidity";
  76.   hum_config["device_class"] = "humidity";
  77.   hum_config["state_topic"] = state_topic;
  78.   hum_config["unit_of_measurement"] = "%";
  79.   hum_config["value_template"] = "{{ value_json.humidity }}";
  80.   hum_config["unique_id"] = String(device_id) + "_humidity";
  81.   hum_config["device"] = temp_config["device"]; // Same device info
  82.   
  83.   char hum_config_message[512];
  84.   serializeJson(hum_config, hum_config_message);
  85.   client.publish(hum_config_topic, hum_config_message, true);
  86. }
  87. void setup() {
  88.   Serial.begin(115200);
  89.   dht.begin();
  90.   setup_wifi();
  91.   client.setServer(mqtt_server, mqtt_port);
  92. }
  93. void loop() {
  94.   if (!client.connected()) {
  95.     reconnect();
  96.   }
  97.   client.loop();
  98.   delay(2000); // Wait between measurements
  99.   float h = dht.readHumidity();
  100.   float t = dht.readTemperature();
  101.   if (isnan(h) || isnan(t)) {
  102.     Serial.println("Failed to read from DHT sensor!");
  103.     return;
  104.   }
  105.   // Create JSON payload
  106.   DynamicJsonDocument doc(256);
  107.   doc["temperature"] = t;
  108.   doc["humidity"] = h;
  109.   char json_string[256];
  110.   serializeJson(doc, json_string);
  111.   
  112.   Serial.print("Publishing: ");
  113.   Serial.println(json_string);
  114.   
  115.   client.publish(state_topic, json_string, true);
  116. }
复制代码


效果
ESP8266 采集 DHT11 和 DS18B20 温湿度数据 MQTT 上传至 Home Ass...图4
ESP8266 采集 DHT11 和 DS18B20 温湿度数据 MQTT 上传至 Home Ass...图5
ESP8266 采集 DHT11 和 DS18B20 温湿度数据 MQTT 上传至 Home Ass...图6
DS18B20
采集 DS18B20 温度数据并通过 MQTT 联网上传至 Home Assistant 智能家居平台;

Arduino Code
  1. #include <ESP8266WiFi.h>
  2. #include <PubSubClient.h>
  3. #include <ArduinoJson.h>
  4. #include <OneWire.h>
  5. #include <DallasTemperature.h>
  6. // WiFi Configuration
  7. const char* ssid = "B228-230";
  8. const char* password = "LPSerB228";
  9. // MQTT Configuration
  10. const char* mqtt_server = "192.168.1.121";
  11. const int mqtt_port = 1883;
  12. const char* mqtt_user = "LJL";
  13. const char* mqtt_password = "4421989g";
  14. // Device Configuration
  15. const char* device_name = "esp8266_ds18b20";
  16. const char* device_id = "water_tank_sensor";
  17. // Topics
  18. const char* state_topic = "home/sensor/";
  19. const char* temp_config_topic = "home/sensor/";
  20. // DS18B20 Setup
  21. #define ONE_WIRE_BUS 5
  22. OneWire oneWire(ONE_WIRE_BUS);
  23. DallasTemperature sensors(&oneWire);
  24. WiFiClient espClient;
  25. PubSubClient client(espClient);
  26. void setup_wifi() {
  27.   delay(10);
  28.   Serial.println();
  29.   Serial.print("Connecting to ");
  30.   Serial.println(ssid);
  31.   WiFi.begin(ssid, password);
  32.   while (WiFi.status() != WL_CONNECTED) {
  33.     delay(500);
  34.     Serial.print(".");
  35.   }
  36.   Serial.println("");
  37.   Serial.println("WiFi connected");
  38.   Serial.println("IP address: ");
  39.   Serial.println(WiFi.localIP());
  40. }
  41. void reconnect() {
  42.   while (!client.connected()) {
  43.     Serial.print("Attempting MQTT connection...");
  44.     if (client.connect(device_name, mqtt_user, mqtt_password)) {
  45.       Serial.println("connected");
  46.       // Send Home Assistant auto-discovery config
  47.       sendAutoDiscoveryConfig();
  48.     } else {
  49.       Serial.print("failed, rc=");
  50.       Serial.print(client.state());
  51.       Serial.println(" try again in 5 seconds");
  52.       delay(5000);
  53.     }
  54.   }
  55. }
  56. void sendAutoDiscoveryConfig() {
  57.   // Configuration for temperature sensor
  58.   DynamicJsonDocument temp_config(512);
  59.   temp_config["name"] = "Water Tank Temperature";
  60.   temp_config["device_class"] = "temperature";
  61.   temp_config["state_topic"] = state_topic;
  62.   temp_config["unit_of_measurement"] = "°C";
  63.   temp_config["value_template"] = "{{ value_json.temperature }}";
  64.   temp_config["unique_id"] = String(device_id) + "_temperature";
  65.   temp_config["device"]["identifiers"] = device_id;
  66.   temp_config["device"]["name"] = "Water Tank Sensor";
  67.   temp_config["device"]["manufacturer"] = "DIY";
  68.   temp_config["device"]["model"] = "ESP8266+DS18B20";
  69.   
  70.   char temp_config_message[512];
  71.   serializeJson(temp_config, temp_config_message);
  72.   client.publish(temp_config_topic, temp_config_message, true);
  73. }
  74. void setup() {
  75.   Serial.begin(115200);
  76.   sensors.begin();
  77.   setup_wifi();
  78.   client.setServer(mqtt_server, mqtt_port);
  79. }
  80. void loop() {
  81.   if (!client.connected()) {
  82.     reconnect();
  83.   }
  84.   client.loop();
  85.   delay(2000); // Wait between measurements
  86.   sensors.requestTemperatures();
  87.   float t = sensors.getTempCByIndex(0);
  88.   // Check if reading is valid
  89.   if(t == DEVICE_DISCONNECTED_C) {
  90.     Serial.println("Error: Could not read temperature data");
  91.     return;
  92.   }
  93.   // Create JSON payload
  94.   DynamicJsonDocument doc(128);
  95.   doc["temperature"] = t;
  96.   char json_string[128];
  97.   serializeJson(doc, json_string);
  98.   
  99.   Serial.print("Temperature: ");
  100.   Serial.print(t);
  101.   Serial.println(" °C");
  102.   Serial.print("Publishing: ");
  103.   Serial.println(json_string);
  104.   
  105.   client.publish(state_topic, json_string, true);
  106. }
复制代码


OLED显示
  1. #include <ESP8266WiFi.h>
  2. #include <PubSubClient.h>
  3. #include <ArduinoJson.h>
  4. #include <OneWire.h>
  5. #include <DallasTemperature.h>
  6. // OLED
  7. #include <Wire.h>
  8. #include <Adafruit_GFX.h>
  9. #include <Adafruit_SSD1306.h>
  10. #include <Adafruit_Sensor.h>
  11. #define SCREEN_WIDTH 128 // OLED display width, in pixels
  12. #define SCREEN_HEIGHT 64 // OLED display height, in pixels
  13. #define OLED_SDA 02                       // SDA引脚,gpio2(D4)
  14. #define OLED_SCL 14                       // SCL引脚,gpio14(D5)
  15. // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
  16. Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
  17. // WiFi Configuration
  18. const char* ssid = "B228-230";
  19. const char* password = "LPSerB228";
  20. // MQTT Configuration
  21. const char* mqtt_server = "192.168.1.121";
  22. const int mqtt_port = 1883;
  23. const char* mqtt_user = "LJL";
  24. const char* mqtt_password = "4421989g";
  25. // Device Configuration
  26. const char* device_name = "esp8266_ds18b20";
  27. const char* device_id = "water_tank_sensor";
  28. // Topics
  29. const char* state_topic = "home/sensor/";
  30. const char* temp_config_topic = "home/sensor/";
  31. // DS18B20 Setup
  32. #define ONE_WIRE_BUS 5
  33. OneWire oneWire(ONE_WIRE_BUS);
  34. DallasTemperature sensors(&oneWire);
  35. WiFiClient espClient;
  36. PubSubClient client(espClient);
  37. void setup_wifi() {
  38.   delay(10);
  39.   Serial.println();
  40.   Serial.print("Connecting to ");
  41.   Serial.println(ssid);
  42.   WiFi.begin(ssid, password);
  43.   while (WiFi.status() != WL_CONNECTED) {
  44.     delay(500);
  45.     Serial.print(".");
  46.   }
  47.   Serial.println("");
  48.   Serial.println("WiFi connected");
  49.   Serial.println("IP address: ");
  50.   Serial.println(WiFi.localIP());
  51. }
  52. void reconnect() {
  53.   while (!client.connected()) {
  54.     Serial.print("Attempting MQTT connection...");
  55.     if (client.connect(device_name, mqtt_user, mqtt_password)) {
  56.       Serial.println("connected");
  57.       // Send Home Assistant auto-discovery config
  58.       sendAutoDiscoveryConfig();
  59.     } else {
  60.       Serial.print("failed, rc=");
  61.       Serial.print(client.state());
  62.       Serial.println(" try again in 5 seconds");
  63.       delay(5000);
  64.     }
  65.   }
  66. }
  67. void sendAutoDiscoveryConfig() {
  68.   // Configuration for temperature sensor
  69.   DynamicJsonDocument temp_config(512);
  70.   temp_config["name"] = "Water Tank Temperature";
  71.   temp_config["device_class"] = "temperature";
  72.   temp_config["state_topic"] = state_topic;
  73.   temp_config["unit_of_measurement"] = "°C";
  74.   temp_config["value_template"] = "{{ value_json.temperature }}";
  75.   temp_config["unique_id"] = String(device_id) + "_temperature";
  76.   temp_config["device"]["identifiers"] = device_id;
  77.   temp_config["device"]["name"] = "Water Tank Sensor";
  78.   temp_config["device"]["manufacturer"] = "DIY";
  79.   temp_config["device"]["model"] = "ESP8266+DS18B20";
  80.   
  81.   char temp_config_message[512];
  82.   serializeJson(temp_config, temp_config_message);
  83.   client.publish(temp_config_topic, temp_config_message, true);
  84. }
  85. void setup() {
  86.   Wire.begin(OLED_SDA, OLED_SCL);
  87.   Serial.begin(115200);
  88.   sensors.begin();
  89.   if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
  90.     Serial.println(F("SSD1306 allocation failed"));
  91.     for(;;);
  92.   }
  93.   delay(2000);
  94.   display.clearDisplay();
  95.   display.setTextColor(WHITE);
  96.   setup_wifi();
  97.   client.setServer(mqtt_server, mqtt_port);
  98. }
  99. void loop() {
  100.   //read temperature
  101.   Serial.print("Requesting temperatures...");
  102.   sensors.requestTemperatures(); // Send the command to get temperatures
  103.   Serial.println("DONE");
  104.   if (!client.connected()) {
  105.     reconnect();
  106.   }
  107.   client.loop();
  108.   delay(2000); // Wait between measurements
  109.   //sensors.requestTemperatures();
  110.   float tempC = sensors.getTempCByIndex(0);
  111.   // Check if reading is valid
  112.   if (tempC != DEVICE_DISCONNECTED_C)
  113.   {
  114.     Serial.print("Temperature for the device 1 (index 0) is: ");
  115.     Serial.println(tempC);
  116.   }
  117.   else
  118.   {
  119.     Serial.println("Error: Could not read temperature data");
  120.     return;
  121.   }
  122.   /*
  123.   if(tempC == DEVICE_DISCONNECTED_C) {
  124.     Serial.println("Error: Could not read temperature data");
  125.     return;
  126.   }
  127.   */
  128.   // clear display
  129.   display.clearDisplay();
  130.   // display temperature
  131.   display.setTextSize(1);
  132.   display.setCursor(0,0);
  133.   display.print("Temperature: ");
  134.   display.setTextSize(2);
  135.   display.setCursor(0,17);
  136.   display.print(tempC);
  137.   display.print(" ");
  138.   display.setTextSize(1);
  139.   display.cp437(true);
  140.   display.write(167);
  141.   display.setTextSize(2);
  142.   display.print("C");
  143.   
  144.   display.display();
  145.   // Create JSON payload
  146.   DynamicJsonDocument doc(128);
  147.   doc["temperature"] = tempC;
  148.   char json_string[128];
  149.   serializeJson(doc, json_string);
  150.   
  151.   Serial.print("Temperature: ");
  152.   Serial.print(tempC);
  153.   Serial.println(" °C");
  154.   Serial.print("Publishing: ");
  155.   Serial.println(json_string);
  156.   
  157.   client.publish(state_topic, json_string, true);
  158. }
复制代码


效果
ESP8266 采集 DHT11 和 DS18B20 温湿度数据 MQTT 上传至 Home Ass...图7


总结

本文介绍了 ESP8266 开发板实现 DHT11 温湿度传感器和 DS18B20 温度传感器实现远程温度监测,通过 MQTT 协议上传至 EMQX 平台,发送 JSON 代码实现 HomeAssistant 智能家居平台数据收集和历史数据查看等功能,为物联网相关硬件部署和智能家居的开发和拓展提供了参考。


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail