APM测量转速

        笔者用的是4.1.1版APM代码,霍尔传感器检测到磁极通过从5V变化0V。

一、源码分析

        先用类图分析。

        

        AP_RPM是前端类,包含AP_RPM_Backend子类。每个具体的实现方式(光流,霍尔传感器等)继承AP_RPM_Backend类,在AP_RPM初始化的时候能根据参数初始化对应的子类,这是C++动态编译的一种特性,也是相对与c语言的一种优势。

        

        具体实现代码如图所示。new一个对应的对象,并将指针地址存如drivers数组中。通过drivers指针数组访问对应实例化对象的update函数。该类的初始化见init_ardupilot()函数。函数调用流程见下图:

        

        rpm_update()函数通过调度器每40Hz调用一次。 

        笔者是霍尔传感器,因此实例化的对象是AP_RPM_Pin(这里由参数控制,具体见第二大点)。故分析AP_RPM_Pin::update()函数。

        

        在AP_RPM_Pin::update()中完成GPIO端口配置,中断设置。get_pin()获取GPIO引脚号,该号码在这个文件定义。这里边有个坑,笔者一开始设置成54,按文件的定义,应该是PWM5触发中断,实际上触发不了中断,后来设置到62,PWM13才成功触发。  

        通过hal.gpio->attach_interrupt()函数设置中断函数,由于笔者的霍尔传感器触发下降沿,因此这里设置成下降沿中断。      

        irp_state[state.instance].dt_count在中断函数被赋值,两次中断时间间隔在100us到1s之间,该值加1。故测量的转速范围在[60,600000]rpm。见中断函数irq_handle();

        转速的计算方法见这里

二、参数设置

         这里的参数设置与代码版本有关,笔者用的是4.1.1版的代码,故有BRD_PWM_COUNT参数,将该参数设置成4。意为4个PWM输出。

        

        接着设置RPM库的参数。

                 

         RPM最多实例化两个对象,因此这里只能设置RPM和RPM2的参数。RPM_TYPE对应着_type[i]变量,在AP_RPM::init()函数中使用,决定着实例化什么子类。

        RPM_PIN设置GPIO引脚编号,get_pin()函数会返回该引脚编号。编号定义见这里。

三、试验结果

        

参考文献 :RPM Measurement — Copter documentation

                   ardupilot/libraries/AP_HAL_ChibiOS/hwdef at master · ArduPilot/ardupilot · GitHub

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值