文章目录
1 简介
Hi,大家好,这里是丹成学长,今天向大家介绍一个 单片机项目, 大家可用于 课程设计 或 毕业设计
基于STM32的平衡车设计与实现
🧿 毕设项目分享:见文末!
1 课题描述
课题的研究主要是为了设计出可以在小范围内活动的轻巧灵活的绿色代步工具,并且在自平衡的功能上加上一些新功能, 如自跟随功能和遥控功能, 这样平衡车不仅可以当作交通工具来使用还可以作为人们的助手, 如可以制造出平衡车形式的拉杆箱、 平衡车形式的超市购物车等。 平衡车技术起源于国外被叫作摄位车(Segway), 在国内有被叫做平衡车、 思维车、 体感车, 平衡车易于放置, 便于携带 。 公共场所、 汽车、 火车上都可以随意携带, 平衡车不需要专用的场地, 可以在马路、 公园、 林间小路甚至室内都可以骑行,所以它相比传统的四轮车是有很大的优势的。
无论是两轮平衡车还是独轮平衡车都可以在小范围内运动, 不像传统的四轮车在小范围内实现转弯很困难。 随着电子技术的不断发展, 人们对代步功能的要求也越来越高, 平衡车也就由此诞生了, 电动平衡车的小巧便携性也给人们带来了很多方便, 同时, 电动平衡车的电驱动性赋予了它绿色交通的使命, 它的广泛流行对文明城市的建设和生活环境的改善都有着重要的意义 。 电动平衡车为人们节省了不少燃油开支和时间, 相比其它的代步工具还有价格上的优势, 使大多数的人都能支付得起, 保养起来也相对简单。 在平衡车上加入一些传感器可以使人更好地控制它, 同时也使它具有了搬运、 壁障等功能, 如加入了自跟随功能就避免了需要人用手携带的缺点。
市面上常见的平衡车
2 课题设计内容
这个项目的核心是平衡车的控制系统, 在平衡车稳定平衡的基础上对自跟随和无线遥控进行研究,
并且计划使用 STM32 作为主处理器进行开发制作, 由对倒立摆控制系统的分析进而分析平衡车的控制理论, 其中包括直立行驶和转弯, 还有自跟随的控制理论分析。
该项目的重点首先是要对 STM32 单片机的各个硬件系统有熟练使用的能力, 这样才能对各模块进行正确的驱动设计。 其中, 需要对 MPU6050 原始数据进行滤波处理, 所以要通过对滤波算法的分析对 MPU6050 中的陀螺仪和加速度数据进行融合, 使滤波后的结果可以满足设计要求。
对 PID 算法进行分析, 为闭环控制系统找到合适的 PID 控制器模型, 其中参数的确定属于本次设计的难点。遥控部分计划由触摸屏和 51 单片机进行设计, 所以需要 51 单片机和 STM32 进行正确通信, 才能完成触摸遥控功能。
3 平衡车控制原理
两轮平衡小车则与颠倒着的单摆系统类似, 倒立摆与单摆有着很大的不同了, 当倒立摆离开平衡位置时它受到的重力作用与运动方向相同, 不是抑制它的变化反而促使它向偏离平衡点更远的地方运动, 也就是它向着不稳定方向发展, 而空气阻力则是时刻与它的运动相反, 所以摆杆要想平衡就必须有其它形式的外力作为辅助, 所以这就引出了速度,给小车一个与摆杆运动方向相同的速度使摆杆因自身的惯性产生一个回复力, 这个回复力就可以使摆杆具有向着稳定状态运动的趋势, 这个回复力的大小为:
如果不考虑空气阻力, 那么若要摆杆具有回复的趋势, 摆杆底部的平台相当于小车车轮的加速度要足够大, 而且是随着偏离平衡的角度的增大而增大
平衡小车的控制任务可以分解成三个基本控制任务。
-
1 首先是控制小车的平衡, 控制小车的平衡可以通过控制平衡小车的两个车轮的正反转实现平衡小车可以在两个运动方向都可以获得产生回复力的加速度, 这样平衡任务就可以实现。
-
2 然后是控制小车的速度, 由以上分析可知小车的速度与倾角有着密不可分的关系, 所以小车的速度变化应该与倾角相对应。
-
3 最后是控制小车的方向, 控制小车的方向可以利用两个车轮之间的转速差进行控制,转向速度应该与速度差的大小成正比 。
4 关键算法
4.1 PID控制算法
PID 算法在工业控制中有着重要的地位, 是现今最常用的模糊控制算法之一, PID 其实是比例控制、 积分控制和微分控制, 简称 PID 控制。 在闭环控制系统中 PID 控制器更是必不可少, PID 控制器之所以被应用这么广泛主要是因为它的结构简单、 工作稳定性好、调整方便的特点, 在实际研究中经常会遇到被控对象的具体参数不能精确的建立出数学模型, 其它控制理论技术难以采用时, 系统的控制器和具体参数必须要根据实验现象来现场调试, 在这种情况下 PID 控制器是最能体现优势了, PID 在实际应用中 PI 控制和 PD 控制较为常见, 甚至有的直接只有一个比例 P 控制就可以完成整个系统的控制。
4.2 卡尔曼滤波
卡尔曼滤波器由系统的输入和输出观测数据, 对系统状态做出最优估计, 它的依据是系统的线性状态方程, 因系统分析数据大部分存在噪声和干扰, 所以最优估计又被看成是滤波过程。 卡尔曼滤波器首次被实现 Stanley Schmidt, 卡尔曼滤波处理数据其实是去除数据中的噪声还原真实数据的数据处理技术, 在方差已知的情况下从存在噪声的系统数据中, 把系统的动态状态估计出来。 由于卡尔曼滤波容易被计算机编程实现, 并且能对现场的数据及时的进行更新和处理, 所以卡尔曼滤波成为目前应用非常广泛的滤波方法。
5 硬件设计
硬件电路是软件部分的基础, 如果软件比作人的大脑, 那么硬件就是各种器官。 只有硬件各部分设计得当, 那么我们的软件算法才能体现出他的优势。 硬件电路部分主要
包括:
- 电源供电部分
- MPU-6050 传感器部分
- STM32 主控芯片部分
- 电机驱动部分
- 编码器测速部分和
- 蓝牙传输部分
本项目学长以流行的平衡车为控制背景平台。 陀螺传感器、 电机速度编码器和超声波传感器用于数据采集。 以 STM32 处理器为控制中心, 利用姿态反馈和算法输出对传感器数据进行处理。 采用集成 H 桥驱动的直流电机进行输出控制, 形成完整的闭环控制系统。
5.1 stm32部分
最小系统电路设计: 单片机引脚与外部设备的连接要做到与功能相适应, 外部设备尽可能的靠近 MCU 的引脚, 使信号走线最短。 使用 Keil MDK 进行 STM32 的程序开发,下载调试方式采用 2 针的 SWD 串行接口, 下载接口采用 micro USB 接口(不是采用 USB下载, 只是提供接口) 更加方便调试。
5.2 电机驱动电路设计
这里学长这里选用的是直流电机, 如下图所示。 直流电机转速可以由加在他两端电压决定, 其转向也与电流流向有关, 因此控制较为简单, 只需要控制接在电机两端的电压的大小和正负极就可以实现对电机的转速和转向控制, 能够满足这个项目的需求。
但,由于单片机 IO 口输出电流能力有限, 但是直流电机的驱动需要大电流, 所以我们要用电流放大模块将单片机输出功率放大, 这里我们选用了 TB6612 芯片, 该芯片广泛应用于直流电机驱动, 它具有大电流 H 桥结构, 双通道电路输出, 可以同时驱动两个电机。电机驱动电路接线如图所示。
5.3 蓝牙通信
蓝牙模块用于实现模块化小车与手机 APP 的通信, 这里我们选用的是蓝牙 HC-05, 如下图所示。 蓝牙 HC-05 可以用于实现处理器与移动应用终端之间的通信, 移动应用终端可以通过蓝牙连接, 控制平衡车的切换和移动。 控制算法的 PID 参数也可以在开发模式下进行调试。 蓝牙通信模块与处理器之间的通信总线是一个串行口, 是一个异步通信接口。
接线图如下
5.4 软件实现
软件设计是系统设计的核心, 因此这部分也是至关重要的。 软件设计总体流程图如下图所示。
软件设计主要包括如下内容:
-
小车运动控制算法软件设计以及 APP 软件设计。
-
小车通过检测陀螺仪和加速度计返回的角度值, 利用 PD 算法控制电机对小车姿态进行调节达到动态平衡, 同时利用 PI 控制算法和 PD 控制算法对小车进行速度控制和转向控制。
不仅如此,在手机 APP 上, 我们可以通过蓝牙和小车连接进而对小车的运功起到控制作用。
5.5 APP设计
为了方便对小车进行运动控制, 本设计利用手机 APP 通过蓝牙与单片机进行连接,进而很方便的在安卓手机端就可以对小车实现控制。 学长开发的手机 APP 是基于Android Studio 开发环境而设计的。
APP功能
设计了首页、 波形、 调试和聊天这几个窗口, 这里学长主要使用了它的首页其实也就是控制窗口以及调试窗口。
在首页我们可以看到底下有三种模式, 分别为重力感应模式、 摇杆模式以及按键模式, 这三种模式基于不同的操作方式都可以对小车进行控制。
重力感应模式利用了手机的重力感应, 当手机向上倾斜时, 小车会前进, 反之小车则后退。 遥感模式下通过摇杆即可完成小车的各种运动控制。 按键模式下, 我们需要双手操控按键以完成运动控制。
调试窗口下, 我们可以明显看到有对参数的调节, 通过更改参数可以使得我们很方便的对小车程序的更改, 进而得到我们想要的运动参数。
5.6 小车平衡控制
车辆在垂直方向上具有机械平衡点, 以实现短平衡, 并向前或向后倾斜。 根据牛顿运动定律, 平衡需要一个相反的方向, 但外部世界无法对其施加力。 根据达朗贝尔原理,当车辆向前倾斜时, 施加向前加速度以确保平衡; 否则, 施加向后加速度。 显示了实际系统中平衡车辆的垂直控制。
车模直立环我们需要让平衡小车上电后, 能够自主且迅速的直立起来, 因此我们选择了 PD 控制方式, 比例系数 Kp 越大可以减小调节时间, 而微分环节又具有超前的调节作用, 可以实现小车的快速直立。 PD 闭环输入为小车的直立机械中值角度(0 度) , 陀螺仪和加速度计实际检测的角度值为反馈, 利用 PD 闭环控制消除偏差。
小车速度控制
为了使车模运动更加稳定, 需要用闭环控制来对车模速度进行实时的调整。 编码器通过检测单位时间内两个轮子旋转的脉冲个数, 以计算电机真实速度。 速度偏差值是通过从所需速度中减去真实速度得到的。 然后, 通过 PI 算法, 计算出速度控制的输出值,即脉宽调制占空比。 这里我们将获取速度控制输出值的子程序调用周期设置为 100 ms,输出值分为 100 个部分, 每毫秒输出速度控制输出值的 1%。
学长这里给出具体关键代码:
int sudu (int bianmaqi_left,int bianmaqi_right)
{
static float Sudu,Bianmaqi_Least,Bianmaqi;
static float Bianmaqi_Integral;
float Kp=80, Ki=0.4;
Bianmaqi_Least (Bianmaqi_Lef+Bianmaqi_Right)-O;
Bianmaqi*=0.7:
Bianmaqi+=Bianmaqi_Least*03;
Bianmaqi_Integral+=Bianmaqi;
Sudu=Bianmaqi*kp+Bianmaq_Integral*ki;
Return Sudu;
}
6 实现效果
后来学长加上来了超声波模块和循迹模块,视频演示如下
毕业设计:基于stm32的双轮平衡车
7 关键代码
// 作者 丹成学长:Q746076041
#include "stm32f10x.h"
#include "sys.h"
u8 Way_Angle=2; //获取角度的算法, 1: 四元数 2: 卡尔曼 3: 互补滤
u8 Flag_Qian,Flag_Hou,Flag_Left,Flag_Right,Flag_sudu=1; //蓝牙遥控相关的变量
u8 Flag_Stop=1,Flag_Show=0; //停止标志位和 显示标志位 默认停止 显示打开
int Encoder_Left,Encoder_Right; //左右编码器的脉冲计数
int Moto1,Moto2; //电机 PWM 变量 应是 Motor 的 向 Moto 致敬
int Temperature; //显示温度
int Voltage; //电池电压采样相关的变量
float Angle_Balance,Gyro_Balance,Gyro_Turn; //平衡倾角 平衡陀螺仪 转向陀螺仪
float Show_Data_Mb; //全局显示变量, 用于显示需要查看的数据
u32 Distance; //超声波测距
u8 delay_50,delay_flag,Bi_zhang=0,PID_Send,Flash_Send; //延时和调参等变量
float Acceleration_Z; //Z 轴加速度计
float Balance_Kp=223,Balance_Kd=0.82,Velocity_Kp=83,Velocity_Ki=0.41;//PID 参数
u16 PID_Parameter[10],Flash_Parameter[10]; //Flash 相关数组
int main(void)
{
delay_init(); //=====延时函数初始化
uart_init(128000); //=====串口初始化为
JTAG_Set(JTAG_SWD_DISABLE); //关闭 JTAG 接口
JTAG_Set(SWD_ENABLE); //打开 SWD 接口 可以利用主板的 SWD 接口调试
LED_Init(); //=====初始化与 LED 连接的硬件接
KEY_Init(); //=====按键初始化
MY_NVIC_PriorityGroupConfig(2); //=====中断分组
MiniBalance_PWM_Init(7199,0); //=====初始化 PWM 10KHZ, 用于驱动电
机 如需初始化电调接口
uart3_init(9600); //=====串口 3 初始化
Encoder_Init_TIM2(); //=====编码器接口
Encoder_Init_TIM4(); //=====初始化编码器 2
Adc_Init(); //=====adc 初始化
IIC_Init(); //=====IIC 初始化
delay_ms(1000);
常熟理工学院毕业设计(论文)
32
MPU6050_initialize(); //=====MPU6050 初始化
DMP_Init(); //=====初始化 DMP
OLED_Init(); //=====OLED 初始化
TIM3_Cap_Init(0XFFFF,72-1); //=====超声波初始化
MiniBalance_EXTI_Init(); //=====MPU6050 5ms 定时中断初始化
while(1)
{
if(Flash_Send==1) //写入 PID 参数到 Flash,由 app 控制该指令
{
Flash_Write();
Flash_Send=0;
}
if(Flag_Show==0) //使用 MiniBalance APP 和 OLED 显示屏
{
APP_Show();
oled_show(); //===显示屏打开
}
else //使用 MiniBalance 上位机 上位机使用的时候需要严格
的时序, 故此时关闭 app 监控部分和 OLED 显示屏
{
DataScope(); //开启 MiniBalance 上位机
}
delay_flag=1;
delay_50=0;
while(delay_flag); //通过 MPU6050 的 INT 中断实现的
50ms 精准延时
}
}
🧿 毕设项目分享:见文末!
8 最后
**项目分享: ** https://blog.csdn.net/m0_984093