1、硬件设计:

2、代码实现
项目主控使用的是ESP32S3,直接使用了库文件:vl6180x-arduino-master 进行实现,具体如下:
2.1、创建一个结构体,用于保存各个激光探头的数据,及相关需要用到的参数,如状态等
//激光探头信息
typedef struct
{
uint8_t tof0_action = 80; //0#激光(右),感应阈值
uint8_t tof1_action = 80; //1#激光(左),感应阈值
uint8_t tof2_action = 100; //2#激光(下),感应阈值
uint8_t tof3_action = 100; //3#激光(下),感应阈值
uint8_t ignore_dis = 10; //盲区距离设置
uint8_t result_garbage; //垃圾处理器动作
uint8_t result_shark; //手扬开关水动作
uint8_t result_real; //即时开关水动作
uint8_t result_unlock_real; //即时开关水解锁动作
} tof_message;
tof_message tofs;
2.2、多从机模式下的参数配置
//多从机模式下:
const uint8_t sensorCount = 4; // 设置激光探头从机数量;
const uint8_t xshutPins[sensorCount] = {17, 16, 18, 19}; // 指定从机复位引脚;
VL6180X sensors[sensorCount]; //创建一个带有sensorCount个从机的激光探头组;
// 依次表示:static uint8_t distance_SIde0, distance_SIde1, distance_Under0, distance_Under1;
static uint8_t distance_ToF[sensorCount]; //用于缓冲激光探头触发阈值; 上电时读取保存值,调距后需保存数据;
2.3、激光探头初始化
/* VL6180x初始化 */
uint8_t VL6180x_init()
{
uint8_t result_de = 0; //缓存初始化结果//缓存初始化结果; result_de: 按位读取,最多支持8个从机设备;
//先执行硬件iic串口初始化********************************************************
while (!Serial)
{
}
//Serial.begin(115200); //不在这里设置
Wire.begin(20, 21);
Wire.setClock(400000); // use 400 kHz I2C
//按iic设备,逐个完成初始化, 每个iic设备最多执行N次初始化*******************************
for (uint8_t i = 0; i < sensorCount; i++)
{
//对第i+1个设备执行初始化操作,最多执行N=30次;
if (result_de & (1 << i))
{
//为真,已经初始化过了,不需要再执行
// sensor.init();
// sensor.configureDefault();
// sensor.setTimeout(500);
}
else
{
//为假,还没初始化成功,执行初始化
pinMode(xshutPins[i], OUTPUT);
digitalWrite(xshutPins[i], LOW); //拉低复位引脚;
delay(10); //延时一定时间,确保硬件能完成复位动作,时间可根据实际硬件电路调整;
pinMode(xshutPins[i], INPUT_PULLUP); //iic设备端已经上拉了,转换为输入模式,此时电平及电器强度由外部上拉下拉电阻决定,好处是不会对iic硬件电平产生影响,适合不支持开漏输出的gpio引脚;
delay(10); //延时一定时间,确保硬件能进入FW待机模式, 时间可根据实际硬件电路调整;
sensors[i].init(); //执行初始化;
sensors[i].configureDefault();
sensors[i].setTimeout(500);
// if(i == 2 || i == 3){
// sensors[i].setScaling(2); //dibu2倍放大加测,最远31cm;
// }
sensors[i].setAddress(0x2A + i);
result_de = result_de | (1 << i); //重写初始化结果
}
}
//底部探头放大检测:
//VL6180X_WriteBytes(DEV_ADDR, 0x0097, 0x7F); //加大检测距离
//VL6180X_WriteBytes(DEV_ADDR, 0x00a3, 0x28); //加大检测距离
//VL6180X_WriteBytes(DEV_ADDR, 0x00bb, 0x28); //加大检测距离
//设置收敛距离
//VL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSRANGE_EARLY_CONVERGENCE_ESTIMATE, 0x01);
//VL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSRANGE_EARLY_CONVERGENCE_ESTIMATE + 1, 0x7F);
//底部探头放大检测:
sensors[2].writeReg(0x0097, 0x7F);
sensors[2].writeReg(0x00a3, 0x28);
sensors[2].writeReg(0x00bb, 0x28);
//设置收敛距离
sensors[2].writeReg16Bit(0x0022, 0x017F);
//VL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSRANGE_RANGE_CHECK_ENABLES, 0x10 | 0x01); // enable (0x01) early convergence estimate
sensors[2].writeReg(0x002D, 0x10 | 0x010); //关闭早期收敛
//底部探头放大检测:
sensors[3].writeReg(0x0097, 0x7F);
sensors[3].writeReg(0x00a3, 0x28);
sensors[3].writeReg(0x00bb, 0x28);
//设置收敛距离
sensors[3].writeReg16Bit(0x0022, 0x017F);
//VL6180X_WriteBytes(DEV_ADDR, VL6180X_SYSRANGE_RANGE_CHECK_ENABLES, 0x10 | 0x01); // enable (0x01) early convergence estimate
sensors[3].writeReg(0x002D, 0x10 | 0x00); //关闭早期收敛
return result_de;
}
2.4、测距
这里使用的是单次测距的方式,连续测距类似,直接调用api读取即可。
//先所有探头执行一次单次测量
for (uint8_t i = 0; i < sensorCount; i++)
{
sensors[i].Start_RangeSingle(); //发起单次测距
}
2.5、后话,注意事项:
实际使用中,需要注意在做EFT测试或环境干扰比较大的情况下,激光模块可能 工作异常(复位等),无法应答IIC,此时需要按需重新对失效的模块执行一下初始化,已确保模块工作正常。

1万+

被折叠的 条评论
为什么被折叠?



