242|0

5

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

【Follow me第二季第2期】扩展任务二:通过外部SHT40温湿度传感器,上传温湿度到HA [复制链接]

  本帖最后由 sinc_sila 于 2024-10-16 09:53 编辑

这章的任务是将将UNO R4 WiFi模块连接到外部的SHT40传感器,并通过MQTT协议将数据上传到Home Assistant。

硬件准备

Arduino UNO R4

SHT40温湿度传感器

使用 Arduino IDE 中的库管理器安装适用于 Arduino 的 Adafruit SHT4X 库
将范例简化后的代码:
#include "Adafruit_SHT4x.h" // 引入SHT40传感器的Adafruit库
Adafruit_SHT4x sht4; // 创建SHT40传感器对象

void setup() {
  Serial.begin(115200); // 初始化串口通信,波特率为115200
  Serial.println(F("SGP40 test with SHT40 compensation")); // 打印开始测试的信息

  // 设置SHT40传感器的测量精度
  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;
  }

  // 配置SHT40传感器的内置加热器状态
  sht4.setHeater(SHT4X_NO_HEATER); // 关闭加热器
  // 打印当前加热器的状态
  switch (sht4.getHeater()) {
    case SHT4X_NO_HEATER: 
      Serial.println(F("SHT40 Heater turned OFF")); // 加热器关闭
      break;
    // 其他加热器设置...
  }

  // 初始化SHT40传感器
  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("----------------------------------")); // 打印分隔线
}

void loop() {
  sensors_event_t humidity, temp; // 创建温湿度事件对象
  sht4.getEvent(&humidity, &temp); // 从传感器获取最新的温湿度数据

  float t = temp.temperature; // 获取温度值
  Serial.println("温度 *C = " + String(t)); // 打印温度值
  float h = humidity.relative_humidity; // 获取相对湿度值
  Serial.println("湿度 % = " + String(h)); // 打印湿度值

  delay(1000); // 延时1秒,之后再次进行测量
}

烧录后串口打印显示:


配置Home Assistant根目录中的configuration.yml :

 sensor:
   - unique_id: R4_温度                              # 设备ID,唯一标识这个温度传感器
     name: "R4_温度"                                 # 设备名称,显示在Home Assistant界面上的名称
     state_topic: "STH40"                            # 订阅端口,用于接收温度传感器数据的消息
     suggested_display_precision: 1                  # 建议显示的小数位数
     unit_of_measurement: "°C"                       # 测量单位,摄氏度
     value_template: "{{ value_json.temperature }}"  # 从消息中提取温度值的模板
   - unique_id: R4_湿度                              # 设备ID,唯一标识这个湿度传感器
     name: "R4_湿度"                                 # 设备名称,显示在Home Assistant界面上的名称
     state_topic: "STH40"                            # 订阅端口,用于接收湿度传感器数据的消息
     unit_of_measurement: "%"                        # 测量单位,百分比
     value_template: "{{ value_json.humidity }}"     # 从消息中提取湿度值的模板

 

保存后重启Home Assistant显示下图为配置成功:


在进阶任务的代码基础上修改整合:
 

#include <ArduinoMqttClient.h> // 引入MQTT客户端库
#include <WiFiS3.h> // 引入WiFi库
#include <ArduinoJson.h>
#include <WiFiClient.h> // 引入WiFi客户端库
#include "Adafruit_SHT4x.h" // 引入SHT40传感器的Adafruit库

Adafruit_SHT4x sht4; // 创建SHT40传感器对象

char ssid[] = "xcxc"; // WiFi网络名称
char pass[] = "xc12345678"; // WiFi密码
int status = WL_IDLE_STATUS; // WiFi连接状态

const char broker[] = "XXXXXXXXX"; // MQTT代理服务器地址
int port = 1883; // MQTT代理服务器端口
const char topic[] = "SHT40"; // MQTT主题

WiFiClient wifiClient; // 创建WiFi客户端对象
MqttClient mqttClient(wifiClient); // 创建MQTT客户端对象,并传入WiFi客户端对象

void setup() {
  Serial.begin(115200); // 初始化串口通信
  while (!Serial) {} // 等待串口监视器打开
  Serial.println(F("SGP40 test with SHT40 compensation")); // 打印开始测试的信息


  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("与WiFi模块通信失败!"); // 如果没有检测到WiFi模块,则停止程序
    while (true);
  }

  // 尝试连接到WiFi网络
  while (status != WL_CONNECTED) {
    Serial.print("尝试连接到WPA SSID: ");
    Serial.println(ssid);
    status = WiFi.begin(ssid, pass); // 连接到WiFi网络
    delay(10000); // 等待10秒看是否连接成功
  }

  Serial.println("已连接到网络"); // 连接成功后的提示
  printCurrentNet(); // 打印当前网络信息
  printWifiData(); // 打印WiFi数据

  // 尝试连接到MQTT代理服务器
  if (!mqttClient.connect(broker, port)) {
    Serial.print("MQTT连接失败!错误代码 = ");
    Serial.println(mqttClient.connectError()); // 如果连接失败,则打印错误代码
    while (1); // 停止程序
  }
  Serial.println("已连接到MQTT"); // 连接成功后的提示

   // 订阅主题
 mqttClient.subscribe(topic);

 Serial.print("等待主题上的消息: ");
 Serial.println(topic);
 Serial.println();

   // 设置消息接收回调
 mqttClient.onMessage(onMqttMessage);

   // 设置SHT40传感器的测量精度
  sht4.setPrecision(SHT4X_HIGH_PRECISION); // 设置为高精度
  Serial.println("SHT40 set to High precision"); // 打印高精度

  // 配置SHT40传感器的内置加热器状态
  sht4.setHeater(SHT4X_NO_HEATER); // 关闭加热器
  // 打印当前加热器的状态
  switch (sht4.getHeater()) {
    case SHT4X_NO_HEATER: 
      Serial.println(F("SHT40 Heater turned OFF")); // 加热器关闭
      break;
  }

  // 初始化SHT40传感器
  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("----------------------------------")); // 打印分隔线

}

void printCurrentNet() {
  Serial.print("SSID: "); Serial.println(WiFi.SSID()); // 打印网络名称
  byte bssid[6]; WiFi.BSSID(bssid); printMacAddress(bssid); // 打印路由器MAC地址
  Serial.print("信号强度 (RSSI):"); Serial.println(WiFi.RSSI()); // 打印信号强度
  Serial.print("加密类型: "); Serial.println(WiFi.encryptionType(), 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() {
  IPAddress ip = WiFi.localIP(); // 获取本地IP地址
  Serial.print("IP地址: "); Serial.println(ip); // 打印IP地址
  byte mac[6]; WiFi.macAddress(mac); Serial.print("MAC地址: "); printMacAddress(mac); // 打印MAC地址
}

void loop() {
  // 发送MQTT保持活动信号,以避免被代理断开连接
  mqttClient.poll();

  sensors_event_t humidity, temp; // 创建温湿度事件对象
  sht4.getEvent(&humidity, &temp); // 从传感器获取最新的温湿度数据

  if (isnan(temp.temperature) || isnan(humidity.relative_humidity)) {
    Serial.println("Failed to read from SHT40 sensor!");
    return;
  }

  float t = temp.temperature; // 获取温度值
  float h = humidity.relative_humidity; // 获取相对湿度值

  Serial.println("温度 *C = " + String(t));
  Serial.println("湿度 % = " + String(h));

  // 创建一个JSON对象
  StaticJsonDocument<200> doc;
  doc["temperature"] = t;
  doc["humidity"] = h;

  // 将JSON对象转换为字符串
  String jsonString;
  serializeJson(doc, jsonString);

  // 发送JSON字符串到MQTT代理服务器
  mqttClient.beginMessage(topic); // 使用之前定义的topic
  mqttClient.print(jsonString);
  mqttClient.endMessage();

  delay(1000); // 延迟5秒发送下一次数据
}

void onMqttMessage(int messageSize) {
  // 我们收到了一条消息,打印出主题和内容
  Serial.println("收到一条消息:");
  Serial.print(mqttClient.messageTopic());

  // 使用Stream接口打印内容
  String message;
  while (mqttClient.available()) {
    message += (char)mqttClient.read();
  }
  Serial.println(message);
}

 

 

点赞 关注
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表