本帖最后由 ntboss 于 2016-12-26 13:16 编辑
前段时间应为感冒原因中断了一下这个开发板的试用,真是不好意思,现在奉上最近把玩的成果。 下面同样分2部分进行,分别是手势识别原理探讨和VCNL4020程序驱动。 第一部分:手势识别原理 首先先搞明白这个VCNL4020到底是如何进行手势识别的。打开附送的资料查看一下其实现原理。
资料是英文的,借助百度翻译,大致弄明白了其原理。我大概归纳了一下,如果有说的不对的地方,欢迎大伙纠正。 VCNL4020其实是一个结合近距离感应和环境亮度感应的传感器,其对距离和环境光强的量化精度均为16位。简单点来说,它可以将物体距离传感器表面的距离,转化为0~65535的数值输出,距离越近,输出数值越大。同时,也可将环境光的亮度转化为0~65535的数值输出,光线越强,数值越大。这两个传感器的数值是分别保存在不同的寄存器中的。两者可以同时进行转换。 那么,光靠这两个传感器就能进行手势识别吗?当然是不行的。识别手势,必然有一个识别运动方向的问题。前后好识别,依靠距离感应就可以了,左右的话,就要另辟蹊径了。 实现原理很简单。在传感器两侧放置2颗LED,当手从左到右滑过时,手距离2个LED的距离在不断的发生变化(距离每个LED有一个由远到近再到远的过程),其产生的漫反射到达传感器,必然会检测到2次亮度变化。再结合2个LED的发光过程,就能识别出运动方向了。
然而我们的开发板上并为携带LED组件,只有1个VCNL4020,因此暂时就不能做手势识别了,但我们可以先将此传感器的程序驱动初步搞通。 第二部分:VCNL4020驱动详解 我电脑已经安装了Keil MDK,因此接下来的软件过程都在这个平台上进行。 打开资料附带的例程,定位到程序入口main,结合传感器手册,一步一步进行分析。 VCNL4020使用IIC总线进行数据交互,关于IIC的原理这里不再赘述。IIC的程序实现多种多样,例程使用一种比较独特的写法:将要发送的数据放入txData数组,并用txSize标明发送的数据总数,同样的将收到的数据放入rxData数组,rxSize标明要收到的数据字节数,最后将这些参数作形参传入SetupXferRecAndExecute函数进行一次IIC通信。 底层通信写好了,重点关注上层实现。任何器件在使用前都有一个初始化的过程。VCNL4020的初始化过程还是很简单的。 首先,设置VCNL4020内部LED(用作距离感应)的电流值。这个值是以10mA作为基本单位的,寄存器地址为83H,可设范围为0-20,对应LED电流为0-200mA。值越大,感应距离约远。 用程序实现起来是这样: 每次设置需要进行一小段时间延时,这个延时不需要很长,程序中只延时了约100个指令周期。 设置好电流后,开始设置功能。功能使能寄存器在80H。 这个寄存器很重要,我们来看一下这个寄存器每个位分别表示什么意思。 Bit 7:只读位,恒为1 Bit 6:环境亮度数据转换完毕标志位,只读,1表示亮度转换完毕,读取亮度结果寄存器会自动清零。 Bit5:距离数据转换完毕标志位,只读,1表示接近距离转换完毕,读取距离结果寄存器会自动清零。 Bit4:启动一次环境亮度转换 Bit3:启动一次距离转换 Bit2:使能环境亮度传感器 Bit1:使能接近距离检测传感器 Bit0:使能周期性测量 为了确保设置正确,先将所有功能给禁止。我设置为启动环境亮度传感器和距离检测传感器,并使用周期性测量,程序如下: 程序中使用了宏定义,定义每一个位一个名称,以提高程序可读性。 完成功能设定后,还需设置一个距离测试转换速率,寄存器地址为82H。 这个速率代表着距离测试转换的频度,我折中设置为31.25次/秒。 设置到这里,初始化已经完了,可以正常使用该模块了,是不是很简单。当然这种需要耗费一定时间进行数据转换的器件一般都有转换中断,但这里先不考虑中断,只用查询法进行数值提取。 由于开启了周期测量,每次只要判断数据是否转换完成再读取相关结果寄存器中的值就可以了,比如查询距离传感是否转换完成可以这样: 转换完成标志位在寄存器80H,之前已经介绍过相关位了,可以参考一下。环境光的转换结果保存在85H和86H中(16位数),85H保存的是高8位,86H是低8位。距离传感结果保存在87H和88H中,87H保存的是高8位。 读取结果寄存器可以像下面这样: 好了,程序分析完成,我读取了距离值和亮度值,显示在显示屏上,效果如下:
是不是和我一开始拿到主板时效果差不多了呢,哈哈! 关于此传感器的详细介绍已经完结了,下面就是将此模块用起来,欢迎大家持续关注,谢谢!
|