在上一篇文章中,我们探索了PID算法和增量PID算法的离散化原理,然后进行了仿真实验,以更深入地了解PID的三个参数。 接下来,我们将使用C语言来实现PID算法。 并结合控制电机的项目进行深入学习。
1.PID算法C语言原代码
先贴一个常见的、比较通用的C语言增量PID算法。
PID{; //设置目标误差; //错误累积; //比例常数; //积分常数; //微分常数; //错误[-1]; //错误[-2]} PID; PID sPID ; PID *sptr = &sPID;/*============================================== == =============================PID参数初始化================== == =================================================* /void (void){sptr->= 0;sptr->= 0; //错误[-1]sptr->= 0; //错误[-2]sptr->= 0; //比例常数->= 0 ; //积分常数->= 0; //微分常数->= 0;}/*============================== ========== ============================ 增量PID计算部分==== ============== =================================================== */ int (int ){ , ; //当前错误 = sptr-> - ; //增量计算 = sptr-> * //E[k]项 -sptr-> * sptr-> //E[k-1]项 sptr-> * sptr->; //E[k-2]项//下次计算存储错误 sptr->= sptr- >;sptr->= ;//返回增量值();}
2、PID整定公式
参数整定找最佳, 从小到大顺序查。
先是比例后积分, 最后再把微分加。
曲线振荡很频繁, 比例度盘要放大。
曲线漂浮绕大弯, 比例度盘往小扳。
曲线偏离回复慢, 积分时间往下降。
曲线波动周期长, 积分时间再加长。
曲线振荡频率快, 先把微分降下来。
动差大来波动慢, 微分时间应加长。
理想曲线两个波, 前高后低四比一。
一看二调多分析, 调节质量不会低。
说实话,对于初学者来说,调优公式其实根本看不懂。 只有通过实际的调校过程,才能逐渐发现其中的奥秘。
三、项目原理
了解到这里对PID算法的理解只是理论上的,所以我们还是结合实际来看看吧。 这里我参考了平衡车之家的信息。 不得不说,确实很容易理解。 我们先从电机的简单控制开始。 !
3.1 直流电机
简单来说,将和-分别连接到电池的正负极上,电机就可以转动;
如果将“-”分别连接到电池的负极和正极,则电机将以相反方向旋转。 电机的转速可以理解为与外部电压(实际上由电枢电流决定)正相关。
3.2.减速机
一般直流电机的转速为每分钟几千或几万转,所以一般需要减速机。 减速机是一种比较精密的机械零件。 使用它的目的是降低速度,增加扭矩。 减速后,直流电机扭矩增大,可控性更强。 按传动级数可分为单级减速机和多级减速机; 按传动类型可分为齿轮减速机、蜗杆减速机和行星齿轮减速机。
3.3 电机驱动
要实现电机调试和换向功能,我们可以使用单片机,但是单片机IO的负载能力较弱,而直流电机又是大电流感性负载,所以需要功放器件,这里我们选择了它。
是东芝半导体公司生产的直流电机驱动装置。 采用大电流H桥结构,双路电路输出,可同时驱动2个电机。 也许大家更熟悉用得不好的L298N,但其实两者的使用方法基本是一样的。 而且,与L298N的散热和外围二极管续流电路相比,不需要外部散热器,外围电路简单。 只需外接电源滤波电容即可直接驱动电机,有利于减小系统尺寸。 至于PWM信号输入频率范围,高达的频率足以满足我们的大部分需求。
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波,控制电机的速度,这里使用的主要控制是。
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 (int ,int ){浮点 Kp=20,Ki=30; int Bias,Pwm,;//相关内部变量定义。 Bias=-;//为了找到速度偏差,用测量值减去目标值。 Pwm =Kp*(Bias-) Ki*Bias; //使用增量PI控制器找到电机PWM。 =Bias;//保存上次偏差 Pwm;//增量输出}
在这里您可以看到使用了增量比例积分控制器。 Kp和Ki的值是在函数中临时设置的。 完全按照公式写的,简单易懂。
4.3 时序控制
int Target_velocity=50; //设定速度控制的目标速度为50个脉冲每10ms
int TIM3_IRQHandler(void)
{
if(TIM3->SR&0X0001)//10ms定时中断
{
TIM3->SR&=~(1<<0); //===清除定时器1中断标志位
Encoder=Read_Encoder(2); //===读取编码器的值,M法测速,输出为每10ms的脉冲数
Led_Flash(100); //===LED闪烁;指示单片机正常运行
Moto1=Incremental_PI(Encoder,Target_velocity); //===速度PI控制器
Xianfu_Pwm(); //===PWM限幅
Set_Pwm(Moto1); //===赋值给PWM寄存器
}
return 0;
}
这里的控制周期设置为每10ms控制一次,在10ms中断期间进行设置。 获得控制量后,通过简单赋值和去绝对值输出到驱动的PWM控制器。
4.4 其他代码
/******************************************************** ***** *************************函数功能:给PWM寄存器赋值 入口参数:PWM 返回值:无**** ****** ********************************************** ********* ******************/void (int moto1){if(moto1>0)AIN2=1,AIN1=0;=0 ,AIN1=1;PWMA=myabs(moto1);} /**************************************** ****************** **************************函数功能:限制PWM分配入口参数:无 返回值:无******************** ************************* ******************************************/void (void){ int =7100; //===PWM 满量程为 7200,限制为 7100 if((Moto1>) Moto1=; }/*** ********************** **************************************************函数功能:绝对值 函数入口参数:int 返回值:int**************** ********************* ****************************** **********/int myabs(int a){int temp; if(aelse temp=a; temp;}
主功能
int main(void)
{
Stm32_Clock_Init(9); //系统时钟设置
...
MiniBalance_PWM_Init(7199,0); //=====初始化PWM 10KHZ 高频可以防止电机低频时的尖叫声
Encoder_Init_TIM2(); //初始化编码器
Timer3_Init(99,7199); //=====10MS进一次中断服务函数,中断服务函数在control.c
while(1);
}
5、电机位置闭环控制
位置闭环控制是根据编码器的脉冲积累测量电机的位置信息并与目标值进行比较以获得控制偏差的过程。 然后,通过控制偏差的比例、积分、微分,将偏差控制为零。
5.1 核心代码
/******************************************************** ***** *************************功能:位置PID控制器入口参数:编码器测量位置信息,目标位置返回值:电机PWM根据位置离散PID公式 pwm=Kp*e(k) Ki*Σe(k) Kd[e(k)-e(k-1)]e(k) 表示这个偏差 e(k-1) 表示upper 主偏差 Σe(k) 表示 e(k) 与之前偏差的累积和; 其中 k 为 1, 2,,k; pwm代表输出********************************************* ******************************/int (int ,int ){ float =80,=0.1,=500; float Bias,Pwm,,;Bias=-;//找出速度偏差并从测量值中减去目标值。 =Bias;//求偏差的积分Pwm=*Bias * *(Bias-);//位置PID控制器=Bias;//保存上次偏差Pwm;//增量输出}
这里使用了稍微复杂一点的PID控制,它比之前的速度控制多了一个微分环节。 不过由于是位置控制,所以代码比较简单,容易理解。
5.2 控制中断函数
int Target_position=11000; //初始值是10000,目标值是11000
int TIM3_IRQHandler(void)
{
if(TIM3->SR&0X0001)//10ms定时中断
{
TIM3->SR&=~(1<<0); //===清除定时器1中断标志位
Encoder=Read_Encoder(2); //===读取编码器的位置数据 初始值是10000
Led_Flash(100); //===LED闪烁;指示单片机正常运行
Moto1=Position_PID(Encoder,Target_position); //===位置PID控制器
Xianfu_Pwm(); //===PWM限幅
Set_Pwm(Moto1); //===赋值给PWM寄存器
}
return 0;
}
其他代码与上面类似
6. 参数调整
首先我们需要明确我们的控制目标,即满足控制系统的三个要求:
具体评价指标包括最大超调、上升时间、静态误差等。
最大超调是响应曲线的最大峰值与稳态值的差值,是评价系统稳定性的重要指标; 上升时间是指响应曲线从原始工作状态开始第一次达到输出稳态值所需的时间。 时间是评价系统快速性的重要指标; 静态差是被控变量的稳定值与给定值之间的差。 一般用于衡量系统的精度。 详细内容请参考前面的解释。
在实际生产工程中,不同的控制系统对控制器效果的要求不同。 例如平衡车、倒立摆对系统的快速性要求很高。 如果响应太慢,系统就会失去控制。 智能家居中的自动门窗开关系统对速度要求不高,但对稳定性和精度要求较高,因此需要严格控制系统的超调量和静态误差。 因此,不同的控制系统中PID参数是不同的。 只要我们了解了各个PID参数的作用,我们就可以在项目中针对各个项目调整PID参数。
一般来说,控制系统的控制难度一般取决于系统的转动惯量和响应速度要求。 转动惯量越小,响应速度要求越低,PID参数越不敏感。 比如现在我们控制电机旋转90°,就需要严格控制超调和静态误差。 但对响应速度没有要求。 由于电机负载轻且转动惯量小,因此这是一项容易完成的任务。 根据以上理论分析和实践,由于对响应速度没有要求,一般P应较小,然后增加系统的阻尼以防止超调,即D参数应尽可能大。 另外,由于P值较小,因此应添加I来控制减小的静态差值。
七、总结
在设备调试过程中,会遇到各种各样的问题。 硬件会随着外部环境不断变化,从而干扰我们的调试和运行结果。 要调整能够适应各种环境的参数,必须对每个环境进行测试,才能综合得到最适合的参数。 因此,在图形化调试和设置过程中可以快速、直观地得出结论。 面对平衡车或四旋翼飞行器等更复杂的情况,多个传感器采集的数据还必须考虑复杂情况下的过滤、限制、加权等问题。 这些将在后续文章中进行总结。
增量式PID调速代码已上传。 可以参考类似位置类型进行修改。