电子工程师技术服务社区
公告
登录
|
注册
首页
技术问答
厂商活动
正点原子
板卡试用
资源库
下载
文章
社区首页
文章
【Crazyflie 2.1开源无人机试用连载】激光测距模块调试
分 享
扫描二维码分享
【Crazyflie 2.1开源无人机试用连载】激光测距模块调试
开源无人机
激光测距
瑟寒凌风
关注
发布时间: 2021-07-23
丨
阅读: 2184
Crazyflie 2.1无人机上使用的激光测距是VL53L1X。 # VL53L1X VL53L1X属于ST公司推出的激光测距传感器。它是市面上较快的微型ToF传感器,快速测距频率高达50 Hz,可在4m范围内精确测距。它采用微型回流焊封装,集成了集成了一个单光子雪崩二极管接收阵列、940nm不可见1类激光发射器、物理红外滤光片和光学器件,在各种环境照明条件(带各种盖片选项)下实现最佳的测距性能。与传统的IR传感器不同,VL53L1X使用ST最新一代ToF技术,可测量在任何目标颜色和反射率时的绝对距离。 ![](https://cf04.ickimg.com/bbsimages/202107/46b84b4790131cc282b2f053a80e5325.jpg) VL53L1X运行高级数字固件的低功耗微控制器,快速、精确的远程测距。它还能通过对接收阵列上兴趣区的大小和位置进行编程来降低传感器FoV和从主机进行多区域操作控制。 他的工作原理很简单,发射激光到反射物,激光折射回来给接收元件,然后VL53L1X内部计算出时间和距离最后通过stm32单片机进行使用。 ![](https://cf04.ickimg.com/bbsimages/202107/f62dc6a8aa972f373c6536be06580211.jpg) VL53L1X的数据传输使用IIC协议,主机客户应用程序正在使用 api控制VL53L1X设备。 # API的简易说明 api向客户应用程序公开了一组高级功能,允许控制 vl53l0x 固件 (fw), 如初始化 /校准, 测距,精度的选择,测距模式的选择。api是写好的函数,可实现最终用户应用程序的快速开发 , 而不会使直接多寄存器访问变得复杂。api 的结构使其可以通过隔离良好的平台层在任何类型的平台上进行编译。 Api中有3种测距模式,其中单测距模式适合调试使用,他在api函数执行一次,获取一次数据,然后系统自动参会sw待机状态,测试模块时使用这个模式方便调试;连续测距模式时在调用api后以连续的方式执行,每一次的测量完成后自动调用下一次得测量,其中的间隔时间可以由用户设置,必须经过用户停止才能返回到sw模式,相当于是一个循环测量;定时范围模式,也是连续测量,但是在车辆过程中通过软件设置一个时间,达到时间后自动停止,适合自动化控制。 # 校准 为了优化系统的动态,必须对参考spad进行校准。在初始制造校准过程中,只需执行一次参考spad校准,然后校准数据就应存储在主机上。初始化和校准阶段在第一次测距之前或设备重置之后执行,用户可能必须定期重复温度校准阶段。 温度校准是对两个参数 (vhv和相位cal) 的校准,这两个参数与温度有关。这两个参数用于设置设备灵敏度。校准应在初始制造校准过程中进行,当温度变化超过 8°c时,必须再次进行校准。 测距相位由范围设置和范围测量组成。在测距操作中,发射了多个 vcsel 红外脉冲,然后由目标对象反射回来,并被接收阵列检测到。一个范围的典型计时预算是 33 毫秒 (初始化/测距/内务处理),实际范围测量采用 23 毫秒。最小范围测量周期为8毫秒。最大值为5秒。计时预算越长, 精度和测距距离能力就越高。 # 代码 先写两个延时函数 ```c void delay_us(u32 nus) { u32 temp; SysTick->LOAD=nus*fac_us; SysTick->VAL=0x00; SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; do { temp=SysTick->CTRL; }while((temp&0x01)&&!(temp&(1<<16))); SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; SysTick->VAL =0X00; } void delay_ms(u16 nms) { u32 temp; SysTick->LOAD=(u32)nms*fac_ms; SysTick->VAL =0x00; SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; do { temp=SysTick->CTRL; }while((temp&0x01)&&!(temp&(1<<16))); SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; SysTick->VAL =0X00; } ``` 激光测距模块的初始化 ```c VL53L1_Error VL53L1_init(VL53L1_Dev_t *pDev) { VL53L1_Error Status = VL53L1_Error_NONE; VL53L1_Dev_t *pMyDevice = pDev; pMyDevice->I2cDevAddr = 0x52; pMyDevice->comms_type = 1; pMyDevice->comms_speed_khz = 400; VL53l1_GPIO_Init(); VL53L1_I2C_Init(); XShut_Off; delay_ms(30); XShut_On; delay_ms(30); Status = VL53L1_WaitDeviceBooted(pMyDevice); if(Status!=VL53L1_Error_NONE) { printf("Wait device Boot failed!\r\n"); return Status; } delay_ms(2); Status = VL53L1_addr_set(pMyDevice, 0x54); if(Status!=VL53L1_Error_NONE) { printf("set addr failed!\r\n"); return Status; } Status = VL53L1_DataInit(pMyDevice); if(Status!=VL53L1_Error_NONE) { printf("datainit failed!\r\n"); return Status; } delay_ms(2); Status = VL53L1_StaticInit(pMyDevice); if(Status!=VL53L1_Error_NONE) { printf("static init failed!\r\n"); return Status; } Status = VL53L1_SetDistanceMode(pMyDevice, VL53L1_DISTANCEMODE_LONG); //short,medium,long if(Status!=VL53L1_Error_NONE) { printf("set discance mode failed!\r\n"); return Status; } delay_ms(2); return Status; } ``` 设置模式 ```c VL53L1_Error VL53L1_set_mode(VL53L1_Dev_t *dev, uint8_t mode) { VL53L1_Error status = VL53L1_Error_NONE; delay_ms(2); status = VL53L1_PerformRefSpadManagement(dev); if(status!=VL53L1_Error_NONE) { printf("refspad failed!\r\n"); return status; } delay_ms(2); status = VL53L1_SetDistanceMode(dev, VL53L1_DISTANCEMODE_LONG); if(status!=VL53L1_Error_NONE) return status; delay_ms(30); status = VL53L1_SetLimitCheckEnable(dev,VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE,1); if(status!=VL53L1_Error_NONE) return status; delay_ms(2); status = VL53L1_SetLimitCheckEnable(dev,VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,1); if(status!=VL53L1_Error_NONE) return status; delay_ms(2); status = VL53L1_SetLimitCheckValue(dev,VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE,Mode_data[mode].sigmaLimit); if(status!=VL53L1_Error_NONE) return status; delay_ms(2); status = VL53L1_SetLimitCheckValue(dev,VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,Mode_data[mode].signalLimit); if(status!=VL53L1_Error_NONE) return status; status = VL53L1_SetMeasurementTimingBudgetMicroSeconds(dev,Mode_data[mode].timingBudget); if(status!=VL53L1_Error_NONE) return status; delay_ms(2); status = VL53L1_SetInterMeasurementPeriodMilliSeconds(dev, 500); if(status!=VL53L1_Error_NONE) { printf("SetInterMeasurementPeriodMilliSeconds failed!\r\n"); return status; } delay_ms(2); status = VL53L1_StartMeasurement(dev); if(status!=VL53L1_Error_NONE) { printf("start measurement failed!\r\n"); return status; } return status; } ``` 获取值 ```c VL53L1_Error VL53L1_single_test(VL53L1_Dev_t *dev,VL53L1_RangingMeasurementData_t *pdata) { VL53L1_Error Status = VL53L1_Error_NONE; u8 isDataReady = 0; Status = VL53L1_GetMeasurementDataReady(dev,&isDataReady); if(Status != VL53L1_Error_NONE) return Status; if(1 == isDataReady) { Status = VL53L1_GetRangingMeasurementData(dev, pdata); Distance = pdata->RangeMilliMeter; } Status = VL53L1_ClearInterruptAndStartMeasurement(dev); return Status; } void VL53L1_general_start(VL53L1_Dev_t *dev,uint8_t mode) { VL53L1_Error Status=VL53L1_Error_NONE; uint8_t i=0; while(VL53L1_set_mode(dev,mode)) { i++; if(i==2) return; } while(Status==VL53L1_Error_NONE) { Status = VL53L1_single_test(dev,&VL53L1_data[0]); } delay_ms(50); } ``` 其中main函数如下 ```c extern VL53L1_Dev_t VL53L1_dev[]; extern VL53L1_RangingMeasurementData_t VL53L1_data[2]; int main() { uint8_t mode = 0; uint8_t Status = 0; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); uart_init(9600); delay_init(); Status = VL53L1_init(&VL53L1_dev[0]); VL53L1_set_mode(&VL53L1_dev[0],mode); while(1) { Status = VL53L1_single_test(&VL53L1_dev[0],&VL53L1_data[0]); if(Status==VL53L1_Error_NONE) { printf("Distance=%4d\r\n",Distance); } delay_ms(100); } return 0; } ```
原创作品,未经权利人授权禁止转载。详情见
转载须知
。
举报文章
点赞
(
0
)
瑟寒凌风
关注
评论
(0)
登录后可评论,请
登录
或
注册
相关文章推荐
MK-米客方德推出工业级存储卡
Beetle ESP32 C3 蓝牙数据收发
Beetle ESP32 C3 wifi联网获取实时天气信息
开箱测评Beetle ESP32-C3 (RISC-V芯片)模块
正点原子数控电源DP100测评
DP100试用评测-----开箱+初体验
Beetle ESP32 C3环境搭建
【花雕体验】16 使用Beetle ESP32 C3控制8X32位WS2812硬屏之二
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回
我要举报该内容理由
×
广告及垃圾信息
抄袭或未经授权
其它举报理由
请输入您举报的理由(50字以内)
取消
提交