深入浅出PID控制算法(三)

您所在的位置:网站首页 pid控制表达式 深入浅出PID控制算法(三)

深入浅出PID控制算法(三)

2024-07-08 10:32| 来源: 网络整理| 查看: 265

GitHub 微信公众号 知乎 B站 CSDN

增量式与位置式PID算法的C语言实现与电机控制经验总结 前言1 PID算法C语言源代码2 PID 整定口诀3 项目原理3.1 直流电机3.2 减速器3.3 电机驱动3.4 编码器 4 电机速度闭环控制4.1 原理4.2 核心代码4.3 定时控制4.4 其他代码 5 电机位置闭环控制5.1 核心代码5.2 控制中断函数 6 参数整定7 总结相关阅读

前言

前文对PID算法离散化和增量式PID算法原理进行来探索,之后又使用Matlab进行了仿真实验,对PID三个参数又有了更深入的认识,接下来我们来使用C语言进行PID算法实现,并且结合控制电机的项目来深入学习。

增量式PID速度调节代码请关注公众号:迈微电子研发社(左侧微信扫码即可)回复“PID算法”,获取下载链接。

1 PID算法C语言源代码

先贴上一种常见的比较通用的C语言增量式PID算法吧

typedef struct PID { intSetPoint; //设定目标 DesiredValue longSumError; //误差累计 doubleProportion; //比例常数Proportional Const doubleIntegral; //积分常数 IntegralConst doubleDerivative; //微分常数Derivative Const intLastError; //Error[-1] intPrevError; //Error[-2] } PID; static PID sPID; static PID *sptr = &sPID; /*============================================================ ======= InitializePID Structure PID 参数初始化 ====== ==============================================================*/ void IncPIDInit(void) { sptr->SumError= 0; sptr->LastError= 0; //Error[-1] sptr->PrevError= 0; //Error[-2] sptr->Proportion= 0; //比例常数Proportional Const sptr->Integral= 0; //积分常数IntegralConst sptr->Derivative= 0; //微分常数Derivative Const sptr->SetPoint= 0; } /*=========================================================== ========= 增量式PID 计算部分 ======== =============================================================*/ int IncPIDCalc(int NextPoint) { registerint iError, iIncpid; //当前误差 iError= sptr->SetPoint - NextPoint; //增量计算 iIncpid= sptr->Proportion * iError //E[k]项 -sptr->Integral * sptr->LastError //E[k-1]项 +sptr->Derivative * sptr->PrevError; //E[k-2]项 //存储误差,用于下次计算 sptr->PrevError= sptr->LastError; sptr->LastError= iError; //返回增量值 return(iIncpid); } 2 PID 整定口诀 参数整定找最佳, 从小到大顺序查。 先是比例后积分, 最后再把微分加。 曲线振荡很频繁, 比例度盘要放大。 曲线漂浮绕大弯, 比例度盘往小扳。 曲线偏离回复慢, 积分时间往下降。 曲线波动周期长, 积分时间再加长。 曲线振荡频率快, 先把微分降下来。 动差大来波动慢, 微分时间应加长。 理想曲线两个波, 前高后低四比一。 一看二调多分析, 调节质量不会低。

说实话整定口诀对于初学者来说,其实根本就看不懂,只有从实际整定过程中才能慢慢发觉其中的奥秘。

3 项目原理

学到这里对PID算法的理解只是停留在理论,那么我们来结合实际看看,这里我参考的是平衡小车之家的资料,不得不说确实浅显易懂,先从电机的简单控制开始理解吧!

3.1 直流电机

简单来说就是,把+和-分别接到电池的正极和负极,电机即可转动; 如果是把的+和-分别接到电池的负极和正极,则电机会反方向转动。电机的转速可以理解为和外接的电压是正相关的(实际是由电枢电流决定)。

3.2 减速器

一般直流电机的转速都是一分钟几千上万转的,所以一般需要安装减速器。减速器是一种相对精密的机械零件,使用它的目的是降低转速,增加转矩。减速后的直流电机力矩增大、可控性更强。按照传动级数不同可分为单级和多级减速器;按照传动类型可分为齿轮减速器、蜗杆减速器和行星齿轮减速器。

3.3 电机驱动

要实现电机调试和换向功能,我们可以使用单片机实现的,但是单片机IO 的带负载能力较弱,而直流电机是大电流感性负载,所以我们需要功率放大器件,在这里,我们选择了 TB6612FNG。

TB6612FNG 是东芝半导体公司生产的一款直流电机驱动器件,它具有大电流MOSFET-H桥结构,双通道电路输出,可同时驱动 2 个电机。也许大家更熟悉被用烂的L298N,其实这两者的使用基本一致的。而且,相比 L298N 的热耗性和外围二极管续流电路,它无需外加散热片,外围电路简单,只需外接电源滤波电容就可以直接驱动电机,利于减小系统尺寸。对于 PWM 信号输入频率范围,高达 100 kHz 的频率更是足以满足我们大部分的需求了。

3.4 编码器

在这里插入图片描述 编码器是一种将角位移或者角速度转换成一连串电数字脉冲的旋转式传感器,我们可以通过编码器测量到底位移或者速度信息。编码器从输出数据类型上分,可以分为增量式编码器和绝对式编码器。

从编码器检测原理上来分,还可以分为光学式、磁式、感应式、电容式。常见的是光电编码器(光学式)和霍尔编码器(磁式)。

这里使用增量式输出的霍尔编码器。编码器有 AB 相输出,所以不仅可以测速,还可以辨别转向。根据上图的接线说明可以看到,我们只需给编码器电源5V 供电,在电机转动的时候即可通过 AB 相输出方波信号。编码器自带了上拉电阻,所以无需外部上拉,可以直接连接到单片机IO读取。

那么单片机如何采集编码器数据?

因为编码器输出的是标准的方波,所以我们可以使用单片机(STM32 STM8 51等)直接读取。在软件中的处理方法是分两种,自带编码器接口的单片机如STM32,可以直接使用硬件计数。而没有编码器接口的单片机如 51 单片机,可以通过外部中断读取,比如把编码器 A 相输出接到单片机的外部中断输入口,这样就可通过跳变沿触发中断,然后在对应的外部中断服务函数里面,通过 B 相的电平来确定正反转。如当 A 相来一个跳变沿的时候,如果 B 相是高电平就认为是正转,低电平就认为是反转。

4 电机速度闭环控制 4.1 原理

速度闭环控制就是根据单位时间获取的脉冲数测量电机的速度信息,并与目标值进行比较,得到控制偏差,然后通过对偏差的比例、积分、微分进行控制,使偏差趋向于零的过程。

需要说明的是,这里速度控制 20ms 一次,一般建议 10ms 或者 5ms,因为在这里电机是使用 USB 供电,速度比较慢,20ms 可以延长获取速度的单位时间,提高编码器的采值。

首先由于需要知道速度,所以一般都需要带编码器的电机,编码器输出有ab相,可以通过单片机定时器的捕获模式来得到速度,之后在单片机内部进行PID算法的运算,得到输出所需要的速度,通过控制占空比来输出PWM波,控制电机的速度,这里用的主控是STM32c8t6。 在这里插入图片描述 在这里插入图片描述

4.2 核心代码 /************************************************************************** 函数功能:增量PI控制器 入口参数:编码器测量值,目标速度 返 回 值:电机PWM 根据增量式离散PID公式 pwm+=Kp[e(k)-e(k-1)]+Ki*e(k)+Kd[e(k)-2e(k-1)+e(k-2)] e(k)代表本次偏差 e(k-1)代表上一次的偏差 以此类推 pwm代表增量输出 在我们的速度控制闭环系统里面,只使用PI控制 pwm+=Kp[e(k)-e(k-1)]+Ki*e(k) **************************************************************************/ int Incremental_PI (int Encoder,int Target) { float Kp=20,Ki=30; static int Bias,Pwm,Last_bias; //相关内部变量的定义。 Bias=Encoder-Target; //求出速度偏差,由测量值减去目标值。 Pwm+=Kp*(Bias-Last_bias)+Ki*Bias; //使用增量 PI 控制器求出电机 PWM。 Last_bias=Bias; //保存上一次偏差 return Pwm; //增量输出 }

这里可以看到使用的是增量式比例积分控制器,Kp和Ki的值在函数中临时设置,完全按照公式编写,简单易懂。

4.3 定时控制 int Target_velocity=50; //设定速度控制的目标速度为50个脉冲每10ms int TIM3_IRQHandler(void) { if(TIM3->SR&0X0001)//10ms定时中断 { TIM3->SR&=~(1SR&=~(1


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3