您的位置 首页 知识

增量式PID算法的STM32完成 剖析份额、积分、微分三个环节

增量式PID算法的STM32实现 分析比例、积分、微分三个环节-虽然PID不是什么牛逼的东西,但是真心希望以后刚刚接触这块的人能尽快进入状态。特地分享一些自己如何实现的过程。 首先说说增量式PID的公式,这个关系到MCU算法公式的书写,实际上两个公式的写法是同一个公式变换来得,不同的是系数的差异。 资料上比较多的是:     还有一种的算法是:     这里主要介绍第二种,具体会分析比例、积分、微分三个环节的作用。 硬件部分: 控制系统的控制对象是4个空心杯直流电机,电机带光电编码器,可以反

尽管PID不是什么牛逼的东西,可是诚心期望今后刚刚触摸这块的人能赶快进入状态。特别共享一些自己怎样完成的进程。
首要说说增量式PID的公式,这个联络到MCU算法公式的书写,实践上两个公式的写法是同一个公式改换来得,不同的是系数的差异。
材料上比较多的是:
 

 

还有一种的算法是:
 

 

这儿首要介绍第二种,详细会剖析份额、积分、微分三个环节的作用。

硬件部分:
操控系统的操控方针是4个空心杯直流电机,电机带光电编码器,能够反应转速巨细的波形。电机驱动模块是一般的L298N模块。
芯片类型,STM32F103ZET6
 


软件部分:
PWM输出:TIM3,能够直接输出4路不通占空比的PWM波
PWM捕获:STM32除了TIM6 TIM7其他的都有捕获功用,运用TIM1 TIM2 TIM4 TIM5四个定时器捕获四个反应信号
PID的采样和处理:运用了根本定时器TIM6,溢出时间便是我的采样周期,理论上T越小作用会越好,这儿我取20ms,根据操控方针吧,假如操控水温什么的采样周期会是几秒几分钟什么的。

上面的PWM输出和捕获关于定时器的设置都有例程,我这儿是这样的:
TIM3输出四路PWM,在引脚 C 的 GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9输出
四路捕获分别是TIM4  TIM1  TIM2  TIM5   ,对应引脚是:  PB7 PE11 PB3 PA1
高档定时器tim1的初始化略不同,它的中止”称号“和通用定时器不同。详细的内容,请咱们看一下我共享的代码就了解了。
 

 程序.zip 

首要解说PID部分
预备部分:先界说PID结构体:

typedef struct 
{
int setpoint;//设定方针
int sum_error;//差错累计
float proportion ;//份额常数
float integral ;//积分常数
float derivative;//微分常数
int last_error;//e[-1]
int prev_error;//e[-2]
}PIDtypedef;

仿制代码

在文件中界说几个要害变量:

float  Kp =     0.32  ; //份额常数
float  Ti =                0.09 ; //积分时间常数
float Td =                0.0028 ;  //微分时间常数
#define T                  0.02 //采样周期
#define Ki     Kp*(T/Ti)        // Kp Ki Kd 三个首要参数
#define Kd                Kp*(Td/T)

仿制代码

PID.H里边首要的几个函数:

void PIDperiodinit(u16 arr,u16 psc);        //PID 采样定时器设定
void incPIDinit(void);                //初始化,参数清零清零
int incPIDcalc(PIDtypedef*PIDx,u16 nextpoint);           //PID核算
void PID_setpoint(PIDtypedef*PIDx,u16 setvalue);  //设定 PID预期值
void PID_set(float pp,float ii,float dd);//设定PID  kp ki kd三个参数
void set_speed(float W1,float W2,float W3,float W4);//设定四个电机的方针转速

仿制代码


PID处理进程:
岔开一下:这儿我操控的是电机的转速w,实践上电机的反应波形的频率f、电机转速w、操控信号PWM的占空比a三者是大致线性的正比的联络,这儿着重这个的意图是
因为楼主在前期一向搞不懂我操控的转速怎样和TIM4输出的PWM的占空比联络起来,后来想清楚里边的联络之后通过公式把各个系数算出来了。

正题:操控流程是这样的,首要我设定我需求的车速(对应四个轮子的转速),然后PID便是开端呼应了,它先采样电机转速,得到差错值E,带入PID核算公式,得到调整量也便是终究更改了PWM的占空比,不断调理,直到转速在稳态的一个小规模上下起浮。
上面讲到的“得到调整量”便是增量PID的公式:

int incPIDcalc(PIDtypedef *PIDx,u16 nextpoint)
{
int iError,iincpid;
iError=PIDx->setpoint-nextpoint;  //当时差错
/*iincpid=                                               //增量核算
PIDx->proportion*iError                //e[k]项
-PIDx->integral*PIDx->last_error          //e[k-1]
+PIDx->derivative*PIDx->prev_error;//e[k-2]
*/
iincpid=                                                          //增量核算
PIDx->proportion*(iError-PIDx->last_error)
+PIDx->integral*iError
+PIDx->derivative*(iError-2*PIDx->last_error+PIDx->prev_error);

PIDx->prev_error=PIDx->last_error; //存储差错,便于下次核算
PIDx->last_error=iError;
return(iincpid) ;
}

仿制代码

注释掉的是第一种写法,没注释的是第二种以Kp KI kd为系数的写法,实践成果是相同的。
处理进程放在了TIM6,溢出周期时间便是是PID里边采样周期(区别于反应信号的采样,反应信号采样是1M的频率)
相关代码:

void TIM6_IRQHandler(void)        //        采样时间到,中止处理函数
{          
        
if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET)//更新中止
        {
        frequency1=1000000/period_TIM4        ; //通过捕获的波形的周期算出频率
        frequency2=1000000/period_TIM1        ;
        frequency3=1000000/period_TIM2        ;
        frequency4=1000000/period_TIM5        ;
/********PID1处理**********/
        PID1.sum_error+=(incPIDcalc(&PID1,frequency1));         //核算增量并累加 
       pwm1=PID1.sum_error*4.6875  ;   //pwm1 代表即将输出PWM的占空比
          frequency1=0; //清零
     period_TIM4=0;
/********PID2处理**********/
         PID2.sum_error+=(incPIDcalc(&PID2,frequency2));         //核算增量并累加  Y=Y+Y'                
         pwm2=PID2.sum_error*4.6875 ;   //即将输出PWM的占空比 
        frequency2=0;
        period_TIM1=0;
/********PID3处理**********/
         PID3.sum_error+=(incPIDcalc(&PID3,frequency3));          //惯例PID操控
        pwm3=PID3.sum_error*4.6875 ;   //即将输出PWM的占空比
        frequency3=0;
        period_TIM2=0;
/********PID4处理**********/
            PID4.sum_error+=(incPIDcalc(&PID4,frequency4));         //核算增量并累加
         pwm4=PID4.sum_error*4.6875 ;   //即将输出PWM的占空比 
        frequency4=0;
        period_TIM5=0; 
          }

TIM_SetCompare(pwm1,pwm2,pwm3,pwm4);             //从头设定PWM值

TIM_ClearITPendingBit(TIM6, TIM_IT_Update); //铲除中止标志位                
}

仿制代码

 

TIM_SetCompare ()函数:

 

上面几个代码是PID完成的要害部分

还有整定进程:
方法有不少,这儿用的是先KP,再TI,再TD,在微调。其他的方法特别是有个尼古拉斯法我发现不适合我这个操控方针。
先Kp,便是消除积分和微分部分的影响,这儿我纠结过究竟是让Ti 等于一个很大的值让Ki=Kp*(T/Ti)里边的KI挨近零,仍是直接界说KI=0,TI=0.
然后发现前者无法找到KP使系统震动的临界值,第二个方法能够得到预期的作用:即KP大了会发生震动,小了会让系统安稳下来,当然这个时分是有稳态差错的。
随后把积分部分加进去,KI=Kp*(T/Ti)这个公式用起来,并且不断调理TI 。TI太大系统安稳时间比较长。
然后加上Kd        =Kp*(Td/T),关于系统呼应比较滞后的状况作用如同好一些,我这儿的电机反映挺快的,所以Td值很小。
最终便是几个参数调理一下,让波形美观一点。这儿的波形实践反映的是收集回来的转速值,用STM32的DAC功用输出和转速对应的电压,用示波器收集的。
最终的波形是这样的:
 

 
 

 

PID操控算法的C言语完成一 PID算法原理

   最近两天在考虑一般操控算法的C言语完成问题,发现网络上尚没有一套完好的比较系统的解说。所以总结了几天,收拾一套思路共享给咱们。

   在工业运用中PID及其衍生算法是运用最广泛的算法之一,是名副其实的全能算法,假如能够熟练掌握PID算法的规划与完成进程,关于一般的研制人员来讲,应该是满足应对一般研制问题了,而难能可贵的是,在我所触摸的操控算法傍边,PID操控算法又是最简略,最能体现反应思维的操控算法,可谓经典中的经典。经典的未必是杂乱的,经典的东西常常是简略的,并且是最简略的,想想牛顿的力学三大规则吧,想想爱因斯坦的质能方程吧,多么的简略!简略的不是原始的,简略的也不是落后的,简略到了美的程度。先看看PID算法的一般方式:

   PID的流程简略到了不能再简略的程度,通过差错信号操控被控量,而操控器自身便是份额、积分、微分三个环节的加和。这儿咱们规则(在t时间):

   1.输入量为rin(t);

   2.输出量为rout(t);

   3.差错量为err(t)=rin(t)-rout(t);

   pid的操控规则为

   了解一下这个公式,首要从下面几个问题着手,为了便于了解,把操控环境详细一下:

   1.规则这个流程是用来为直流电机调速的;

   2.输入量rin(t)为电机转速预订值;

   3.输出量rout(t)为电机转速实践值;

   4.执行器为直流电机;

   5.传感器为光电码盘,假定码盘为10线;

   6.直流电机选用PWM调速 转速用单位 转/min 表明;

  不难看出以下定论:

   1.输入量rin(t)为电机转速预订值(转/min);

   2. 输出量rout(t)为电机转速实践值(转/min);

   3.差错量为预订值和实践值之差(转/min);

   那么以下几个问题需求弄清楚:

   1.通过PID环节之后的 U(k) 是什么值呢?

   2.通过调理 PWM 的电压占空比来调理电机的转速。

   3.那么U(k)与操控电机的 PWM 之间存在怎样的联络呢?

 

看到有不少人问究竟怎样让UK值与PWM占空比值对应,然后完成占空比输出和输出操控电压对应。

(留意,我这儿评论的条件是输出操控的是电压,不是PWM方波。PWM输出后要通过滤波整形再输出操控。)

条件条件:

输出电压操控电压规模是0-10V。

给定、反应、输出电压采样输入电压规模是0-5V(通过运放)。

运用单片机AD为10位AD芯片。

那么10位AD芯片电压收集得到的数据规模便是0-1024。

PWM为 8位可调占空比方波,0对应输出占空比为0的方波,255对应输出占空比100%的方波,127对应输出50%的方波。

比方当时给定是2.5V,反应电压是1V。(KP,KI,KD等系数略,关于PID算法的整数完成我在前文中有论说怎样完成)。

那么通过AD采样

1、给定2.5V对应为 512

2、反应1V对应为 205

假定通过PID核算得到的UK为400

也就意味着输出电压应当为(400*(UPWM峰值电压))/1024

那么UK对应的PWM占空比是多少呢?

咱们知道,UK=1024对应占空比为100,也便是PWM的占空比系数为255。可知,PWM系数 = UK/4;

那么400就应当对应系数 400/4=100。

也便是输出电压=400*10/1024=3.9V

一起,因为采样精度以及PWM输出占空比精度操控的问题,将导致输出电压和期望值不是那么线性,所以,我在项目内加入了输出电压采样的操控。

采样AD输入为0-5V,所以,关于输出0-10V有一个缩小的份额。

输出10V则采样值对应为255

输出5V则采样之对应127

可知,3.9V对应AD成果为97

采样输出电压值,能够针对性的调整一下占空比输出,然后得到差错答应规模内的一个操控输出电压。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/zhishi/343041.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部