6、程序设计
程序思路如下:STM32通过读取传感器数据,做滤波和姿态计算,然后通过串级PID进行控制;同时接收遥控指令,做出前后左右以及旋转的动作。下面开始分步介绍:
1)MPU6050采用I2C总线驱动,楼主使用模拟I2C,速度很快,100多个us就能读完传感器数据,然后进行滤波+姿态解算,得到小车的角度信息。
数据处理和PID控制就是自平衡小车的核心了。我们对加速度计做低通滤波,对陀螺仪做滑动滤波,过滤大部分由震动引起的数据噪声。 然后用四元数来计算姿态,最后转换成角度(欧拉角),就能用于控制了。初次接触MPU6050的网友可能对数据解算比较陌生,建议看一下下面这个精品贴: 【讨论帖】姿态解算相关知识储备
关于MPU6050的驱动:: stm32f103运行mpu6050源码
为什么选择6050呢,因为它内部集成了一个硬件算法,能够直接输出表示姿态的四元数,我们只需要把这个四元数用公式转化成角度(欧拉角),就能用于控制了,是不是很方便呢!前期调过姿态解算,后期再慢慢研究姿态解算的问题。
公式如下:
Q_ANGLE.Yaw = atan2(2 * q1 * q2 + 2 * q0 * q3, -2 * q2*q2 - 2 * q3* q3 + 1)* 57.3; // yaw
Q_ANGLE.Y = asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3; // pitch
Q_ANGLE.X = atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3; // roll
实际上我们用到一个角度即可
关于MPU6050的DMP功能,请看:传感器驱动实验(DMP测试,串口回传欧拉角及四元数,附视频,工程文件)(欧拉角万向锁视频)
2)串级PID相关介绍:串级PID----代码+调参
3)Nrf2401通讯实验:NRF无线通讯实验(附视频,工程文件)
4)电机控制,当然要搞清楚这个电机驱动怎么用啦,我们一起来看看:
TB6612的的用法:
TB6612是双驱动,也就是可以驱动两个电机
下面分别是控制两个电机的IO口
STBY口接单片机的IO口清零电机全部停止,置1通过AIN1 AIN2,BIN1,BIN2 来控制正反转
VM 接12V以内电源
VCC 接5V电源
GND 就不多说了啊
驱动1路
PWMA 接单片机的PWM口
真值表:
AIN1 0 0 1
AIN2 0 1 0
停止 正传 反转
A01
AO2 接电机1的两个脚
驱动2路
PWMB 接单片机的PWM口
真值表:
BIN1 0 0 1
BIN2 0 1 0
停止 正传 反转
B01
BO2 接电机2的两个脚
很容易写出电机驱动,包括转速控制和前进后退控制
/******************************************************************************
函数原型: void Motor_Out(int16_t duty1,int16_t duty2)
功 能: 电机驱动
*******************************************************************************/
void Motor_Out(int16_t duty1,int16_t duty2)
{
if(duty1>1000) duty1=1000;
if(duty1<0) duty1=0;
if(duty2>1000) duty2=1000;
if(duty2<0) duty2=0;
TIM2->CCR1 = duty1;
TIM2->CCR2 = duty2;
}
/******************************************************************************
函数原型: void Forward(void)
功 能: 前进
*******************************************************************************/
void Forward(void)
{
STBY_H;
AIN1_L;AIN2_H;
BIN1_H;BIN2_L;
}
/******************************************************************************
函数原型: void Back(void)
功 能: 后退
*******************************************************************************/
void Back(void)
{
STBY_H;
AIN1_H;AIN2_L;
BIN1_L;BIN2_H;
}
/******************************************************************************
函数原型: void Stop(void)
功 能: 停止
*******************************************************************************/
void Stop(void)
{
STBY_L;
AIN1_L;AIN2_L;
BIN1_L;BIN2_L;
}