2024艾迈斯欧司朗竞赛 - 基于TMF8821的液体分辨装置
该项目使用了TMF8821和RP2040游戏机,实现了液体种类分辨的设计,它的主要功能为:分辨液体种类。
标签
RP2040
TMF8821
2024艾迈斯欧司朗竞赛
obrulviser
更新2025-03-10
73

2024艾迈斯欧司朗dToF传感器光电设计竞赛

--基于飞行时间的液体分辨装置


一、项目介绍

本项目依托2024艾迈斯欧司朗dToF光电传感器设计竞赛,使用比赛官方的RP2040游戏机作为主控,驱动开发TMF8821传感器,基于上位机-受控端配合运行的模式,实现了一套液体种类分辨装置,可以分辨可乐、水、运动饮料等液体。


项目内容:

1、驱动TMF8821传感器。

2、设计一套液体检测装置。

3、采集各液体数据,设计一套分辨算法。


应用场景:

本项目为一折射率测试仪的简单样例,基于光学路径的不同,可以实现对固液气等处于不同物质形态的不同物质进行折射率测量。由于其基于激光的飞行时间来测量折射率,为一典型的非接触式测量,同时激光能量低、反应速度快、不易对待测物品造成损伤。可以用于液体的防污染检测,空气湿度检测等场景。


硬件介绍

本项目使用的传感器板和主控板如图所示。主控板为RP2040游戏机,基于树莓派基金会的RP2040芯片,板载屏幕、按键、摇杆等外设,同时还有红外对管等传感器。本次使用的传感器为TMF8821,TMF8821 是一款直接飞行时间 (dToF) 传感器,采用单个模块化封装,带有相关的 VCSEL。dToF 设备基于 SPAD、TDC 和直方图技术,可实现 5000 mm 的检测范围。由于它的镜头位于 SPAD 上,它支持 3x3、4x4 和 3x6 多区域输出数据以及宽广的、动态可调的视野。VCSEL 上方的封装内的多透镜阵列 (MLA) 拓宽了 FoI(照明场)。原始数据的所有处理都在片上进行,TMF8821在其 I2C 接口上提供距离信息和置信度值。



二、传感器驱动

基于官方要求,该传感器不能使用官方驱动,需要根据通信手册和数据手册编写传感器驱动。本文采用的编程环境为pico-sdk 2.1

2.1自定义I2C通信函数

通信手册用多个字母表示各种对i2c总线的通信操作及数据,如图。


综合全手册,i2c的操作有寄存器单字读写,寄存器多字读写。其中寄存器多字写仅有下载固件部分有使用,且数据要多次拼接,单独为该部分实现寄存器多字写价值不大。因而i2c工具实现寄存器单字读写和寄存器多字读。




单字写最为简单,根据手册形式大致为,即写寄存器和数值即可。


可见为i2c总线的单次写操作,将寄存器和写数值拼接,调用i2c库的写函数即可。

void i2c_write_byte(uint8_t reg, uint8_t data)
{
uint8_t buf[2] = {reg, data};
i2c_write_blocking(I2C_PORT, I2C_ADDRESS, buf, 2, false);
}

单字和多字读寄存器操作大致相同,都是首先写寄存器值,不释放,读所需要的位数。


调用一次i2c的写函数,一次i2c的读函数即可。此处单字和多字略有不同,单字采取的是返回值,多字直接传入指针。

// I²C读一个字节
uint8_t i2c_read_byte(uint8_t reg)
{
uint8_t data;
i2c_write_blocking(I2C_PORT, I2C_ADDRESS, &reg, 1, true); // 发送寄存器地址
i2c_read_blocking(I2C_PORT, I2C_ADDRESS, &data, 1, false); // 读取数据
return data;
}
// I²C读多个字节
void i2c_read_bytes(uint8_t reg, uint8_t *data, uint8_t size)
{
i2c_write_blocking(I2C_PORT, I2C_ADDRESS, &reg, 1, true); // 发送寄存器地址
i2c_read_blocking(I2C_PORT, I2C_ADDRESS, data, size, false); // 读取数据
}

后文中,采用r(reg)和rs(reg,data)代表读单字和多字,w(reg,data)代表写单字,ws(reg,data)代表写多字。其中reg代表寄存器,data代表数据。

2.2 上电

根据手册1.2.1,该传感器使用步骤大致如下


本章主要涉及前4条,即bootloader之前的部分。

首先上电,然后记得拉高传感器的en管脚(第一条和第二条)

第三条是向0xe0寄存器写入0x01,即 w(0xe0,0x01)

第四条如图,循环读使能寄存器0xe0,直至返回0x41,即循环r(0xe0),直到读取到0x41。手册2.1还列出了其他几种情况,请自行阅读并区分。


此时,传感器应当进入bootloader模式,读取0x00寄存器(APPID_REG),值应当为0x80。即r(0x00),返回值应为0x80。

2.3 bootloader

这部分流程请仔细阅读通信手册3.2,第13页和14页,此处附上手册中的流程图。




首先,发送DOWNLOAD_INIT指令,手册中是下图,即ws(0x08,{0x14,0x01,0x29,0xc1})


然后读CMD_STAT寄存器,直至该寄存器状态为READY,返回0x00 0x00 0xff。手册中如下图。即循环调用函数rs(0x08,data,3),直到data[2]是0xff。这部分检查CMD_STAT寄存器操作的部分后面常用到,后文使用简称cc()。



然后Issus ADDR_RAM command,根据本文目标和手册的行文顺序,修正(简化)为下图这步。即,调用函数ws(0x08,{0x43,0x02,0x00,0x00,0xBA})。

然后,检查CMD_STAT寄存器,即,调用cc()。




此时,传感器已经做好接收固件的准备。对于下载固件,手册中描述如下。由于固件很大,不能单次下载完成,需要通过一系列W_RAM操作完成。

简而言之,就是ws(0x08,{0x41,n,hex1,hex2,... ,hexn,checksum})。其中,n代表本次下载的固件字数,单次下载的n不能大于20,hex代表固件,checksum代表本次操作的校验和。

关于校验和,手册中描述如下。

简言之,将ws中的data部分,即,{0x41,n,hex1,hex2,... ,hexn,checksum},全部相加,然后取最后两位的补码。给出计算check_sum的代码

uint8_t calculate_checksum(uint8_t cmd_stat, uint8_t size, uint8_t *data, uint8_t data_length)
{
uint16_t sum = cmd_stat + size;
for (int i = 0; i < data_length; i++)
{
sum += data[i];
}
return ~(sum & 0xFF); // 取最低字节的补码
}

每次传输完一部分固件后,都要检查CMD_STAT寄存器状态。即,调用cc()。




固件下载完成后,发送RAMREMAP_RESET指令,手册原文如下。即,ws(0x08,{0x11,0x00,0xee})



等待3ms后读取APPID寄存器,此时APPID应为0x03,传感器离开bootloader,进入应用。即,r(0x00)。

2.4 配置

请参考通信手册第21页,如下图,这里是最简易的配置步骤。本部分不会进行传感器校准。未经校准的传感器会载入默认校准数据,寄存器0x07会输出0x31或0x32报错。



首先载入默认配置,如下图。即w(0x08,0x16)

然后检查CMD_STAT寄存器状态,应返回单字0x00,即r(0x08),返回值应为0x00。本步检查后文常用,简化为c(check)。对于本步,就是c(0x00)。

需要检查配置页面是否被正确载入,如下图。即rs(0x20,data),需要data0=0x16,data2=0xbc,data3=0x00。



此时可以设定测量周期,手册给出的是100ms,即0x0064,如下图。即ws(24,{0x64,0x00})



然后是设定SPAD类型,如下图。即w(0x34,0x06)。不同SPAD类型请参考数据手册23和24页。



硬禾的传感器板板载了一颗led,可以通过本步配置使其随测量进行闪烁,如下图配置传感器的GPIO0。即,调用w(0x31,0x03)。



最后将配置写入传感器,如下图。即,w(0x08,0x15)。

检查CMD_STAT寄存器状态。即,调用c(0x00)。



使能中断,如下图。即,w(0xe2,0x02)。

清除中断,如下图。即,w(0xe1,0xff)。



至此,一个简易的测量步骤已经结束,可以开始测量。

2.5 测量

请参考手册4.5和4.5,第36页。



开始测量,命令如下。即,w(0x08,0x10)

检查CMD_STAT寄存器状态。即,调用c(0x01)注意!是c(0x01)。




现在测量已经开始,等待中断管脚产生下降沿即可,如图。请忽略第四条。

产生下降延后根据第二和第三条,需要w(0xe1,r(0xe1))

最后根据数据手册第39-40页中,appid=0x03,cid=0x10部分的寄存器定义读值即可。如,读取0x3a,即,调用r(0x3a)。

2.6 校准

手册建议传感器到手后应进行一次校准,否则会出现误差。根据本人测试,在未叠加任何光学设计之前,误差较小,因而未作校准。


三、液体分辨设计

本传感器有直方图模式,可以读取原始数据,基于此,可以应用于较复杂的光路设计中,如图1。图中液体A、B、C、D可以相同可以不同。箭头代指光路,图中仅画出第一条反射光线和最后一条,其余若干界面均会发生反射,图中忽略。根据若干个回波时间,即可得知激光在A、B、C、D中的飞行时间,进而求解折射率。

未命名文件.png

图1

由于时间问题,本设计并未采用直方图模式,即使对于定性测量而言,图1的若干反射,尤其是第一条反射光线会对传感器测量结果造成强烈干扰,重新设计装置结构如图2.将dToF与液体A的容器紧密相连,液体A容器与反射镜紧密相连,排除第一条反射光线干扰。液体容器为壁厚约1mm的塑料瓶,光路的单向长度约为80mm,因而忽略容器壁干扰。近似认为激光直接进入液体,经由反射镜反射返回传感器。

装置2.png

图2


使用装置如图2,测试多种液体,包含可乐的稀溶液,自来水,某运动饮料,结果发现各饮料距离数值差距显著,结果稳定,因而直接采用分段查找即可。参考常见液体折射率表,进行估算,水和酒精在本装置条件下伪距差距约为3mm左右,差距水平显著,符合结果数据。

四、实物图

成品装置如图所示,效果请参见视频,瓶身左侧应与传感器致密结合,此处为美观,并未增加固定装置。瓶身右侧贴有反光膜。

13205c40dec6fe24bab35129fa6bd7d.jpg


五、结论与未来

本文介绍了一种基于TMF8821和RP2040游戏机的液体分辨装置设计,成功实现了多种液体的分辨。由于数据样本不足,缺少测试仪器,不能对各液体折射率进行标定,因而本装置仅为定性测量。但是,如果传感器采用直方图模式,具有折射率测试相关仪器进行标定,本装置完全可以成为一种定量测量仪器。

附件下载
hello_usb-3.zip
团队介绍
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号