打印
[其他ST产品]

用 STM32 实现电机控制,PID 调参经验分享

[复制链接]
1521|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
烟雨蒙蒙520|  楼主 | 2024-12-5 16:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 烟雨蒙蒙520 于 2024-12-5 16:46 编辑

基础概念PID 控制器PID 控制器由比例 (P)、积分 (I)、微分 (D) 三部分组成:
  • P (Proportional): 调节与误差成比例,控制响应速度。
  • I (Integral): 修正长期误差,消除稳态误差。
  • D (Derivative): 抑制误差变化趋势,增强系统稳定性。
控制公式:
其中:
  • e(t):期望值与实际值的误差。
  • ​:PID参数。

使用特权

评论回复
沙发
烟雨蒙蒙520|  楼主 | 2024-12-5 16:46 | 只看该作者
硬件准备
(1) 电机
直流电机(DC Motor):通过PWM控制电压来调节速度。
步进电机:控制步进脉冲信号频率和方向。
无刷电机(BLDC):通过霍尔传感器或无传感器FOC(场定向控制)实现精准控制。
(2) STM32开发板
推荐支持定时器和PWM的STM32芯片,如STM32F103、STM32F4系列等。
(3) 驱动器
H桥电路:如L298N、DRV8833等,用于直流电机。
无刷驱动器:如DRV8302,用于BLDC。
步进驱动器:如A4988、TMC2208。
(4) 编码器或传感器
增量式编码器:获取速度和位置。
霍尔传感器:检测无刷电机的转子位置。

使用特权

评论回复
板凳
烟雨蒙蒙520|  楼主 | 2024-12-5 16:46 | 只看该作者
PID 控制系统设计
(1) 系统框架
输入:期望值(速度或位置)。
反馈:电机的实际速度或位置(通过编码器或霍尔传感器获取)。
控制器:PID 算法,根据误差输出控制信号。
执行器:通过PWM信号驱动电机。

使用特权

评论回复
地板
烟雨蒙蒙520|  楼主 | 2024-12-5 16:46 | 只看该作者
软件实现
(1) PWM 初始化
通过 STM32 的定时器生成 PWM 信号,控制电机驱动器的输入:

c
复制代码
void MX_TIM3_Init(void) {
    TIM_HandleTypeDef htim3;
    TIM_OC_InitTypeDef sConfigOC = {0};

    htim3.Instance = TIM3;
    htim3.Init.Prescaler = 84 - 1;  // 设置PWM频率
    htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim3.Init.Period = 1000 - 1;  // 设定PWM分辨率
    HAL_TIM_PWM_Init(&htim3);

    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 0;  // 初始占空比
    HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1);

    HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
}

使用特权

评论回复
5
烟雨蒙蒙520|  楼主 | 2024-12-5 16:46 | 只看该作者
编码器读取
通过TIM配置编码器模式获取电机位置:

c
复制代码
void MX_TIM4_Init(void) {
    TIM_HandleTypeDef htim4;

    htim4.Instance = TIM4;
    htim4.Init.Prescaler = 0;  // 不分频,直接读取编码器脉冲
    htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim4.Init.Period = 0xFFFF;  // 最大计数值
    htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    HAL_TIM_Encoder_Init(&htim4, &sEncoderConfig);
    HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_ALL);
}

int16_t ReadEncoder(void) {
    return __HAL_TIM_GET_COUNTER(&htim4);  // 读取编码器位置
}

使用特权

评论回复
6
烟雨蒙蒙520|  楼主 | 2024-12-5 16:46 | 只看该作者
PID 算法实现
PID 控制器核心逻辑:

c
复制代码
typedef struct {
    float Kp;      // 比例系数
    float Ki;      // 积分系数
    float Kd;      // 微分系数
    float prev_error;
    float integral;
} PIDController;

void PID_Init(PIDController *pid, float Kp, float Ki, float Kd) {
    pid->Kp = Kp;
    pid->Ki = Ki;
    pid->Kd = Kd;
    pid->prev_error = 0.0f;
    pid->integral = 0.0f;
}

float PID_Compute(PIDController *pid, float setpoint, float measured, float dt) {
    float error = setpoint - measured;
    pid->integral += error * dt;
    float derivative = (error - pid->prev_error) / dt;

    float output = pid->Kp * error + pid->Ki * pid->integral + pid->Kd * derivative;
    pid->prev_error = error;

    return output;
}
调用 PID 控制器:

c
复制代码
PIDController motor_pid;
PID_Init(&motor_pid, 1.0f, 0.5f, 0.1f);

float control_signal = PID_Compute(&motor_pid, target_speed, actual_speed, dt);
SetMotorPWM(control_signal);

使用特权

评论回复
7
烟雨蒙蒙520|  楼主 | 2024-12-5 16:52 | 只看该作者
PID 调参经验
(1) 参数调整顺序
设置 =0,=0
K i =0,K d=0,只调节
K p :增加 K p
​  提高响应速度。
K p
过高可能引起震荡。
引入 K d:增加 K d
  抑制震荡,平滑控制。
最后调整
K i:增加 K i

消除稳态误差。
K i过大会导致积分饱和(系统振荡)。

使用特权

评论回复
8
烟雨蒙蒙520|  楼主 | 2024-12-5 16:53 | 只看该作者
常见问题及解决方案
震荡:K p 太大或 K i 过高,减小对应参数。
响应迟缓:K p  太小或 K d 过大,增加 K p,减小 K d。
稳态误差:增加
K i,但需注意避免积分饱和。

使用特权

评论回复
9
烟雨蒙蒙520|  楼主 | 2024-12-5 16:53 | 只看该作者
调参技巧
实验法:从小到大逐步增加参数,观察响应曲线。
Ziegler-Nichols法:通过测试系统的极限震荡点计算参数。
结合MATLAB仿真:对系统进行建模,利用工具快速调参。

使用特权

评论回复
10
烟雨蒙蒙520|  楼主 | 2024-12-5 16:53 | 只看该作者
优化建议
(1) 采样与计算周期
保证采样周期一致(如通过定时器中断)。


dt 过大导致延迟,过小增加计算量,典型值为10ms。
(2) 增加限幅
防止PID输出过大:

c
复制代码
if (output > MAX_PWM) output = MAX_PWM;
else if (output < MIN_PWM) output = MIN_PWM;
(3) 抗积分饱和
引入抗饱和机制:

c
复制代码
if (output == MAX_PWM || output == MIN_PWM) {
    pid->integral -= error * dt;  // 防止积分累积
}
(4) 调试工具
使用示波器观察速度或位置反馈信号。
配合串口调试工具打印关键变量。

使用特权

评论回复
11
烟雨蒙蒙520|  楼主 | 2024-12-5 16:53 | 只看该作者
可以实现高效、稳定的电机PID控制,并通过合理的调参实现精确控制!

使用特权

评论回复
12
zhe_jiang| | 2024-12-7 11:37 | 只看该作者
学习, 能再仔细介绍一下吗?

使用特权

评论回复
13
xiaogougou| | 2024-12-24 11:35 | 只看该作者
烟雨蒙蒙520 发表于 2024-12-5 16:53
可以实现高效、稳定的电机PID控制,并通过合理的调参实现精确控制!

请问最近在调pid控制,电机总是一下下的转,不是一直转,可以详细说说你的pid吗

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

36

主题

666

帖子

0

粉丝