【Follow me第二季第2期】扩展任务二:通过外部SHT40温湿度传感器,上传温湿度到HA.
[复制链接]
本帖最后由 御坂10032号 于 2024-9-8 23:56 编辑
前言
通过上一章的练习我们已经学会了如何使用R4来读取传感器的数据并且上传到HA由HA进行显示(手机端或者Web端)。 那么本章节也是同样的道理,只不过传感器换成了SHT40. 我们可以直接使用上一个章节的代码, 不过需要替换掉原本的驱动函数以及对应的消息主题
正文
1- 驱动SHT40
同样得益于强大的开源生态,我们可以使用别人已经写好的SHT40 库来读取湿温度传感器的数据
在Arduino 库管理器中搜索SHT40 并且安装
打开示例程序,删除无关的传感器初始化代码, 如下所示
/***************************************************************************
Example for the SGP40+SHT40 board
written by Thiago Barros for BlueDot UG (haftungsbeschränkt)
BSD License
Version 1.0.0 (2023-04-22)
This sketch was written for the sensors SGP40 and SHT40 from Sensirion and is based on the Adafruit libraries for these sensors.
The SGP40 is a device for measuring volatile organic compounds (VOC) and for evaluating indoor air quality.
The SHT40 is a digital temperature and relative humidity sensor.
The VOC Algorithm from Sensirion integrates the output values from the SHT40 to improve the calculation of the VOC index.
For more technical information on the SGP40 and on the SHT40, go to ------> http://www.bluedot.space
***************************************************************************/
#include "Adafruit_SHT4x.h"
Adafruit_SHT4x sht4;
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println();
Serial.println(F("##################################"));
Serial.println(F("SGP40 test with SHT40 compensation"));
//*********************************************************************
//*************ADVANCED SETUP - SAFE TO IGNORE!************************
//Here we can configure the SHT40 Temperature and Humidity Sensor
//First we set the measurement precision
//There are three precision levels: High, Medium and Low
//The precision levels direclty affect the measurement duration, noise level and energy consumption
//On doubt, just leave it on default (High precision)
sht4.setPrecision(SHT4X_HIGH_PRECISION);
switch (sht4.getPrecision()) {
case SHT4X_HIGH_PRECISION:
Serial.println(F("SHT40 set to High precision"));
break;
case SHT4X_MED_PRECISION:
Serial.println(F("SHT40 set to Medium precision"));
break;
case SHT4X_LOW_PRECISION:
Serial.println(F("SHT40 set to Low precision"));
break;
}
//*********************************************************************
//*************ADVANCED SETUP - SAFE TO IGNORE!************************
// The SHT40 has a built-in heater, which can be used for self-decontamination.
// The heater can be used for periodic creep compensation in prolongued high humidity exposure.
// For normal operation, leave the heater turned off.
sht4.setHeater(SHT4X_NO_HEATER);
switch (sht4.getHeater()) {
case SHT4X_NO_HEATER:
Serial.println(F("SHT40 Heater turned OFF"));
break;
case SHT4X_HIGH_HEATER_1S:
Serial.println(F("SHT40 Heater: High heat for 1 second"));
break;
case SHT4X_HIGH_HEATER_100MS:
Serial.println(F("SHT40 Heater: High heat for 0.1 second"));
break;
case SHT4X_MED_HEATER_1S:
Serial.println(F("SHT40 Heater: Medium heat for 1 second"));
break;
case SHT4X_MED_HEATER_100MS:
Serial.println(F("SHT40 Heater: Medium heat for 0.1 second"));
break;
case SHT4X_LOW_HEATER_1S:
Serial.println(F("SHT40 Heater: Low heat for 1 second"));
break;
case SHT4X_LOW_HEATER_100MS:
Serial.println(F("SHT40 Heater: Low heat for 0.1 second"));
break;
}
//*********************************************************************
//*************ADVANCED SETUP IS OVER - LET'S CHECK THE CHIP ID!*******
if (! sht4.begin(&Wire1)) {
Serial.println(F("SHT40 sensor not found!"));
while (1) ;
}
else
{
Serial.print(F("SHT40 detected!\t"));
Serial.print(F("Serial number:\t"));
Serial.println(sht4.readSerial(), HEX);
}
Serial.println(F("----------------------------------"));
}
//*********************************************************************
//*************NOW LET'S START MEASURING*******************************
void loop() {
sensors_event_t humidity, temp;
sht4.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
float t = temp.temperature;
Serial.println("Temp *C = " + String(t));
float h = humidity.relative_humidity;
Serial.println("Hum. % = " + String(h));
delay(1000);
}
此时将程序烧录到开发板上之后,便可以通过串口助手查看室内的温度和湿度。
2- 配置HA实体
同样是配置configuration.yml , 根据官方文档得知我们可以加入以下的参数
sensor:
- name: "Temperature"
unique_id: temperature
state_topic: "office/sensor1"
suggested_display_precision: 1
unit_of_measurement: "°C"
value_template: "{{ value_json.temperature }}"
- name: "Humidity"
unique_id: humidity
state_topic: "office/sensor1"
unit_of_measurement: "%"
value_template: "{{ value_json.humidity }}"
注意: 修改完configuration.yml 后需要在HA的web界面重载配置。到此HA的配置完成
3- 发送数据到MQTT服务器(整合HA)
我们可以直接使用上一个章节的代码,只是替换驱动函数即可。 修改后的代码如下所示
/***************************************************
This is an example for the LTR329 light sensor that reads both channels
and demonstrates how to set gain and check data validity
Designed specifically to work with the LTR-329 light sensor from Adafruit
----> https://www.adafruit.com/product/5591
These sensors use I2C to communicate, 2 pins are required to
interface
****************************************************/
#include "Adafruit_SHT4x.h"
#include <ArduinoMqttClient.h>
#include <WiFiS3.h>
#include <WiFiClient.h>
#include <Arduino_JSON.h>
Adafruit_SHT4x sht4;
char ssid[] = "ImmortalWrt";
char pass[] = "mazha1997";
int status = WL_IDLE_STATUS;
const char broker[] = "192.168.1.113";
int port = 1883;
const char command_topic[] = "office/sensor1";
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
JSONVar dataObj;
void setup() {
Serial.begin(115200);
sht4.setPrecision(SHT4X_HIGH_PRECISION);
switch (sht4.getPrecision()) {
case SHT4X_HIGH_PRECISION:
Serial.println(F("SHT40 set to High precision"));
break;
case SHT4X_MED_PRECISION:
Serial.println(F("SHT40 set to Medium precision"));
break;
case SHT4X_LOW_PRECISION:
Serial.println(F("SHT40 set to Low precision"));
break;
}
//*********************************************************************
//*************ADVANCED SETUP - SAFE TO IGNORE!************************
// The SHT40 has a built-in heater, which can be used for self-decontamination.
// The heater can be used for periodic creep compensation in prolongued high humidity exposure.
// For normal operation, leave the heater turned off.
sht4.setHeater(SHT4X_NO_HEATER);
switch (sht4.getHeater()) {
case SHT4X_NO_HEATER:
Serial.println(F("SHT40 Heater turned OFF"));
break;
case SHT4X_HIGH_HEATER_1S:
Serial.println(F("SHT40 Heater: High heat for 1 second"));
break;
case SHT4X_HIGH_HEATER_100MS:
Serial.println(F("SHT40 Heater: High heat for 0.1 second"));
break;
case SHT4X_MED_HEATER_1S:
Serial.println(F("SHT40 Heater: Medium heat for 1 second"));
break;
case SHT4X_MED_HEATER_100MS:
Serial.println(F("SHT40 Heater: Medium heat for 0.1 second"));
break;
case SHT4X_LOW_HEATER_1S:
Serial.println(F("SHT40 Heater: Low heat for 1 second"));
break;
case SHT4X_LOW_HEATER_100MS:
Serial.println(F("SHT40 Heater: Low heat for 0.1 second"));
break;
}
//*********************************************************************
//*************ADVANCED SETUP IS OVER - LET'S CHECK THE CHIP ID!*******
if (! sht4.begin(&Wire1)) {
Serial.println(F("SHT40 sensor not found!"));
while (1) ;
}
else
{
Serial.print(F("SHT40 detected!\t"));
Serial.print(F("Serial number:\t"));
Serial.println(sht4.readSerial(), HEX);
}
Serial.println(F("----------------------------------"));
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}
// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.print("You're connected to the network");
printCurrentNet();
printWifiData();
if (!mqttClient.connect(broker, port)) {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
while (1);
}
Serial.println("You are connected to MQTT");
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true);
}
}
void printCurrentNet() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print the MAC address of the router you're attached to:
byte bssid[6];
WiFi.BSSID(bssid);
Serial.print("BSSID: ");
printMacAddress(bssid);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.println(rssi);
// print the encryption type:
byte encryption = WiFi.encryptionType();
Serial.print("Encryption Type:");
Serial.println(encryption, HEX);
Serial.println();
}
void printMacAddress(byte mac[]) {
for (int i = 0; i < 6; i++) {
if (i > 0) {
Serial.print(":");
}
if (mac[i] < 16) {
Serial.print("0");
}
Serial.print(mac[i], HEX);
}
Serial.println();
}
void printWifiData() {
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print your MAC address:
byte mac[6];
WiFi.macAddress(mac);
Serial.print("MAC address: ");
printMacAddress(mac);
}
void loop() {
sensors_event_t humidity, temp;
sht4.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
float t = temp.temperature;
Serial.println("Temp *C = " + String(t));
float h = humidity.relative_humidity;
Serial.println("Hum. % = " + String(h));
dataObj["temperature"] = t;
dataObj["humidity"] = h;
String jsonString = JSON.stringify(dataObj);
mqttClient.beginMessage(command_topic);
mqttClient.print(jsonString);
mqttClient.endMessage();
delay(500);
}
效果现象:HA中可以查看当前室内的湿度和温度,已经历史变化曲线
代码如下:
|