Sensor Hub 是 TuyaOS 传感器管理组件,可以实现对传感器设备的硬件抽象,设备管理和数据处理。基于 sensor_hub 开发传感器应用时,开发者无需关注传感器的传输协议,只需要对传感器挂载硬件接口、工作方式、采集间隔等进行配置,然后在事件回调中读取传感器处理即可。
本项目采用 T2-U 开发板及 TuyaOS Sensor Hub 组件,使用 SHT30 温湿度传感器,开发一款智能 Wi-Fi 温湿度计。
传感器 SHT30
本方案选用 SHT30 作为温湿度传感器。
SHT30 概述
SHT3x 系列是由瑞士 Sensirion 生产的高精度温湿度传感器,提供了一系列新功能,如增强信号处理、两个独特和用户可选I2C地址、一个可编程温湿度极限的报警模式,以及高达1 MHz的通信速度。
芯片资料可在官网 https://sensirion.com/media/documents/213E6A3B/63A5A569/Datasheet_SHT3x_DIS.pdf 下载。
供电:SHT3x 系列温湿度传感器采用宽电压设计,可使用 2.15 v 至 5.5 v 电压范围。
封装:SHT3x 采用 8-pin DFN 封装
芯片总共有 8 个引脚:
Pin | 名称 | 说明 |
---|---|---|
1 | SDA | I2C 数据线引脚 |
2 | ADDR | 地址引脚,可连接 VSS 或 VDD,分别会有不同的地址,不能浮空。 |
3 | ALERT | 报警输出引脚,如果使用,建议接到单片机的外部中断。不用的话需要浮空。 |
4 | SCL | I2C 时钟线引脚 |
5 | VDD | 电压输入引脚 |
6 | nRESET | 复位引脚,低电平有效。如果不用,建议浮空;也可以通过一个 ≥2 kΩ 的电阻链接到 VDD |
7 | R | 没有电气连接,需连接到 VSS |
8 | VSS | 接地 |
- I2C 通讯地址:SHT3x 系列温湿度传感器可以通过 ADDR 引脚设置通讯地址。
SHT3x 温湿度传感器 | I2C地址 | ADDR(pin 2)引脚配置 |
---|---|---|
I2C address A | 0x44(默认) | 连接到逻辑低电平 |
I2C address B | 0x45 | 连接到逻辑高电平 |
数据读取
SHT3x系列温湿度传感器支持I2C快速模式(频率高达1000千赫)。
1. 单次读取
SHT3x 温湿度传感器有一种单次测量模式。这种模式只按我们规定的方式运行一次,测量通信序列由一个启动条件、I2C写标头和一个16位测量命令组成。在传感器完成测量后,通过发送一个START条件和一个I2C读标头,主控可以读取测量结果。具体的格式如下:
2. 周期读取
SHT3X温湿度传感器还有一种周期性检测数据的方式。这种方式先将SHT3X温湿度传感器配置为周期获取模式。在这一模式下就可以周期获取数据了。
3. 数据转换
测量数据总是以16位无符号整数的形式传输。这些值已经线性化,并补偿了温度和电源电压的影响。可以使用简单的公式将这些原始值转换为物理量值。
温度转换公式(结果为摄氏度和华氏度):
相对湿度换算公式(结果为%RH):
SRH和ST分别表示原始传感器输出的湿度和温度。只有当SRH和ST用十进制表示时,这些公式才能正确工作。
其中:
- SHT30 的湿度精度为 +- 2%RH
- SHT30 的温度精度为 +- 0.2°C
产品创建
第一步:选择品类
- 进入 涂鸦 IoT 开发平台,使用先前注册的账号登录。
- 在侧边栏单击 产品 > 产品开发 > 创建产品。
- 在标准类目中,选择 传感 > 环境 > 温湿度传感器。
- 选择 产品开发 > 自定义方案 > 温湿度传感器。
- 填写 产品名称,通讯协议根据模组对应选择即可,之后单击 创建产品。
- T2-U 是 WiFi-蓝牙双模模组,通讯协议选择“WiFi-蓝牙”;同时我们当前使用USB供电,功耗类型选择“标准功耗”。
注:T2-U SDK不支持低功耗功能
第二步:选择功能
创建产品后,需要为产品选择功能。左边列表栏是可以选择的功能,右边列表栏是已经选择的功能,您可以根据实际应用场景选择对应的功能。
- 温湿度传感器默认已经添加了"温度"、”湿度“两个功能,其中温度为必选功能不能删除。
在左侧“选择标准功能” 点击添加需新增的功能
- 选择功能后,会跳转到 功能定义 界面。产品名称下方是产品的 PID 信息,中间是为产品选择的功能,可以看到功能的 ID 和数据类型等。如果想要添加功能,可以单击后面的 添加功能 进行调整。
第三步:选择控制面板
单击 设备交互,在 面板控制 栏中为产品选择控制面板。
控制面板就是在智能生活 App 上控制设备的界面样式,不同的控制面板界面、控件风格会有所不同。平台提供了大量的公版面板供您选择,您也可以使用涂鸦提供的开发工具包,自定义开发面板或者定制面板。这里以公版面板为例。
选择控制面板后,还可以更换面板或者简单地编辑面板。您可以使用智能生活 App 扫描右侧的二维码体验面板。
第四步:选择开发方式
单击 硬件开发,接入方式选择 TuyaOS。
配置完成后,复制 PID 至我们需要开发的代码中。
Sensor Hub 应用
Sensor Hub 组件目前已经支持 sht3x、sht4x、cht8305等温湿度传感器驱动,可以在 tdd_sensor_temp_humi
目录下找到。
根据 《TuyaOS Sensor Hub组件介绍》中介绍 Sensor Hub使用流程
- 调用
tdd_sensor_xxx_register
注册 xxx 设备。 - 调用
tdl_sensor_dev_find
查找 xxx 设备,获得设备句柄(确认 xxx 设备是否注册成功)。 - 调用
tdl_sensor_dev_config
配置 xxx 设备(启动前的一些必要配置;启动后也可通过调用该接口控制设备)。 - 调用
tdl_sensor_dev_open
启动 xxx 设备(在需要启动时调用),同时需要编写数据通知回调函数。 - 调用
tdl_sensor_dev_read
读取 xxx 设备的实时数据(有需要时)。 - 调用
tdl_sensor_dev_close
停止 xxx 设备(在需要停止时调用)。
使用示例
在 tuyaos_sensor_hub_demo_quickstart 项目的 src 目录下 app_temp_humi.c
中已经实现了以上流程。
1. 设备注册、查找设备获取设备句柄
Code: Select all
STATIC OPERATE_RET __sht30_register(VOID_T)
{
OPERATE_RET op_ret;
SR_I2C_GPIO_T i2c_gpio = {
.scl = SHT30_SCL_PIN,
.sda = SHT30_SDA_PIN
};
SR_TH_I2C_CFG_T sht30_i2c_cfg = {
.port = 0,
.addr = SR_I2C_ADDR_SHT3X_A,
.gpio = i2c_gpio
};
SR_TH_MEAS_CFG_T sht30_meas_cfg = {
.prec = SR_TH_PREC_HIGH,
.freq = SR_TH_FREQ_1HZ
};
op_ret = tdd_sensor_sht3x_register("SHT30", sht30_i2c_cfg, sht30_meas_cfg);
if (OPRT_OK != op_ret) {
TAL_PR_ERR("tdd_sensor_sht3x_register, error code: %d.", op_ret);
return op_ret;
}
op_ret = tdl_sensor_dev_find("SHT30", &sg_sht30_handle);
if (OPRT_OK != op_ret) {
TAL_PR_ERR("tdl_sensor_dev_find, error code: %d.", op_ret);
return op_ret;
}
return OPRT_OK;
}
2. 设备启动
- 采集触发模式为:轮询(软件定时)
- 采集间隔:APP_TEMP_HUMI_READ_CYCLE(当前应用通过宏定义为2 * 1000 ms)
- 数据就绪通知回调:__sht30_inform_cb
- 存放返回给app数据的缓存大小:1字节
- 元素型数据订阅模型配置:NULL
Code: Select all
#define APP_TEMP_HUMI_READ_CYCLE 2 * 1000 // units:ms
STATIC OPERATE_RET __sht30_open(VOID_T)
{
if (sg_sht30_flag.turn_on) {
TAL_PR_ERR("The device is already turned on.");
return OPRT_COM_ERROR;
}
OPERATE_RET op_ret;
SR_DEV_CFG_T sht30_cfg;
tkl_system_memset(&sht30_cfg, 0, SIZEOF(SR_DEV_CFG_T));
sht30_cfg.mode.trig_mode = SR_MODE_POLL_SOFT_TM;
sht30_cfg.mode.poll_intv_ms = APP_TEMP_HUMI_READ_CYCLE;
sht30_cfg.inform_cb.ele = __sht30_inform_cb;
sht30_cfg.fifo_size = 1;
sht30_cfg.ele_sub = NULL;
op_ret = tdl_sensor_dev_open(sg_sht30_handle, &sht30_cfg);
if (OPRT_OK != op_ret) {
TAL_PR_ERR("tdl_sensor_dev_open, error code: %d.", op_ret);
return op_ret;
}
sg_sht30_flag.turn_on = TRUE;
TAL_PR_INFO("Open device successfully.");
return OPRT_OK;
}
3.数据获取
在回调函数中获取数据,在函数中对数据进行了比较,当前读取到的数据比上一次读取到的数据差在一定范围之内,才会触发上报。当前应用通过宏定义设置为温度上报间隔为 2.0 ℃
,湿度上报间隔为 2.0 %/H
。
Code: Select all
#define APP_TEMP_REPORT_INTERVAL 20 // default: 2.0 ℃
#define APP_HUMI_REPORT_INTERVAL 20 // default: 2.0 %
STATIC VOID_T __sht30_inform_cb(CHAR_T* name, UCHAR_T ele_num, SR_ELE_BUFF_T *ele_data)
{
INT_T temp, humi;
for (UCHAR_T i = 0; i < ele_num; i++) {
if (ele_data[i].id == SR_TH_ELE_ID_TEMP) {
temp = (INT_T)(ele_data[i].val[0].sr_float * 10 * TEMP_SCALE);
TAL_PR_INFO("Temp: %d sg_th_dp_data.temp.dp_value: %d", temp, sg_th_dp_data.temp.dp_value);
if (temp != sg_th_dp_data.temp.dp_value) {
if ((temp > (sg_th_dp_data.temp.dp_value + APP_TEMP_REPORT_INTERVAL)) || \
((temp + APP_TEMP_REPORT_INTERVAL) < sg_th_dp_data.temp.dp_value)) {
sg_th_dp_data.temp.dp_value = temp;
sg_sht30_flag.temp_change = TRUE;
TAL_PR_INFO("Temp change. Enable report");
}
}
} else {
humi = (INT_T)(ele_data[i].val[0].sr_float * 10 * HUMI_SCALE);
TAL_PR_INFO("Humi: %d sg_th_dp_data.humi.dp_value: %d", humi, sg_th_dp_data.humi.dp_value);
if (humi != sg_th_dp_data.humi.dp_value) {
if ((humi > (sg_th_dp_data.humi.dp_value + APP_HUMI_REPORT_INTERVAL)) || \
((humi + APP_HUMI_REPORT_INTERVAL) < sg_th_dp_data.humi.dp_value)) {
sg_th_dp_data.humi.dp_value = humi;
sg_sht30_flag.humi_change = TRUE;
TAL_PR_INFO("Humi changed. Enable report");
}
}
}
}
}
4. 数据上报
示例中上报采用的是软件定时器轮询检测温/湿度变化标记(sg_sht30_flag.temp_change/sg_sht30_flag.humi_change)
Code: Select all
STATIC VOID_T __repo_one_dp_data(CONST UCHAR_T dp_id, CONST UCHAR_T dp_type, CONST TY_OBJ_DP_VALUE_U dp_value)
{
GW_WIFI_NW_STAT_E wifi_stat = STAT_LOW_POWER;
get_wf_gw_nw_status(&wifi_stat);
if (wifi_stat <= STAT_AP_STA_DISC || wifi_stat == STAT_STA_DISC) {
return;
}
TY_OBJ_DP_S dp_repo;
dp_repo.dpid = dp_id;
dp_repo.type = dp_type;
dp_repo.time_stamp = 0;
switch (dp_type) {
case PROP_BOOL:
dp_repo.value.dp_bool = dp_value.dp_bool;
break;
case PROP_VALUE:
dp_repo.value.dp_value = dp_value.dp_value;
break;
case PROP_ENUM:
dp_repo.value.dp_enum = dp_value.dp_enum;
break;
case PROP_STR:
dp_repo.value.dp_str = dp_value.dp_str;
break;
case PROP_BITMAP:
dp_repo.value.dp_bitmap = dp_value.dp_bitmap;
break;
default:
break;
}
TAL_PR_INFO("repo_one_dp_data ID:%d", dp_repo.dpid);
OPERATE_RET op_ret = dev_report_dp_json_async(NULL, &dp_repo, 1);
if (OPRT_OK != op_ret) {
TAL_PR_ERR("__repo_one_dp_data -- dev_report_dp_json_async, error code: %d.", op_ret);
}
}
STATIC VOID_T __sht30_report_timer_cb(TIMER_ID timer_id, VOID_T *arg)
{
if (sg_sht30_flag.alert) {
__sht30_alert_occur_handler();
}
if (sg_sht30_flag.temp_change) {
TAL_PR_INFO("temp change report.");
sg_sht30_flag.temp_change = FALSE;
__repo_one_dp_data(DP_ID_TEMP, PROP_VALUE, sg_th_dp_data.temp);
}
if (sg_sht30_flag.humi_change) {
TAL_PR_NOTICE("humi change report.");
sg_sht30_flag.humi_change = FALSE;
__repo_one_dp_data(DP_ID_HUMI, PROP_VALUE, sg_th_dp_data.humi);
}
}
示例修改
在 tuyaos_sensor_hub_demo_quickstart 示例中,已经实现了上面的逻辑,开发中做一些适当的修改即可使用
1. PID 修改
获取 “产品创建” 步骤中已创建产品的 PID,
可修改 app_temp_humi.h
文件中的 PID
Code: Select all
#define PID "8q46zzdfuofastqr"
2. 功能 DP_ID 号修改
获取 “产品创建” -> "01 功能定义“ 中的标准功能下的DPID修改当前定义。
tuyaos_sensor_hub_demo_quickstart 中功能 DP_ID 定位在 app_temp_humi.h
文件中,根据实际情况修改。
Code: Select all
/**
* @brief DP list
*/
#define DP_ID_TEMP 1
#define DP_ID_HUMI 2
#define DP_ID_TEMP_MAX 10
#define DP_ID_TEMP_MIN 11
#define DP_ID_HUMI_MAX 12
#define DP_ID_HUMI_MIN 13
#define DP_ID_TEMP_ALT 14
#define DP_ID_HUMI_ALT 15
#define DP_ID_SWITCH 21
#define MAX_DP_NUM 9
3. 温湿度传感器 GPIO 修改
T2-U 使用 I2C 接口连接 SHT3x,tuyaos_sensor_hub_demo_quickstart 中采用软件 I2C 链接,GPIO 定义在 app_temp_humi.h
文件中,可根据实际连接情况修改。
Code: Select all
/**
* @brief pin define
*/
#define SHT30_SCL_PIN GPIO_NUM_20
#define SHT30_SDA_PIN GPIO_NUM_22
#define SHT30_ALT_PIN GPIO_NUM_14
设备配网与使用
- 长按 S2 按钮,使 T2-U 进入配网状态
- 使用 涂鸦智能APP 对设备进行配网,连接路由器成功后,设备会自动连接涂鸦云并自动与当前用户绑定,这样就可以在 涂鸦智能APP 上发现对应的设备。
- 可查看智能温湿度计上报的温度
- 可进入“设置" 设置报警温度
示例代码下载
tuyaos_sensor_hub_demo_quickstart 示例代码可在以下链接中下载:
T2-U开发板获取方式
- 方式一:前往 涂鸦 IoT 开发平台样品商店 获取
- 方式二:前往 网页版淘宝网商品详情 获取