小白学习日记-----arduino如何使用PID控制算法

ardiuino如何使用PID控制算法

引言

PID:Proportional(比例)、Integral(积分)、Differential(微分)的缩写。顾名思义,PID控制算法是结合比例、积分和微分三种环节于一体的控制算法,PID控制的实质就是根据输入的偏差值,按照比例、积分、微分的函数关系进行运算,运算结果用以控制输出。

连续控制系统理想pid控制规律

在这里插入图片描述
u(t):是输出值;
kp:是比例增益;
e(t):是设定值与测量值之间的差值;
Tt:积分时间常数;
Td:微分时间常数;

两边同时进行拉氏变换

     U(s) = Kp(1 + 1/(Tt*s) + Td*s) * E(s);

传递函数

      C(s)  =  Kp(1 + 1/(Tt*s) + Td*s)

对pid三个参数的理解

kp: 能提高系统的动态响应速度,迅速反映误差,从而减少误差,但是不能消除误差,简单来说就是越大越快越小越慢但是可能会超调或者过慢有很多弊端,并且太大了会不稳定。
Ki:一般就是消除稳态误差,只要系统存在误差积分作用就会不断积累,输出控制量来消除误差,如果偏差为零这时积分才停止,但是积分作用太强会使得超调量加大,甚至使系统出现震荡
Kd:微分显然与变化率有关,你可以把它理解为导数,它可以减小超调量来克服震荡,使系统稳定性提高,同时加快响应速度,使系统更快有更好的动态性能。

PID控制器的使用

在计算机控制系统中,由于控制是使用采样控制,它只能根据采样时刻的偏差计算控制量,而不能像模拟控制那样连续输出控制量量,进行连续控制。所以数字PID控制也属于离散型控制系统。(注重点:实际使用pid控制器是离散控制系统)

数字型PID控制算法可分为位置式PID和增量式PID控制算法。

位置式PID:位置式PID控制的输出与整个过去的状态有关,用到了误差的累加值;
增量式PID:而增量式PID的输出只与当前拍和前两拍的误差有关,

(1) 位置式PID
由于是离散型控制系统,积分项和微分项不能直接使用,必须进行离散化处理。离散化处理的方法为:以 T 作为采样周期,k 作为采样序号,则离散采样时间 kT 对应着连续时间t,用矩形法数值积分近似代替积分,用一阶后向差分近似代替微分,可作如下近似变换:
在这里插入图片描述
根据以上公式的转换,便可得到离散的PID表达式
在这里插入图片描述
位置式PID算法的特点:
由于全量输出,所以每次输出均与过去状态有关,计算时要对ek进行累加,工作量大,耗内存;并且,因为计算机输出的uk 对应的是执行机构的实际位置,如果计算机出现故障,输出的 uk将大幅度变化,会引起执行机构的大幅度变化,有可能因此造成严重的生产事故,这在实生产际中是不允许的。

(2) 增量式PID
所谓增量式 PID 是指数字控制器的输出只是控制量的增量∆uk。当执行机构
需要的控制量是增量,而不是位置量的绝对数值时,可以使用增量式PID控制算法进行控制。
增量式 PID 控制算法可以通过位置式PID公式推导出。由位置式PID公式可以得到控制器的第 k-1 个采样时刻的输出值为:
在这里插入图片描述
对位置式PID取增量可以得到:
在这里插入图片描述
增量式PID算法的特点:
增量式 PID 控制算法与位置式 PID 算法公式相比,如果计算机控制系统采用恒定的采样周期 T,一旦确定Kp、Ti、Td参数,只要使用前后三次测量的偏差值,就可以由增量式PID公式求出控制量。计算量小的多,因此在实际中得到广泛的应用。

PID实际使用

增量法计算公式:

  //OUT=Kp*[E(t)-E(t-1)]+Ki*E(t)+Kd*[E(t)-2*E(t-1)+E(t-2)]
  ERROR = setpoint - input
  SUMERROR += ERROR
  OUT = KP*ERROR + KI*SUMERROR + KD*(LASTERROR - PREVERROR)input
  PREVERROR =  LASTERROR 
  LASTERROR = ERROR
arduino写的pid测试程序
int setpoint = 100;
long sumerror;
double kp = 0.3,ki = 0.15,kd = 0.1;
int lasterror;
int input = 10;
int output;
int nowerror;
void setup() {
  // put your setup code here, to run once:
    Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  nowerror = setpoint - input;
  sumerror += nowerror; 
  output = kp*nowerror + ki*sumerror + kd*(lasterror - nowerror);
  lasterror = nowerror;
  input += output;
  Serial.println(input);
  delay(50); 
 
}
kp  ki  kd  还没有调节。
arduino串口显示效果如下

在这里插入图片描述

您好!要使用Arduino控制JGB37-520编码器电机,您需要将编码器连接到Arduino,并使用适当的代码来控制它。以下是一些基本步骤: 1. 确保您有一个JGB37-520编码器电机和一个Arduino板。 2. 连接编码器的电源和地线到Arduino的5V和GND引脚。 3. 将编码器的A相和B相输出连接到Arduino的两个数字引脚。可以选择任何可用的数字引脚,但最好选择支持外部中断的引脚。 4. 在Arduino上编写代码来读取编码器的输出并控制电机。 以下是一个示例代码,可以用作起点: ```arduino // 定义编码器的引脚 const int encoderPinA = 2; // A相 const int encoderPinB = 3; // B相 // 定义电机驱动引脚 const int motorPin1 = 4; // 电机控制引脚1 const int motorPin2 = 5; // 电机控制引脚2 // 定义编码器计数值和方向 volatile long encoderCount = 0; volatile int encoderDirection = 0; void setup() { // 配置引脚模式 pinMode(encoderPinA, INPUT_PULLUP); pinMode(encoderPinB, INPUT_PULLUP); pinMode(motorPin1, OUTPUT); pinMode(motorPin2, OUTPUT); // 配置编码器中断 attachInterrupt(digitalPinToInterrupt(encoderPinA), updateEncoder, CHANGE); } void loop() { // 在这里实现您的控制逻辑 // 例如,可以根据编码器计数值来控制电机的转动方向和速度 // 注意:在这个示例中,我只是简单地改变电机的方向,您可能需要根据实际需求进行更复杂的控制 if (encoderDirection == 1) { // 顺时针方向 digitalWrite(motorPin1, HIGH); digitalWrite(motorPin2, LOW); } else if (encoderDirection == -1) { // 逆时针方向 digitalWrite(motorPin1, LOW); digitalWrite(motorPin2, HIGH); } else { // 停止 digitalWrite(motorPin1, LOW); digitalWrite(motorPin2, LOW); } } // 编码器中断处理函数 void updateEncoder() { // 读取A相和B相的状态 int encoderStateA = digitalRead(encoderPinA); int encoderStateB = digitalRead(encoderPinB); // 根据状态改变计数值和方向 if (encoderStateA == encoderStateB) { encoderDirection = -1; } else { encoderDirection = 1; } encoderCount += encoderDirection; } ``` 这只是一个简单的示例代码,您可以根据您的需求对其进行修改和调整。请确保仔细阅读JGB37-520编码器电机的规格和连接方式,并根据需要进行相应的调整。 希望这可以帮助到您!如有任何问题,请随时提问。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值