为Teensy Atmega 32u4实现PI控制

时间:2019-03-07 04:42:09

标签: c pid atmega integral teensy

我正在使用Teensy Atmega32u4的标准库实现PID控制。我的控制变量是PWM信号。我的过程变量是与10kohm电位计连接的直流电动机的当前角位置,该电位计的代码可读取0至270度刻度上的位置ADC输入。设定点是激光切割操纵杆,其手柄也连接到10kohm电位计,该电位计以与过程变量相同的方式读取角位置。

我的问题是如何实现控制方案的组成部分。积分项由下式给出:

Error = Set Point – Process Variable

Integral = Integral + Error

Control Variable = (Kp * Error) + (Ki * Integral)

但是我不确定如何计算积分部分。我们是否需要考虑样本之间经过的时间或仅考虑累积误差,然后将积分部分初始化为零,以便将其真正离散化?由于我使用的是C,因此积分项可以只是全局变量吗?

我在正确的轨道上吗?

2 个答案:

答案 0 :(得分:0)

由于采样时间(计算PID的时间)始终是相同的,因此u是否用采样时间除以积分项并不重要,因为该采样时间只是一个Ki常数,但最好对积分进行除法用采样时间来表示,因此如果u更改采样时间,则PID随采样时间而变化,但这不是强制性的。

这是我为Python的Drone Robotics竞赛编写的PID_Calc函数。忽略“ [index]”,它是我制作的使我的代码通用的数组。

def pid_calculator(self, index):

    #calculate current residual error, the drone will reach the desired point when this become zero
    self.Current_error[index] = self.setpoint[index] - self.drone_position[index]      

    #calculating values req for finding P,I,D terms. looptime is the time Sample_Time(dt).
    self.errors_sum[index] = self.errors_sum[index] + self.Current_error[index] * self.loop_time 
    self.errDiff = (self.Current_error[index] - self.previous_error[index]) / self.loop_time

    #calculating individual controller terms - P, I, D.
    self.Proportional_term = self.Kp[index] * self.Current_error[index]
    self.Derivative_term = self.Kd[index] * self.errDiff
    self.Intergral_term = self.Ki[index] * self.errors_sum[index] 

    #computing pid by adding all indiviual terms
    self.Computed_pid = self.Proportional_term + self.Derivative_term + self.Intergral_term 

    #storing current error in previous error after calculation so that it become previous error next time
    self.previous_error[index] = self.Current_error[index]

    #returning Computed pid
    return self.Computed_pid

这里是否链接到git hub中我的整个PID脚本。 看看对您有没有帮助。 按向上按钮ig = f喜欢答案,并像github中的脚本一样给我的Github存储库加注星标。 谢谢。

答案 1 :(得分:0)

要添加到先前的答案,还请考虑代码中整数结束的情况。如果出现结束,应该有某种机制可以重置积分项。另外,选择最大的可用数据类型以保留积分(和)项,以避免积分溢出(通常为long long)。也要注意积分溢出。

如果您选择足够高的采样频率,则可以避免除法以减少所涉及的计算。但是,如果要尝试采样时间,则将采样时间保持为2的幂的倍数,以便可以通过移位运算来完成除法。例如,假设选择的采样时间为100ms,50ms,25ms,12.5ms。那么除法因子可以是1、1 << 1、1 << 2、1 << 4。

将PID控制器的所有关联变量都保留在单个struct中,然后将此struct用作在该PID上运行的函数中的参数非常方便。这样,代码将是模块化的,并且许多PID循环可使用相同的代码和struct的不同实例在微控制器上同时运行。这种方法在大型机器人项目中特别有用,在该项目中,您可以使用单个CPU进行许多循环控制。