该篇博客紧接接上一篇开题篇创 基于stm32的两轮自平衡小车1(模块选型篇)(鸽了好些日子了…)。该篇为原理篇,包含一些理论分析的部分,碰到一些自己可能写不好的地方直接引用了我认为很不错的参考,有些地方还没能理解透彻,如有不足的地方恳请指出,非常感谢!本篇内容详见目录。

目录

  • 参考资料
  • 系统框图
  • 运动分析
  • PID算法
  • 定时器PWM输出
  • 定时器编码器模式
  • 六轴传感器获取角度

参考资料

这里有一些博主收集资料过程中发现的好东西,分享一波:
正点原子手把手教你学STM32-M3(视频)
一天攻克平衡小车(视频)
两轮平衡小车开源资料(原理图、PCB、程序源码、BOM等)
基于STM32和MPU-6050的两轮自平衡小车系统设计与实现
超详细双轮平衡小车原理分析 附STM32源码
基于stm32两轮平衡车制作
自平衡小车的入门(arduino)
参赛作品《stm32平衡小车》
基于STM32F103C8T6平衡车–从零开始
编码器速度和方向检测,stm32编码器接口模式
平衡小车中的MPU6050测量倾角
还有一篇非常经典的平衡小车原理论文,是第七届全国大学生“飞思卡尔”杯智能汽车竞赛组委会给的一套超详细的平衡小车平衡原理资料:直立行车参考设计方案第二版,也放这里了:gveh
看一下别人的作品再看看自己的,觉得自己好菜… 想不写下去了…但flag已立,不得不继续。,。

系统框图

按照我自己的理解,平衡小车的系统框图大概是这样子的一个思路:
在这里插入图片描述
获取小车的速度和角度这两组数据就是实现小车自平衡的前提,这些数值在stm32的中断控制中结合PID算法使用,输出运算后的数值赋值给PWM寄存器控制电机,从而实现小车的自平衡;而遥控数据则是小车转向控制才需要用的,因此可以先不关注遥控部分,在小车能够站起来后再去关注。

运动分析

平衡小车的运动控制可以分为平衡控制、速度控制和方向控制,即直立环、速度环和转向环,其中平衡控制是最关键的部分。平衡小车作为一个控制对象,可以简化地把它看做两个电机的转动速度和转动方向控制,小车的直立控制和方向控制是直接通过控制小车两个驱动电机完成的,小车的速度则是通过调节小车到的角度来完成的,不同的倾角会引起小车的加减速。(这里需要关注这两个关键词:速度和角度,这两个数据是通过检测装置(传感器)获取的,后面部分会详细讲述)。

平衡控制(直立环)

小车的平衡控制是通过负反馈来实现的。

反馈又称回馈,是控制论的基本概念,指将系统的输出返回到输入端并以某种方式改变输入,进而影响系统功能的过程;而使输出起到与输入相反的作用,使系统输出与系统目标的误差减小,系统趋于稳定的反馈称为负反馈。(百度)

直立环
平衡小车的两个轮子着地,车体只会在轮子滚动的方向上发生倾斜,因此可以通过控制轮子转动,抵消在一个维度上倾斜的趋势便可以保持车体平衡,即如果车体向前倾斜就向前加速运动,向后倾斜就向后加速运动。

保持小车稳定平衡的条件是:能够精确测量小车倾角θ的大小和角速度θ ’ 的大小以及可以控制车轮的加速度。(直立行车参考设计方案第二版)

直立控制主要是保证小车在运行过程中保持在一个理想的角度,这个理想的角度一般由小车的机械零点决定。这个点在实际中大多指的是一个范围。(如果在单纯调试直立环的时候调了很多组参数小车的平衡效果还是不好,不妨尝试一下在直立控制的程序中加上或者减去一个小一些的数值)

单纯直立环作用,在调好参数的情况下小车也是可以保持一定范围和时间的平衡的,但是对外界干扰特别敏感,不稳定,轻轻一推小车就失衡了,因此仅仅使用平衡控制是不足以实现我们想要的平衡效果的,要实现稳定效果,还需要加上速度环。

速度控制(速度环)

小车的速度控制是通过正反馈来实现的。使输出起到与输入相同的作用,使系统输出与系统目标的误差增大,系统趋于不稳定的反馈称为正反馈;即小车要向前倾斜,就往前更快地加速,以达到再次平衡。
解释
在这里插入图片描述

由于存在安装误差,传感器实际测量的角度与车模角度有偏差,因此车模实际不是保持与地面垂直,而是存在一个倾角,在重力的作用下,车模就会朝倾斜的方向加速前进。平衡小车的速度是通过调节小车倾角来完成的,平衡小车不同的倾角会引起车模的加减速,从而达到对于速度的控制。(直立行车参考设计方案第二版)

要调节小车的倾角,首先需要获取小车电机的转动速度,一般都是通过编码器来获取。某宝上大多数平衡小车的车模都是带有编码器的,引出AB两相,因为stm32的定时器有编码器模式,因此特定的GPIO口可以直接连接电机上的编码器接口,从而读取脉冲,获得速度值。
编码盘
直立环与速度环共同作用,就可以实现小车的平衡了,参数调好了即使用力推小车,小车也会迅速回到平衡位置。

转向控制(转向环)

实现平衡小车的转向控制的前提是平衡控制和速度控制已经能够实现较好地平衡效果,要是还没调好这两个环,就先不要调转向环。转向控制比较简单,就是给予两个电机差速,例如上位机需要控制小车左转,那么在最终赋值给电机的时候让左轮比右轮慢就行了(即左轮最终赋值减去转向输入值,右轮最终赋值加上转向输入值,两值大小相同,符号相反)。
在这里插入图片描述

PID算法

这里分享三篇有关PID算法的文档,从原理到C语言实现再到调参,总有一篇能解决你的疑惑,平衡小车运用的PID算法就只是几个式子,如果是兴趣爱好去做的话不用太深入去理解具体的推导过程,有条件的话还是钻研一番比较利于后面的学习。

<<<<<<<<<<<<<<<<<<<<---------------------------------------->>>>>>>>>>>>>>>>>>>>>>>>

PID控制算法的C语言实现.(绝对的好东西) hm5o
PID算法原理、调试经验和代码 z2r8
PID调节控制做电机速度控制 rw60

<<<<<<<<<<<<<<<<<<<<---------------------------------------->>>>>>>>>>>>>>>>>>>>>>>>

定时器PWM输出

脉冲宽度调制(PWM),是英文“Pulse Width Modulation” 的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。

因为我们在驱动电机的时候是希望它按照一定的速度行驶的,如果直接赋值高低电平来控制,则达不到我们要的控制效果。利用定时器输出PWM波则可以实现上述要求。STM32 的定时器除了除了基本定时器TIM6和TIM7外,其他的定时器都可以用来产生 PWM 输出。其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出。而通用定时器也能同时产生多达 4路的 PWM 输出。

定时器输出PWM的配置无非是相关GPIO口初始化、使能时钟、使能定时器、设置自动装载值和预分频系数、设置PWM输出通道和方向这些,相信开发手册写得很详细了。要是懒得翻开发手册,这里再贴一个大佬的一篇博客:【STM32】通用定时器的PWM输出(实例:PWM输出)高级定时器(以TIM1为例)的配置和通用定时器的配置基本一样,但是还需要使能刹车和死区寄存器(TIM1_BDTR)的MOE位,以使能整个 OCx(即 PWM)输出。设置函数为:TIM_CtrlPWMOutputs(TIM1,ENABLE);// MOE 主输出使能

定时器编码器模式

编码器模式是通用定时器和高级定时器的功能之一:
在这里插入图片描述
这里要着重提醒的是:stm32定时器只有TIMx_CH1和TIMx_CH2支持编码器模式:
在这里插入图片描述
选择编码器接口模式的方法是:如果计数器只在TI2的边沿计数,则置TIMx_SMCR寄存器中的SMS=001;如果只在TI1边沿计数,则置SMS=010;如果计数器同时在TI1和TI2边沿计数,则置SMS=011。

通过设置TIMx_CCER寄存器中的CC1P和CC2P位,可以选择TI1和TI2极性;如果需要,还可以对输入滤波器编程。

两个输入TI1和TI2被用来作为增量编码器的接口。参看下表:
在这里插入图片描述
假定计数器已经启动(TIMx_CR1寄存器中的CEN=’1’),计数器由每次在TI1FP1或TI2FP2上的有效跳变驱动。 TI1FP1和TI2FP2是TI1和TI2在通过输入滤波器和极性控制后的信号;如果没有滤波和变相,则TI1FP1=TI1,TI2FP2=TI2。根据两个输入信号的跳变顺序,产生了计数脉冲和方向信号。依据两个输入信号的跳变顺序,计数器向上或向下计数,同时硬件对TIMx_CR1寄存器的DIR位进行相应的设置。不管计数器是依靠TI1计数、依靠TI2计数或者同时依靠TI1和TI2计数。在任一输入端(TI1或者TI2)的跳变都会重新计算DIR位。

编码器接口模式基本上相当于使用了一个带有方向选择的外部时钟。这意味着计数器只在0到TIMx_ARR寄存器的自动装载值之间连续计数(根据方向,或是0到ARR计数,或是ARR到0计数)。所以在开始计数之前必须配置TIMx_ARR;同样,捕获器、比较器、预分频器、触发输出特性等仍工作如常。在这个模式下,计数器依照增量编码器的速度和方向被自动的修改,因此计数器的内容始终指示着编码器的位置。计数方向与相连的传感器旋转的方向对应。
在这里插入图片描述
当定时器配置成编码器接口模式时,提供传感器当前位置的信息。使用第二个配置在捕获模式的定时器,可以测量两个编码器事件的间隔,获得动态的信息(速度,加速度,减速度)。指示机械零点的编码器输出可被用做此目的。根据两个事件间的间隔,可以按照固定的时间读出计数器。如果可能的话,你可以把计数器的值锁存到第三个输入捕获寄存器(捕获信号必须是周期的并且可以由另一个定时器产生);也可以通过一个由实时时钟产生的DMA请求来读取它的值。

以上内容参考stm32中文手册,更详细说明可以参考这篇博客:【STM32平衡小车】STM32定时器配置为编码器模式

六轴传感器获取角度

平衡小车制作的核心部分是倾角和加速的的获取,想要使小车站立和运动,这两种参数的获取是非常关键的,前者是控制小车直立的关键参数,后者是速度环和转向环的关键参数。平衡小车使用MPU6050六轴传感器模块来获取角度和加速度值,MPU6050六轴传感器模块的本质是三轴陀螺仪倾角输出+三轴加速度计速度输出,并带有温度传感器。
在这里插入图片描述
该模块的通信方式是IIC通信,芯片内置16字节AD转换器,能输出16位数据。得到输出的四元数后,可利用自带的数字运动处理器(DMP)硬件加速引擎,通过主IIC接口,向应用端输出姿态解算后的数据,通过DMP,就可以使用InvenSense公司提供的运动处理资料库,非常方便地实现姿态解算,降低了运动处理运算对操作系统的负荷,同时大大降低了开发难度。其内部框图如下:
在这里插入图片描述
SCL 和 SDA 是连接 STM32F103C8T6芯片的 IIC 接口, MCU通过这个 IIC 接口来控制 MPU6050。VLOGIC 是 IO 口电压,该引脚最低可以到 1.8V,一般直接接 VDD 即可。 AD0 是从 IIC 接口(接 MCU)的地址控制引脚,该引脚控制IIC 地址的最低位。如果接 GND,则 MPU6050 的 IIC 地址是: 0X68,如果接 VDD,则是0X69。

因为陀螺仪买的是某点原子的,这里分享他们提供的详细资料:
ATK-MPU6050六轴传感器模块用户手册_V1.0 w7wy
ATK-MPU6050六轴传感器模块使用说明(Mini V3)_AN1507hhob

前前后后写了好几天,一些我认为比较容易进坑的地方都加粗了。原理部分就先到这里,下一篇硬件篇。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐