本文为翻译 Brett Beauregard 的博文
结合新的Arduino PID 库的发布,我决定发布这一系列的帖子。最后一个库虽然可靠,但并没有真正提供任何代码解释。这一次的计划是非常详细地解释为什么代码是这样的。我希望这对两类人有用:
这将是一个艰难的过程,但我想我找到了一种不太痛苦的方式来解释我的代码。我将从我所谓的 ==初学者的 PID== 开始。然后我将逐步改进它,直到我们得到一个高效、健壮的 pid 算法。
这是每个人第一次学习的 PID 方程:

img
这导致几乎每个人都编写了以下 PID 控制器:
/*working variables*/unsigned long lastTime;double Input, Output, Setpoint;double errSum, lastErr;double kp, ki, kd;void Compute(){ /*How long since we last calculated*/ unsigned long now = millis(); double timeChange = (double)(now - lastTime); /*Compute all the working error variables*/ double error = Setpoint - Input; errSum += (error * timeChange); double dErr = (error - lastErr) / timeChange; /*Compute PID Output*/ Output = kp * error + ki * errSum + kd * dErr; /*Remember some variables for next time*/ lastErr = error; lastTime = now;}void SetTunings(double Kp, double Ki, double Kd){ kp = Kp; ki = Ki; kd = Kd;}
Compute() 被定期或不定期地调用,它工作得很好。不过,这个系列并不是关于“效果很好”。如果我们要将这段代码变成与工业 PID 控制器相当的代码,我们必须解决一些问题: