c - 为 Teensy Atmega 32u4 实现 PI 控制

标签 c atmega teensy pid-controller

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

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

Error = Set Point – Process Variable

Integral = Integral + Error

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

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

我走在正确的道路上吗?

最佳答案

由于采样时间(计算 PID 后的时间)始终相同,因此您是否将积分项除以采样时间并不重要,因为该采样时间仅充当 Ki 常数,但最好将积分除以项以采样时间为单位,因此,如果您更改采样时间,则 PID 会随采样时间而变化,但这不是强制性的。

这是我用 python 为无人机机器人竞赛编写的 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=fu 你喜欢答案,并为我的 Github 存储库加注星标(我喜欢 github 中的脚本)。 谢谢。

关于c - 为 Teensy Atmega 32u4 实现 PI 控制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55036226/

相关文章:

c - 尝试 portaudio 示例,但得到 "ld: symbol(s) not found for architecture x86_64"

c - 函数陷入无限循环

ATMEGA328 的 c 库创建

c - ATMEGA 2560 uart 代码未在 minicom 上给出正确的输出

arduino - 什么是 rosidl_runtime_c__double__Sequence 类型?

c++ - 移位寄存器74HC595输出电流

c - 迷宫死端过滤器检查

c - 未接收来自 TCP 连接的文件传输

arduino - AVR USART通讯问题