低成本3D空间导航/测绘机器人(2)——基于STM32+A4950芯片的机器人里程驱动设计

332
5
2021年2月4日 09时49分

写在前面

 

在上一节中我们讲到了测绘小车的基本架构。今天我们来一起学习机器人的下位机。

 

我们测绘小车的下位机采用STM32F103RCT6,下位机的四个基本功能为:

 

  1. 接收轮胎编码器的数据获取机器人轮胎里程,同时对轮胎进行控制
  2. 驱动两路舵机实现二维云台的控制
  3. 与Linux处理器进行通讯,执行Linux处理器的控制指令,并上传硬件状态
  4. 其他功能(电量采集,蜂鸣器,灯光控制等)

 

下面我们来学习机器人STM32对轮胎的控制:

 

基于STM32+A4950芯片的机器人里程驱动设计

 

轮胎驱动的硬件连接

 

我们使用两块A4950芯片实现对机器人两路轮胎控制电机的驱动;A4950的功能与TB6612FNG类似,不同点在于:TB6612FNG有2路Pin控制电机正反转,1路PWM输入信号(也就是说一个电机需要三个引脚控制)。而A4950使用两路输入的信号差分进行正反转和速度的控制,如下图:

 

图片1

 

我们使用下面的电路图来实现电机的驱动,其中Header6代表了两个电机的接口,其中两个电机的驱动输入分别对应STM32的PB6,PB7(左侧电机)以及PB8,PB9(右侧电机)。两个电机的编码器对应PA0,PA1(左侧电机,Timer5的CH1和CH2)以及PA2,PA3(右侧电机,TIM2的CH3和CH4)

 

图片2

 

轮胎驱动的软件设计

 

PWM输出驱动信号

 

STM32RCT6的TIM4可以生成4路独立的PWM信号,我们使用前两路的差分PWM控制左侧轮子,使用3,4路PWM控制右侧轮子。软件程序流程如下:

 

图片3

 

我们首先配置好TIM,其中包括基础TIMER与PWM功能:

 

图片4

 

PWM定时器初始化完成后,就可以使用下面这个语句控制四个通道的PWM:

 

TIM4->CCR1 =[电机1—CH1]

TIM4->CCR2 =[电机1—CH2]

TIM4->CCR3 =[电机2—CH1]

TIM4->CCR4 =[电机2—CH2]

 

完整的函数可以这样:

 

图片5

 

电机的编码器里程反馈

 

为了使轮胎控制形成闭环,必须要实现轮胎的里程计反馈。我买的机器人电机上带有正交编码器,STM32可以将一路Timer的两个捕获输入用于正交编码以获取轮子的转动方向和转动角度。

 

我们购买的电机为6端子直流减速电机(2端子为电机电源输入,4端子为编码器相关),我们以一个6线端子表示表示电机;它与STM32的连接如下:

 

图片6

 

读取编码器的数值可以采用两种不同的方法:

 

  • 使用Timer对应的正交编码器,这种方式适用于轮速非常快且编码器分辨率的机器人。
  • 使用EXTI外部中断,适用功能较为复杂(需要更多Timer)的机器人。

 

我们使用EXTI外部中断的方式来捕获机器人编码器数据:

 

图片7

 

初始化完成以后,我们可以通过以下两个中断函数获得左右轮胎编码器的数值:

 

图片8

 

注意:轮胎转速非常快,分辨率特别高时时,会出现编码器大量占用CPU资源的现象,此时我们需要想一些新的策略(不过正常情况下时不用的):

 

现在我们完成了轮胎驱动以及编码器的读取初始化,同时可以通过几个简单的函数读取到相关数值。

 

接下来我们测试以下:

首先,我们写一个测试main函数:

 

图片9

 

拿出我们的小车,使用Keil配合ST-Link的调试模式(如图,不懂的可以文末联系方式小窗我),监控轮胎的运动和编码器的状态:

 

图片10

 

微分算法——机器人电机控速巡航

 

我们通电,5秒后电机转起来了,但是用手一按就停下了。

 

这种直接用PWM控制的方式叫做开环控制,是无法精确控制速度的。为了控制电机,我们需要引入闭环反馈控制,可以理解为常见的PID控制算法。

 

传统的PID算法比较适用于小型电机,但是PID的参数调整过于困难,所以我们使用了微分算法,可以大大减少我们调参的工作量,微分算法的具体思想可以参考我之前在csdn的博客。

 

要控制机器人的定速,那么我们要实时读取机器人轮胎的数据,并进行反馈调整相关的PWM参数,如下图:

 

图片12

 

我们使用一个间隔20ms的主循环函数,来调整电机速度。

 

第一步,初始化Timer寄存器(我们用Timer2):

 

图片13

 

第二步:在Timer中加入中断程序,判断电机的实时速度:

 

图片14

 

程序中的PULSE_PER_METER对应电机转动1米输出的脉冲数。我们调试的方法测试这个值,发现轮子转一圈输出205个脉冲,而我们轮子的直径是70mm(0.07m),所以我们可以精确计算出轮子的每转动一米的脉冲数:

 

我的没米脉冲数大概为933个。但是不同的电机轮子右不同的脉冲数量。

 

第三步:反馈调节PWM占空比

 

在这里就使用了我们的微分函数(跟PID差不多),我把代码沾上来:

 

图片15

 

再配合之前的PWM控制程序,就完成了轮子的实时调速了。

 

本章小结和下节预告

 

本章我们一起学习了智能车使用STM32驱动一双轮子,一般情况下我们可以使用L298N,TB6612FNG,A4950等芯片进行轮子驱动。每个芯片的驱动方式不同,有两线和三线驱动的。

 

我们使用的A4950使用两线PWM驱动。使用一路Timer(Timer4)做PWM输出,一路Timer做电机回环控制(Timer2);两路EXTI做编码器里程计读取。

 

下一节我们将学习机器人底盘的舵机驱动与下位机/上位机的串口通讯机制。

 

发表评论

后才能评论

评论列表(5条)

  • 玉笛公子 2021年2月23日 下午2:48

    没太看明白架构,能否麻烦博主解释一下?
    我理解的总共5个中断,2个外部中断采集编码器数据,1个串口中断采集上位机指令,1个5ms中断控制pwm更新,1个20ms中断做速度闭环,但是
    问题1. 5ms中断,利用上位机速度指令,没有速度反馈?(这里更新速度目标值和读取双轮速度目标值的区别是什么?)做 PID计算,输出PWM控制轮胎电机(不太明白没有反馈怎么做的PID计算)
    2.为了精确控制速度,所以又加了一个20ms TIM中断,用微分算法,算出更精确的PWM,那么20ms中断中利用编码器反馈换算车轮速度,是直接拿外部中断的编码器数据,还是采用定时器去采集的呢 ?
    4.20ms主循环跟软件架构图的循环主函数是一个嘛?
    3.博主提到外部中断这种方法不适合高速时使用,那么高速时的解决办法是什么呢?与定时器正交编码方式齐用嘛?

    • 麻辣小蘑菇 回复 玉笛公子 2021年2月25日 下午1:45

      1. pwm 不依赖中断,用的是timer捕获输出
      2. 速度反馈在串口中断的处理函数里(下一节有介绍)
      3. 速度控制直接用中断的,每次中断编码器变量++
      4. 高速轮会一直在中断里边卡死,解决方案使用Timer高级定时器的正交捕获

  • 7k5ya_8858 2021年2月4日 下午7:53

    博主建议你做个配置清单,如果有需要的,可以邮件提供购买链接