VL53L0X是TOF(Time Of Flight)传感器,字面上就是测量光线(激光)传播(飞行)的时间,来计算传感器到障碍物之间的距离的,就是下面这个小东西。
记录Arduino下使用它的几个要点。
一、所使用的库
有现成的库,库中搜索VL53L0X能找出来第三方的库(Vl53L0X by Pololu)。库写的挺好的,基本就是拿来就能用的那种。
二、使用中遇到的问题
该库有一个问题,其依赖于I2C库Wire.h,项目使用的时候,如果要多个I2C总线,库中没有说明怎么整。所以不得不研究下Arduino环境ESP32使用多条I2C总线的问题。
I2C总线有2种驱动方式,一种是硬件I2C,一种是软件I2C,这个在之前的一篇文章(micropython下如果使用ESP32的硬件I2C总线驱动OLED屏幕)中讲到过,关于区别可自行研究一下。
micropython使用了颇长时间,写代码挺高效的,但是后来遇到了LVGL移植的瓶颈,不得不放弃了micropython转而使用Arduino。
1.ESP32是有两条硬件I2C总线的,乐鑫提供的Wire库是直接调用硬件I2C的库
软件I2C驱动的方式,乐鑫并没有提供,Arduino第三方库中能搜到一些软件I2C的库,可自行移植,不是本文重点。
2.Wire库中其实直接把两条I2C总线对象给了出来
打开Wire.h,最后几行的定义能看到:
extern TwoWire Wire;
extern TwoWire Wire1;
这个Wire和Wire1就是对应0号I2C和1号I2C总线的对象,只要#include <Wire.h>,就能在代码中直接使用这两个对象了。
3.修改VL53L0X所使用的总线号
VL53L0X示例代码中选择的是0号总线,代码中
Wire.begin();
就是使用Wire.h中定义的第一个I2C总线对象。
如果要使用1#总线,那修改为
Wire1.begin();
好像就行了。
但是好像还缺点什么。全览VL53L0X示例代码,好像没有一行代码是把I2C总线与VL53L0X进行关联的。所以,还是打开VL53L0X.cpp源码再看看,找到如下线索:
#include <Wire.h>
.........
VL53L0X::VL53L0X()
: bus(&Wire)
, address(ADDRESS_DEFAULT)
, io_timeout(0) // no timeout
, did_timeout(false)
{
}
.........
这个构造函数居然把VL53L0X所使用的I2C总线写死成了第一条总线“Wire”。
注意文件头引用了Wire.h,那么无疑函数bus(&Wire)这行里的Wire指的就是第一条I2C总线。
既然如此了,要使用第二条总线最简单的方法就是把这行的Wire修改成Wire1咯。或者心情好点就修改构造函数为带参数的,把Wire或者Wire传进去,方便选择。
4.I2C引脚
Wire.cpp中关于begin方法的定义可以打开看一下,可以用传引脚参数,如果不传的话就是默认引脚,默认引脚可以在esp32的手册中查到。最好自己指定,如:
Wire1.begin(42,41);//使用第二条总线,SDA=42脚,SCL=41脚
如果接线没有任何问题,你的VL53L0X应该能跑得很欢快了。精度还是挺高的,厘米级别。用途挺多,用来精确测量个什么十几厘米长度的什么东西啦,或者水位啦什么的都可以。
至于VL53L0X.cpp里面每行代码操作什么寄存器做什么运算,我想我只是应用它,解决遇到的问题,并不需要都搞懂。