[作品提交] 【Follow me第二季第2期】+通过外部SHT40温湿度传感器,上传温湿度到HA

一只小跳帽   2024-9-22 15:24 楼主

今天来完成第四个任务通过外部SHT40温湿度传感器,上传温湿度到HA,通过HA面板显示数据

首先完成对SHT40 的采集 

SHT4X是业内知名的Sensirion公司推出的第四代数字温湿度传感器系列。传承了盛思锐湿度和温度传感器在业界有口皆碑的质量和可靠性,SHT40 可在广阔的测量范围内提供始终如一的高精确度,为用户带来最佳的性价比。 SHT40凭借宽电源电压范围 (3.3 – 5 V) 和顶尖精度(±1.8% 相对湿度,±0.2℃),它拥有更出色的灵活性。 SHT40可以测量 0 至 100% 的相对湿度以及 -40℃ 至 125℃ 的温度,可以达到 ±1.8%的湿度精度和 ±0.2℃温度精度。 SHT40集成可变功率加热器,在冷凝环境也可以正常工作。 凭借 3.3 V 至 5 V 的宽电源电压以及低于0.15mA的低功耗模式,SHTC40非常适合移动和电池驱动型应用,可以非常容易的集成到智能楼宇、天气站、仓库存储、养殖、孵化等应用场景中

首先获取温湿度数据这里要注意的是我们使用的 是Qwiic Connector 所以使用的是IIC2端口因此很多例子我们不能使用比如Adafruit_SHT4x 库中例子他就是使用的是IIC1 的接口

下面我们首先使用官方的历程进行读取数据

/*************************************************** 
  This is an example for the SHT4x Humidity & Temp Sensor

  Designed specifically to work with the SHT4x sensor from Adafruit
  ----> https://www.adafruit.com/products/4885

  These sensors use I2C to communicate, 2 pins are required to  
  interface
 ****************************************************/
#include <Wire.h>
#include "Adafruit_SHT4x.h"

Adafruit_SHT4x sht4 = Adafruit_SHT4x();
void setup() {
  Serial.begin(115200);

  while (!Serial)
    delay(10);     // will pause Zero, Leonardo, etc until serial console opens

  Serial.println("Adafruit SHT4x test");
  if (! sht4.begin(&Wire1)) {
    Serial.println("Couldn't find SHT4x");
    while (1) delay(1);
  }
  Serial.println("Found SHT4x sensor");
  Serial.print("Serial number 0x");
  Serial.println(sht4.readSerial(), HEX);

  // You can have 3 different precisions, higher precision takes longer
  sht4.setPrecision(SHT4X_HIGH_PRECISION);
  switch (sht4.getPrecision()) {
     case SHT4X_HIGH_PRECISION: 
       Serial.println("High precision");
       break;
     case SHT4X_MED_PRECISION: 
       Serial.println("Med precision");
       break;
     case SHT4X_LOW_PRECISION: 
       Serial.println("Low precision");
       break;
  }

  // You can have 6 different heater settings
  // higher heat and longer times uses more power
  // and reads will take longer too!
  sht4.setHeater(SHT4X_NO_HEATER);
  switch (sht4.getHeater()) {
     case SHT4X_NO_HEATER: 
       Serial.println("No heater");
       break;
     case SHT4X_HIGH_HEATER_1S: 
       Serial.println("High heat for 1 second");
       break;
     case SHT4X_HIGH_HEATER_100MS: 
       Serial.println("High heat for 0.1 second");
       break;
     case SHT4X_MED_HEATER_1S: 
       Serial.println("Medium heat for 1 second");
       break;
     case SHT4X_MED_HEATER_100MS: 
       Serial.println("Medium heat for 0.1 second");
       break;
     case SHT4X_LOW_HEATER_1S: 
       Serial.println("Low heat for 1 second");
       break;
     case SHT4X_LOW_HEATER_100MS: 
       Serial.println("Low heat for 0.1 second");
       break;
  }
  
}


void loop() {
  sensors_event_t humidity, temp;
  
  uint32_t timestamp = millis();
  sht4.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
  timestamp = millis() - timestamp;

  Serial.print("Temperature: "); Serial.print(temp.temperature); Serial.println(" degrees C");
  Serial.print("Humidity: "); Serial.print(humidity.relative_humidity); Serial.println("% rH");

  Serial.print("Read duration (ms): ");
  Serial.println(timestamp);

  delay(1000);
}

我们查看串口打印的数据

Read duration (ms): 10
Temperature: 24.83 degrees C
Humidity: 54.25% rH
Read duration (ms): 10

串口正确的读到了温湿度

下面我们再结合上一个连接mqtt的例子进行上传数据这里我们上次设置的上传数据 的主题是homeassistant/sensor/sensorroom/state

那这里我们就再加一个函数用于上传数据


void Update_Value(float temp,float hum)
{
  String topics="homeassistant/sensor/sensorroom/state";


  JsonDocument doc;

 doc["temperature"] = temp;
 doc["humidity"] = hum;

 String output;

 doc.shrinkToFit();  // optional

serializeJson(doc, output);

  if(mqttClient.publish(topics, output.c_str())){
    Serial.println("Publish topic:");Serial.println(topics);
    Serial.println("Publish message:");Serial.println(output);    
  } else {
    Serial.println("Message Publish Failed."); 
  }





}

这样我们就可以完整的上传我们需要的温湿度了下面我们来看一下结果

 

我们看到已经上传上去了 下面是完整的代码

//#include <WiFiS3.h>
#include <PubSubClient.h>
#include "Adafruit_SHT4x.h"
#include <Wire.h>
 #include <WiFi.h>
 #include "aaa.h"
 #define ARDUINOJSON_SLOT_ID_SIZE 1
#define ARDUINOJSON_STRING_LENGTH_SIZE 1
#define ARDUINOJSON_USE_DOUBLE 0
#define ARDUINOJSON_USE_LONG_LONG 0
#include <ArduinoJson.h>
// 设置wifi接入信息(请根据您的WiFi信息进行修改)

const char* mqttServer = "broker.emqx.io";
IPAddress server(192,168,31 ,200);

WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
 Adafruit_SHT4x sht4 = Adafruit_SHT4x();
void setup() {
  Serial.begin(9600);
  // 连接WiFi
  connectWifi();


  if (! sht4.begin(&Wire1 )) {
    Serial.println("Couldn't find SHT4x");
    while (1) delay(1);
  }
  
  // 设置MQTT服务器和端口号
  mqttClient.setServer(server, 1883);
 
  // 连接MQTT服务器
  connectMQTTServer();
  Register_temp();
  Register_hum();

}
 
void loop() { 
   sensors_event_t humidity, temp;
sht4.getEvent(&humidity, &temp);
Serial.print("Temperature: "); Serial.print(temp.temperature); Serial.println(" degrees C");
  Serial.print("Humidity: "); Serial.print(humidity.relative_humidity); Serial.println("% rH");

  if (mqttClient.connected()) { // 如果开发板成功连接服务器    
    Update_Value(temp.temperature,humidity.relative_humidity);
  } else {                  // 如果开发板未能成功连接服务器
    connectMQTTServer();    // 则尝试连接服务器
  }
  




}
 
void connectMQTTServer(){
  String clientId = "UNOR4";
 
  // 连接MQTT服务器

  if (mqttClient.connect(clientId.c_str())) { 
    Serial.println("MQTT Server Connected.");
    Serial.println("Server Address: ");
    Serial.println(mqttServer);
    Serial.println("ClientId:");
    Serial.println(clientId);
  } else {
    Serial.print("MQTT Server Connect Failed. Client State:");
    Serial.println(mqttClient.state());
    delay(3000);
  }  
}
 
void connectWifi(){
 
  WiFi.begin(ssid, password);
 
  //等待WiFi连接,成功连接后输出成功信息
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi Connected!");  
  Serial.println(""); 
  Serial.println(WiFi.localIP());
}
void Register_temp()
{
  // Stream& output;
  const char * topics="homeassistant/sensor/sensorBedroomT/config";
String output;
JsonDocument doc;

doc["device_class"] = "temperature";
doc["name"] = "Temperature";
doc["state_topic"] = "homeassistant/sensor/sensorroom/state";
doc["value_template"] = "{{ value_json.temperature}}";
doc["unique_id"] = "temp01ae";

JsonObject device = doc["device"].to<JsonObject>();
device["identifiers"][0] = "room01";
device["name"] = "room";

doc.shrinkToFit();  // optional

serializeJson(doc, output);
Serial.println(output.length());


  if(mqttClient.publish(topics, output.c_str())){
    Serial.println("Publish topic:");Serial.println(topics);
    Serial.println("Publish message:");Serial.println(output);    
  } else {
    Serial.println("Message Publish Failed."); 
  }






}

void Register_hum()
{
  // Stream& output;
    const char * topics="homeassistant/sensor/sensorBedroomH/config";
String output;
JsonDocument doc;

doc["device_class"] = "humidity";
doc["name"] = "Humidity";
doc["state_topic"] = "homeassistant/sensor/sensorroom/state";
doc["unit_of_measurement"] = "%";
doc["value_template"] = "{{ value_json.humidity}}";
doc["unique_id"] = "hum01ae";

JsonObject device = doc["device"].to<JsonObject>();
device["identifiers"][0] = "room01";
device["name"] = "room";

doc.shrinkToFit();  // optional

serializeJson(doc, output);
Serial.println(output);
Serial.println(output.length());


  if(mqttClient.publish(topics, output.c_str())){
    Serial.println("Publish topic:");Serial.println(topics);
    Serial.println("Publish message:");Serial.println(output);    
  } else {
    Serial.println("Message Publish Failed."); 
  }



}

void Update_Value(float temp,float hum)
{
  String topics="homeassistant/sensor/sensorroom/state";


  JsonDocument doc;

 doc["temperature"] = temp;
 doc["humidity"] = hum;

 String output;

 doc.shrinkToFit();  // optional

serializeJson(doc, output);


  if(mqttClient.publish(topics.c_str(), output.c_str())){
    Serial.println("Publish topic:");Serial.println(topics);
    Serial.println("Publish message:");Serial.println(output);    
  } else {
    Serial.println("Message Publish Failed."); 
  }





}








下方的视频为详细讲解




 

 

 

本帖最后由 一只小跳帽 于 2024-9-22 22:31 编辑

回复评论 (1)

SHTC40适合移动和电池驱动型应用,很多例子我们不能使用比如Adafruit_SHT4x 库中例子他就是使用的是IIC1 的接口,这个原因是什么

点赞  2024-9-24 07:49
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复