调试了LIDAR-Lite v3激光测距仪PWM驱动,在这里做一下记录。
飞控硬件是pixhawk1,PX4软件版本为1.7.3。
按照官方教程进行接线和配置,链接为 https://docs.px4.io/en/sensor/lidar_lite.html。
PWM的接线方式为:
这里接了 AUX_PWM 的 CH6 来供电,接 CH5 进行 PWM 捕获。而实际上飞控的 AUX_PWM 是不带电的,除非有 BEC 接入,没有的话需要将供电口接入其他接口上的 5V 电源,比如 I2C 口的 5V 电源就可以。
LIDAR-Lite v3激光测距仪PWM模式的工作原理是,当激光测距仪的PWM输出引脚被拉低时,就向外输出一个脉冲信号,其脉宽就表示测距数值,10us/cm。如图接线,将①接飞控的GND,②接飞控的PWM采集口,就可以利用PWM捕获方式来获取脉冲信号的脉宽进而得到测距数值。
在rc.sensors启动文件中,对应的启动脚本为:
# Sensors on the PWM interface bank
if param compare SENS_EN_LL40LS 1
then
if pwm_input start
then
ll40ls start pwm
fi
可以看到,当设定参数SENS_EN_LL40LS = 1时,会执行脚本 pwm_input start 和 ll40ls start pwm,前者打开PWM输入的对应线程,后者打开LIDAR-Lite v3激光测距仪的对应线程。
在 src/drivers/pwm_input/pwm_input.cpp 文件中, pwm_input start 脚本实际调用了 pwmin_start() 函数,建立一个 PWMIN 类的例程; PWMIN::init() 函数建立一个深度为2的循环队列,与上一篇的作用类似,可以实现在多线程间异步读取; PWMIN::open() 函数会进行调用 PWMIN::_timer_init() 函数进行定时器设定,设定工作模式为PWM捕获模式,需要利用定时器的两个通道,让定时器的计数间隔为1us,向上计数模式,最大值为0xFFFF;当定时器获取到一个新的上升沿时,触发中断,进入中断服务函数 pwmin_tim_isr() ,在这里读取了上一个上升沿到本次上升沿的时间 period,中间经历的高电平脉宽 pulse_width,以及中断状态 status,并发布 pwm_input 消息;而 PWMIN::read() 函数则是从上述长度为2的循环队列中读取数据,其原理在上一篇中已经说明。
定时器中断一旦设定好之后就会由外部 PWM 输入事件触发,不受系统调度控制,当中断事件发生时,中断服务函数就会被调用。因此发布 pwm_input 消息的频率是由外部 PWM 输入事件决定的。
在 src/drivers/ll40ls/LidarLitePWM.cpp 文件中,读取测距数值的代码是 LidarLitePWM::collect() 函数,首先进行 ::open() 打开设备,实际上就是上面的 PWMIN::open() 函数,如果没有打开过就会设定时器,已经打开过了就继续运行不再设定,利用 ::read() 来读取数据,实际调用 PWMIN::read() 上面已经说明。
在 LidarLitePWM 进行数据读取时按照设定的周期进行的,原理与上一篇相同,就是反复将读取函数加入 work_queue(),由此可见,中断进行数据读取和这读取的数据实际是不同步的。