概述
STHS34PF80传感器项目种修改 Arduino 脚本,重新移植到STM32的MCU中。
该项目基于STHS34PF80 IR温度传感器,能够检测环境和物体温度,并且在最大4米范围内检测存在和运动。有一个Arduino脚本,显示如何为基本环境和物体温度测量配置传感器,并如何配置嵌入式功能算法,并使用它们检测存在和运动。脚本允许连续或一次性模式,允许更改低通滤波器和检测阈值以实现各种检测行为。脚本利用内嵌的中断引擎来检测温度数据的就绪状态,以及通知存在和运动事件。
本节将在上节代码中继续配置,通过获取模块的状态标志位来检测是否有人体存在。
最近在弄ST和瑞萨RA的课程,需要样片的可以加群申请:6_15061293 。
视频教学
[https://www.bilibili.com/video/BV1dp4y1P7g9/]
样品申请
[https://www.wjx.top/vm/OhcKxJk.aspx#](
参考Demo
[hthttps://github.com/kriswiner/STHS34PF80/tree/main](
完整代码下载
[https://download.csdn.net/download/qq_24312945/88257572](
参考程序获取数据
获取数据标志位
使用状态寄存器(STATUS,地址为23h)来检查何时有新的数据集可用。这里的数据集可能包括多种数据输出:物体温度、环境温度,以及可能的其他几个由嵌入式智能算法生成的输出(如存在检测、动作检测和环境温度冲击检测)。
参考文档设置如下所示。
修改如下。
/**
* @brief 获取DRDY
*
* @param add 设备地址
* @param val 设备ID.
* @retval ret 正常返回HAL_OK
*
*/
uint8_t STHS34PF80_getDataReadyStatus(uint8_t add)
{
uint8_t temp = 0;//STHS34PF80_STATUS- >0x23
sths34pf80_read_reg(add, STHS34PF80_STATUS, (uint8_t *)&temp, 1);
return temp;
}
使用数据准备就绪信号
FUNC_STATUS 寄存器(地址为25h)是一个只读寄存器,它包含了设备的嵌入式智能算法的状态标志。
PRES_FLAG: 这是一个存在检测标志。当检测到存在时,此位变为1;当没有检测到存在时,此位变回0。默认值为0。
(0: 没有检测到存在;1: 检测到存在)
MOT_FLAG: 这是一个运动检测标志。当检测到运动时,此位变为1;当没有检测到运动时,此位变回0。默认值为0。
(0: 没有检测到运动;1: 检测到运动)
TAMB_SHOCK_FLAG: 这是一个环境温度冲击检测标志。当检测到环境温度冲击时,此位变为1;当没有检测到环境温度冲击时,此位变回0。默认值为0。
(0: 没有检测到环境温度冲击;1: 检测到环境温度冲击)
参考文档设置如下所示。
获取代码如下所示。
/**
* @brief 清零DRDY
*
* @param add 设备地址
* @param val 设备ID.
* @retval ret 正常返回HAL_OK
*
*/
uint8_t STHS34PF80_getFuncStatus(uint8_t add)
{
uint8_t temp = 0;//STHS34PF80_FUNC_STATUS- >0x25
sths34pf80_read_reg(add, STHS34PF80_FUNC_STATUS, (uint8_t *)&temp, 1);
return temp;
}
嵌入式智能数字算法的输出数据
在4.5.4节中,描述了嵌入式智能数字算法的输出数据。这些数据包括存在检测、运动检测和环境冲击检测的输出数据,分别发送到TPRESENCE_H (3Bh) 和 TPRESENCE_L (3Ah) 寄存器,TMOTION_H (3Dh) 和 TMOTION_L (3Ch) 寄存器,以及 TAMB_SHOCK_H (3Fh) 和 TAMB_SHOCK_L (3Eh) 寄存器。
这些数据没有内在的物理意义,只是嵌入式智能数字算法用来断言相应的标志。
获取代码如下所示。
/**
* @brief 嵌入式智能数字算法产生的存在检测输出数据
*
* @param add 设备地址
* @param val 设备ID.
* @retval ret 正常返回HAL_OK
*
*/
int16_t STHS34PF80_readPresence(uint8_t add)
{
uint8_t rawData[2]; //STHS34PF80_TPRESENCE_L- >0x3A
sths34pf80_read_reg(add, STHS34PF80_TPRESENCE_L, (uint8_t *)&rawData[0], 2);
return (int16_t)(((int16_t)rawData[1]) < < 8 | rawData[0]);
}
/**
* @brief 嵌入式智能数字算法产生的运动检测输出数据
*
* @param add 设备地址
* @param val 设备ID.
* @retval ret 正常返回HAL_OK
*
*/
int16_t STHS34PF80_readMotion(uint8_t add)
{
uint8_t rawData[2]; //STHS34PF80_TMOTION_L- >0x3C
sths34pf80_read_reg(add, STHS34PF80_TMOTION_L, (uint8_t *)&rawData[0], 2);
return (int16_t)(((int16_t)rawData[1]) < < 8 | rawData[0]);
}
/**
* @brief 嵌入式智能数字算法产生的环境冲击输出数据
*
* @param add 设备地址
* @param val 设备ID.
* @retval ret 正常返回HAL_OK
*
*/
int16_t STHS34PF80_readAmbShock(uint8_t add)
{
uint8_t rawData[2]; //STHS34PF80_TAMB_SHOCK_L- >0x3E
sths34pf80_read_reg(add, STHS34PF80_TAMB_SHOCK_L, (uint8_t *)&rawData[0], 2);
return (int16_t)(((int16_t)rawData[1]) < < 8 | rawData[0]);
}
4.5.3节中提供了一个简单的例子,展示了如何从传感器获取物体温度数据(以最低有效位LSB表示)并将其转换为摄氏度°C。
该例子的过程也适用于获取环境温度数据。
代码如下所示。
/**
* @brief
*
* @param add 视场内对象发出的红外辐射量(未补偿)
* @param val 设备ID.
* @retval ret 正常返回HAL_OK
*
*/
int16_t STHS34PF80_readObjTemp(uint8_t add)
{
uint8_t rawData[2]; //STHS34PF80_TOBJECT_L- >0x26
sths34pf80_read_reg(add, STHS34PF80_TOBJECT_L, (uint8_t *)&rawData[0], 2);
return (int16_t)(((int16_t)rawData[1]) < < 8 | rawData[0]);
}
4.5.2节描述了如何获取环境温度数据,并在哪些寄存器中这些数据可以被找到。
寄存器存储:环境温度数据被发送到TAMBIENT_H(29h)和TAMBIENT_L(28h)寄存器中。其中,TAMBIENT_H存储了环境温度值的最高有效字节(MSB),而TAMBIENT_L存储了最低有效字节(LSB)。
数据格式:通过拼接TAMBIENT_H和TAMBIENT_L,可以得到完整的环境温度输出数据。这个值被表示为一个16位的有符号二进制补码数字。
单位转换:每个环境温度输出样本可以通过一个灵敏度值(在这个例子里是100 LSB/°C)来转换成摄氏度。公式如下:
应用场景:环境温度数据代表了与设备热耦合的环境的实际温度。这些数据可用于校正由于与传感器热耦合的环境温度变化而导致的物体温度输出数据的变化(详见4.6节)。
代码如下所示。
/**
* @brief
*
* @param add 环境温度数据
* @param val 设备ID.
* @retval ret 正常返回HAL_OK
*
*/
int16_t STHS34PF80_readAmbTemp(uint8_t add)
{
uint8_t rawData[2];//STHS34PF80_TAMBIENT_L- >0x28
sths34pf80_read_reg(add, STHS34PF80_TAMBIENT_L, (uint8_t *)&rawData[0], 2);
return (int16_t)(((int16_t)rawData[1]) < < 8 | rawData[0]);
}
补偿后的物体温度数据存储在TOBJ_COMP_L(38h)和TOBJ_COMP_H(39h)寄存器中。其中,TOBJ_COMP_H包含最高有效字节(MSB),TOBJ_COMP_L包含最低有效字节(LSB)。
需要注意的是,即使补偿算法处于活动状态,26h和27h寄存器中仍然包含原始物体温度数据。如果补偿没有激活,38h和39h寄存器会与26h和27h寄存器对齐。
补偿后的物体温度数据(以LSB为单位)与使用的光学系统的透射率成比例。您可以通过实际的灵敏度值来转换这些补偿后的数据,以获得相应的摄氏度值。不过,这些补偿后的数据并不实际代表视场内物体的温度。
如果启用了增益减小功能(见第4.7节),则不能启用嵌入式补偿算法。
代码如下所示。
/**
* @brief 嵌入式智能数字算法产生的视场内物体发射的红外辐射量输出数据(已经经过环境温度补偿)
*
* @param add 设备地址
* @param val 设备ID.
* @retval ret 正常返回HAL_OK
*
*/
int16_t STHS34PF80_readCompObjTemp(uint8_t add)
{
uint8_t rawData[2];//STHS34PF80_TOBJ_COMP_L- >0x38
sths34pf80_read_reg(add, STHS34PF80_TOBJ_COMP_L, (uint8_t *)&rawData[0], 2);
return (int16_t)(((int16_t)rawData[1]) < < 8 | rawData[0]);
}
主程序
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
// printf("PA7=%d",HAL_GPIO_ReadPin ( GPIOA, GPIO_PIN_7));
// if(HAL_GPIO_ReadPin ( GPIOA, GPIO_PIN_7))
// {
status = STHS34PF80_getDataReadyStatus(STHS34PF80_ADDRESS);
if(FUNCTIONS)
{
funcstatus = STHS34PF80_getFuncStatus(STHS34PF80_ADDRESS);
if(funcstatus & 0x04) printf("(存在)Presence detected !n");
if(funcstatus & 0x02) printf("(运动)Motion detected !n");
if(funcstatus & 0x01) printf("(环境温度冲击)T Shock detected !n");
}
if(status & 0x04) // when data ready
{
Presence = STHS34PF80_readPresence(STHS34PF80_ADDRESS);//嵌入式智能数字算法产生的存在检测输出数据
Motion = STHS34PF80_readMotion(STHS34PF80_ADDRESS); // 嵌入式智能数字算法产生的运动检测输出数据
AmbTemp = STHS34PF80_readAmbTemp(STHS34PF80_ADDRESS);//环境温度数据
ObjTemp = STHS34PF80_readObjTemp(STHS34PF80_ADDRESS);//视场内对象发出的红外辐射量(未补偿)
CompObjTemp = STHS34PF80_readCompObjTemp(STHS34PF80_ADDRESS);//嵌入式智能数字算法产生的视场内物体发射的红外辐射量输出数据(已经经过环境温度补偿)
AmbShock = STHS34PF80_readAmbShock(STHS34PF80_ADDRESS);//嵌入式智能数字算法产生的环境冲击输出数据
printf("(原始数据)Raw countsn");
printf("(视场内对象发出的红外辐射量(未补偿))STHS34PF80 ObjTemp = %dn",ObjTemp);
printf("(视场内物体发射的红外辐射量输出(经过环境温度补偿))STHS34PF80 Compensated ObjTemp = %dn",CompObjTemp);
printf("(环境温度)STHS34PF80 AmbTemp = %dn",AmbTemp);
printf("(存在检测)STHS34PF80 Presence = %dn",Presence);
printf("(运动检测输出)STHS34PF80 Motion = %dn",Motion);
printf("(环境冲击输出)STHS34PF80 AmbShock = %dn",AmbShock);
printf("(环境温度)STHS34PF80 Ambient Temperature = %.2fn",(float)(AmbTemp) / 100.0f); //环境温度数据
printf("(对象温度)STHS34PF80 Object Temperature = %.2fn",((float)(ObjTemp) / (float)(ObjSense) ) );
}
// }
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */