PID勺子
因为有人在B评论区说想要了解下如何制作,现写一篇文章说明一下制作步骤。
视频链接:
pid勺子
一、材料准备
- 主控:STM32F103C8T6(当然也可以使用其他型号)
- 数据采集:MPU6050陀螺仪
- 输出:MG90舵机
- 杜邦线若干
- 电源模块
- 两根筷子(视频中我手边没有筷子只有俩勺子,就……)
二、硬件组装
如图:
我是用的是一个180°舵机固定筷子时让舵机转到最大角度,让上面的塑料条和侧面的筷子垂直,然后再固定筷子到塑料条上,塑料条可以拔下来调整位置。
接线:
MG90舵机:
舵机一共有三根线颜色不一,其中:
棕:GND
红:5V
橙:PWM信号
MPU6050:
MPU6050一共有四根线:
VCC:3V3
GND:GND
SCL:连接STM32的IIC的SCL
SDA:连接STM32的IIC的SDA
这里我是用的是IIC2因此SCL对应PB10,SDA对应PB11。
三、软件代码讲解
变量说明:
变量名 | 说明 |
---|---|
P | 系统反应速度 |
D | 系统阻尼 |
mpu.Roll | 俯仰角 |
pid_val | 决定最后给舵机的PWM占空比 |
Err | 误差角度 |
preErr | 上一次的误差角度 |
main.c:
while(1)
{
MPU6050_Pose();//读取mpu6050的数据
pid();//PID控制
}
我是用的是一个增量式PID,就是如果误差不为0那就一直按照某个固定值增加/减少pwm_val的值
核心代码:
float pid_val = 0;
MPU mpu;
void pid()
{
static float P=-1.5,D =4.5 ,Err,preErr;
//滤波,降低系统敏感性
float a = 0.30;
Err=preErr * a;
Err += mpu.Roll * (1-a);
//计算PID
pid_val += Err * P + (preErr - Err) *D;
//PID_VAL限幅,定时器自动重装载值是20000,可控制舵机的比较值范围就是500~2500
if(pid_val < 500) pid_val = 500;
if(pid_val > 2500) pid_val = 2500;
//应用
__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_4,(int)pid_val);
preErr = Err;
}
四、调参
主要修改核心代码中的P、D、a三个变量的值。
P:pid_Val每次增加/减小的值,代表系统响应速度。
D:阻尼,抵抗P导致的过冲。
a:如果感觉PD调整的不错了,但是筷子还是在水平位置上下浮动,那就调小a来降低系统敏感度。