昨天分享了一篇国产红外测温传感器替代迈莱芯MLX90614在电吹风上的应用,看阅读量和点赞收藏数量不少,对于第一次分享能有这样的成效还是比较满意的。趁热打铁再分享一下这个传感器的设计指导,包括结构设计注意事项、热设计注意事项、硬件设计和接口调试源代码。
我们采用的是领麦微一款型号FW-TRS-5.5D1,简写FW-D1的红外非接触测温传感器。这是一款TO39封装,直插形式的数字红外热测温传感器,用于非接触测温应用。传感器内置MEMS热电堆传感单元和专用处理芯片,用户无需其他外围,直接通过 IIC 总线与传感器进行通讯读取最终测量温度。该型号产品据说广泛应用于家电、工业、电力等测温和需要做温控的场景,因为这个品牌可以协助使用者做定制算法开发,还可以做产品级的出厂标定,适用于我们这种对传感器一知半解,且没有研发能力和经验的产品方案开发者。真的要我们花费很多时间精力和资金投入去研究传感器,对于在珠三角这些追求高效运转的企业来说是个拦路虎,哈哈...我们只要能好用就可以了,当然成本也是考虑的重要因素。这也是为什么领麦微能替代迈莱芯90614很关键的一点。迈莱芯和海曼这些都是红外测温领域的前辈和先行者,但是成本也确实很高,已经割了我们多少年的韭菜了。真心推荐国产替代!
言归正传!上一个实物图,再上一个封装示意图。
设计注意事项如下:
1,结构要求
如果结构上允许,可以将传感器镜头突出设备外壳上表面。 如果外观有限制需要将器件内置,则需要保证结构避让器件视场。如下图所示
传感器本身自带红外透镜,因为滤光片对红外线有衰减,会导致测量结果偏低,如 非必要,不要再增加其他滤光片。如果因为防水、防污都要求必须要加外置镜片时,算法和标定就要重新做。这个工作量还是蛮大的
2,热设计要求
环境温度对测温效果影响较大,尽量保证传感器处于一个稳定的环境温度下,避免热源对其影响。因此要远离高发热器件,PCB 上传感器四周尽可能做开槽设计,将传感器置于孤岛。如果实在是避让不开就要做大量的测试把产品热特性摸清,提取出热模型关键参数,在做算法。又一个熬人的过程。
3,硬件设计
硬件设计比较简单,器件引脚包含电源、IIC 总线共 4 个管脚,供电电压允许范围为 2.3~3.6V。传感器本身功耗很低,电源地之间使用一颗 0.1uF 电容即可,如果传感器离供电部分比较远,可以考虑增加一个 10uF 电容,以保证电源稳定降低噪声。如下图
4,程序设计
传感器采用 IIC 接口,器件上电后需要等待 2mS 以上,待器件复位并完成初始化操作即可以直接读取测量温度结果。调试源代码如下:
#include <stdio.h> #include "drv_i2c.h" #include "trs55d.h" #include "body_temp.h"
extern uint8_t uartSendString(const char* buf);
extern void OLED_ShowString(uint8_t x,uint8_t y, const char *chr,uint8_t size1,uint8_t mode); extern void OLED_ShowBNum(uint8_t x,uint8_t y,float num,uint8_t len,uint8_t size2,uint8_t mode);
uint8_t TRS55D_IIC_Read(uint8_t addr_dev, uint8_t addr_reg, uint8_t *buf, uint16_t count)
{
uint8_t ret; uint8_t ackflag; uint16_t i = 0; drv_i2c_start();
drv_i2c_select_dev(addr_dev,DRV_I2C_OPWR);
drv_i2c_writebyte(addr_reg); drv_i2c_start();
drv_i2c_select_dev(addr_dev,DRV_I2C_OPRD); for(i = 0; i < count; i ++) {
ackflag = (i < (count-1)) ? 1:0; buf[i]
= drv_i2c_readbyte(ackflag);
}
drv_i2c_stop(); return ret;
}
void TRS55D_IIC_Write(uint8_t addr_dev, uint8_t addr_reg, uint8_t *buf, uint16_t count)
{
uint16_t i = 0; drv_i2c_start();
drv_i2c_select_dev(addr_dev,DRV_I2C_OPWR); drv_i2c_writebyte(addr_reg);
for (i = 0; i < count; i ++)
{ drv_i2c_writebyte(buf[i]);
}
drv_i2c_stop();
}
typedef union{
int16_t i16; uint16_t u16; struct {
uint8_t u8l; uint8_t u8h;
}un;
}uu16_t;
typedef union{
int32_t i32; struct {
uint8_t u8b0; uint8_t u8b1; uint8_t u8b2; uint8_t u8b3;
}un;
}uu32_t;
static char buffer[264];
uu32_t obj,tmp_3, vtp_cor;
float tamb_temp ,vtp_cor_uv ,Tobj_temp ;
#include "FW_TRS_CAL.h"
uint16_t t_objx10_u16;
int16_t Tambx10_u16;
void Trs_Read(void)
{
uint8_t rbuf[4];
uint8_t raddr, rdat;
uint8_t waddr = 0x0, wdat = 0x0;
int timeout=0;
waddr = 0x30;//CMD
wdat = 0x09;//0x0000 1 FSM 001 单通道连续转换
TRS55D_IIC_Write(TRS_ADDR_AD, waddr, &wdat,1); //start conversion 模式使能
delay_ms(10);
raddr = 0x03;//原始数据地址
do {
TRS55D_IIC_Read (TRS_ADDR_AD, raddr, &rdat,1);
} while(((rdat == 0xFF) || (!(rdat & 0x30))) && timeout++ < 100);//全真为真
//flag置1 结果为真 取反为假跳出循环
raddr = 0x02;//经过校准后的数据地址
do {
TRS55D_IIC_Read (TRS_ADDR_AD, raddr, &rdat,1);
} while(((rdat == 0xFF) || (!(rdat & 0x0B))) && timeout++ < 200);
//flag置1 结果为真 取反为假跳出循环
delay_ms(50);
raddr = NORMAL_DATA1_MSB_R;//0x19 通道1校准后adc数据
TRS55D_IIC_Read (TRS_ADDR_AD, raddr, &rbuf[0],3);
vtp_cor.un.u8b2 = rbuf[0];
vtp_cor.un.u8b1 = rbuf[1];
vtp_cor.un.u8b0 = rbuf[2];
if (vtp_cor.un.u8b2 & 0x80) {
vtp_cor.un.u8b3 = 0xFF;
}else {
vtp_cor.un.u8b3 = 0x00;
}
float vt_cor = 524288;
vtp_cor_uv = (float)vtp_cor.i32/vt_cor;//vtp_cor_uv=DATA1/2^19(±16mV)=vtp_cor.i32/vt_cor
vtp_cor_uv *= 1000.0;
raddr = NORMAL_TEMP_MSB_R;//0x16环境校准后温度
TRS55D_IIC_Read (TRS_ADDR_AD, raddr, &rbuf[0],3);
tmp_3.un.u8b2 = rbuf[0];
tmp_3.un.u8b1 = rbuf[1];
tmp_3.un.u8b0 = rbuf[2];
if (tmp_3.un.u8b2 & 0x80) {
tmp_3.un.u8b3 = 0xFF;
}else {
tmp_3.un.u8b3 = 0x00;
}
raddr = NORMAL_Tobj_MSB_R;//0x10 dsp处理数据据
TRS55D_IIC_Read (TRS_ADDR_AD, raddr, &rbuf[0],3);
obj.un.u8b2 = rbuf[0];
obj.un.u8b1 = rbuf[1];
obj.un.u8b0 = rbuf[2];
if (obj.un.u8b2 & 0x80) {
obj.un.u8b3 = 0xFF;
}else {
obj.un.u8b3 = 0x00;
}
Cal_get_temp(tmp_3.i32,1000,obj.i32,1000,&Tambx10_u16,&t_objx10_u16);
Tobj_temp = (float)t_objx10_u16/10;
tamb_temp = (float)Tambx10_u16/10;
sprintf(buffer, "vtp_cor = %7.2fμV, Tobj = %5.2f℃ , tamb = %5.2f℃\r\n"\
,vtp_cor_uv,Tobj_temp,tamb_temp);
uartSendString(buffer);
小结
为了能让使用者快速熟悉和上手,领麦微原厂还配套了Demo板,这个是用于对他们各型号传感器进行评估测试。测量结果会在屏幕上显示,也可以通过 USB 转串口打印到 PC 端串口调试软件。如下两图所示,超级好用。