会飞的小东 2023-09-22 14:54 采纳率: 50%
浏览 38
已结题

PID算法的输出结果如何转换成pwm

问题

嵌入式PID算法的输出结果是如何转换成pwm控制的

遇到的现象和发生背景

我现在在开发中需要运用到pid算法,主要是压力传感器和流量传感器,pwm主要控制的是比例阀,控制着流量的大小,而流量也会影响输出端的压力大小,现在反馈的是传感器压力的值和我设定的压力值之间的差值作为e(k)

如下是我现在的pid主要代码流程
//根据增量式离散PID公式
//▲u(k) =  Kp[e(k)-e(k-1)]+Ki*e(k)+Kd[e(k)-2e(k-1)+e(k-2)]
//pwm+=Kp[e(k)-e(k-1)]+Ki*e(k)+Kd[e(k)-2e(k-1)+e(k-2)]
//e(k)代表本次偏差 
//e(k-1)代表上一次的偏差  以此类推 
//e(k-2)代表上上次的偏差
//pwm代表增量输出
typedef struct PID
{ 
  float kp;
  float ki;
  float kd;
  float ek;     //当前误差
  float ek_1;   //上一次误差
  float ek_2;   //上上一次误差
  float limit;  //限幅
  float pid_out;   //pid增量累加和
  //float ek_sum; //误差总和
}PID;

static PID pid;

void PID_Init()
{
    pid.kp = 5;             //这个接口后续调出方便调试使用
    pid.ki = 0.25;
    pid.kd = 3;
    pid.limit = 1000;
    pid.ek = 0;
    pid.ek_1 = 0;
    pid.ek_2 = 0;
    pid.pid_out = 0;
}

// 增量式PID控制
float PID_Increase(int Encoder,int Target)
{
    float delta_pwm = 0;
    pid.ek = Target - Encoder; // 计算当前误差
    //pid.ek_sum += pid.ek;      //求出偏差的积分
    delta_pwm = pid.kp*(pid.ek - pid.ek_1) + pid.ki*pid.ek + 
    pid.kd*(pid.ek - 2*pid.ek_1 + pid.ek_2);   //增量式PID控制器
    pid.ek_1 = pid.ek;   //保存上一次偏差 
    pid.ek_2 = pid.ek_1; //保存上上一次的偏差
    if(pid.pid_out > pid.limit) //这段判断后续再做判断要不要
    {
      delta_pwm =  pid.limit;
    }
    else if(pid.pid_out < -pid.limit)
    {
      delta_pwm =  -pid.limit;
    }
    pid.pid_out += delta_pwm;
    return pid.pid_out;
}

我的解答思路和尝试过的方法

这是我的PID流程图

img

我想要达到的结果,如果你需要快速回答,请尝试 “付费悬赏”

我现在想知道我用PID增量算法得出来的结果那个数值,是怎么转换成pwm 0-100的开合度的?是不是有一个比例系数?是如何计算的?
我这流量和压力两个参数是不是要用串级pid好一点

  • 写回答

8条回答 默认 最新

  • Leodong. 2023-09-22 16:22
    关注

    该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
    将PID算法的输出结果转换为PWM控制信号的方式通常是通过映射函数来实现。PWM信号的占空比(duty cycle)通常是在0到100之间的百分比,表示开合度。您可以使用以下方法将PID算法的输出映射到PWM占空比范围:

    1、 确定PID输出的范围:根据您的具体应用和系统要求,确定PID输出的最小值和最大值,例如`outputMin`和`outputMax`。
    
    2、 缩放PID输出:将PID的输出值缩放到0100之间的范围。可以使用以下公式:
    
    
       scaledOutput = (pidOutput - outputMin) * (100.0 / (outputMax - outputMin))
    
       ``scaledOutput`是缩放后的输出值,`pidOutput`是PID算法的输出值。
    

    3、 限制PWM占空比范围:根据PWM的要求,将缩放后的输出值限制在0到100之间,以确保PWM占空比的有效范围。可以使用以下代码:

       if (scaledOutput > 100.0) {
         scaledOutput = 100.0;
       } else if (scaledOutput < 0.0) {
         scaledOutput = 0.0;
       }
    

    4、 将缩放后的输出值作为PWM占空比应用于控制信号。具体的应用方法取决于您所使用的嵌入式平台和硬件接口。您可能需要查阅相关文档或资料以了解如何使用PWM模块或函数来生成相应的PWM信号。

    关于您提到的流量和压力两个参数是否需要使用串级PID,这取决于您的系统要求和控制目标。串级PID可以在多个级别对系统进行控制,其中一个PID控制器的输出作为另一个PID控制器的输入。通过串级PID,您可以更好地处理多个物理量之间的相互影响和耦合关系。根据您的应用需求和系统特性,您可以考虑使用串级PID来实现更高级别的控制和优化。

    请注意,上述代码和方法仅供参考,并根据实际情况进行调整和修改。具体的实现方式可能会因嵌入式平台、硬件接口和应用要求的差异而有所不同。


    如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
  • mornbin 2023-09-22 15:08
    关注

    1、PID增量算法得出来的结果那个数值不应该是个差值吗?它反应的是当前系统与目标之前的差距,不是直接对应0-100的结果的;
    2、是不是有一个比例系数?没有
    3、是如何计算的?是指pwm对应的阀的开合度?如果指的是这个的话,看下阀的产品规格书或者自己测试下就知道了;
    4、流量和压力两个参数是不是要用串级pid好一点?流量和压力之间是不是有对应关系,有的话,本质上控制一个就可以了,没有的话无法同时控制

    评论
  • 小星星星球 2023-09-22 15:11
    关注

    通过PID的测试数据,将PID输出映射到合适的范围。PID算法的输出通常是一个连续的数值,将其映射到PWM占空比的范围内。例如,假设PID输出范围为[-100, 100],而PWM占空比范围为[0, 100],则可以通过线性映射将PID输出映射到PWM占空比范围内

    评论
  • CSDN-Ada助手 CSDN-AI 官方账号 2023-09-22 16:04
    关注

    【以下回答由 GPT 生成】

    如何将PID算法的输出结果转换为PWM控制信号?

    1. 如何将PID算法的输出结果转换成0-100的PWM开合度?

    在将PID算法的输出结果转换为0-100的PWM开合度之前,首先需要了解一下PWM控制信号的工作原理。

    PWM (Pulse Width Modulation) 是一种调制技术,通过控制脉冲的宽度来实现对电平的调节。一般来说,PWM的周期是一定的,而占空比则表示高电平的占整个周期的百分比。因此,我们可以利用PID算法的输出结果来实现对PWM占空比的控制。

    具体的转换步骤如下: - 首先,确定PID控制输出的范围。假设PID控制输出的范围是[-1000, 1000]。 - 然后,根据PWM的工作周期,计算出PID控制输出的比例系数。假设PWM的周期是10 ms,那么比例系数就是 100 / 1000 = 0.1 。 - 最后,将PID算法的输出乘以比例系数,并加上 50 ,即可得到0-100的PWM占空比。

    下面是具体的代码实现:

    # 假设PID控制输出的范围是[-1000, 1000]
    pid_output = ... # 这里是PID算法的输出结果
    
    # 假设PWM的周期是10 ms
    pwm_period = 0.01
    
    # 计算比例系数
    scale_factor = 100 / 1000
    
    # 将PID算法的输出转换为PWM占空比
    pwm_duty_cycle = pid_output * scale_factor + 50
    
    # 输出PWM占空比
    print("PWM占空比:", pwm_duty_cycle)
    

    这样,你就可以将PID算法的输出结果转换为0-100的PWM开合度了。

    2. 是否存在一个比例系数来进行转换?如果是的话,如何计算这个比例系数?

    是的,存在一个比例系数来进行转换。这个比例系数取决于PID算法的输出范围和PWM的周期。

    假设PID算法的输出范围是[PID_min, PID_max],PWM的周期是T,那么比例系数可以通过以下公式计算得出:

    比例系数 = PWM占空比总范围 / (PID_max - PID_min)

    其中,PWM占空比总范围就是你想要的PWM占空比的范围,比如0-100。

    具体的代码实现如下:

    # 假设PID算法的输出范围是[PID_min, PID_max]
    PID_min = -1000
    PID_max = 1000
    
    # 假设PWM的周期是10 ms
    pwm_period = 0.01
    
    # 假设PWM占空比的范围是0-100
    pwm_duty_cycle_range = 100
    
    # 计算比例系数
    scale_factor = pwm_duty_cycle_range / (PID_max - PID_min)
    
    # 输出比例系数
    print("比例系数:", scale_factor)
    

    3. 是否需要使用级联PID来更好地控制流量和压力这两个参数?

    根据问题描述,你需要同时控制流量和压力这两个参数,那么在实际应用中,考虑使用级联PID可以更好地实现这个目的。

    级联PID控制是一种将多个PID控制器串联起来,通过优先级的方式控制不同的参数。在该情况下,可以设计两个独立的PID控制回路,一个用于控制流量,另一个用于控制压力。

    具体的控制框图如下:

                   +-------------+
      Setpoint  -->|   Flow PID  |
                   |             |--> Flow Control
                   +-------------+
                        | 
        Flow      ------+
      Measurement
                        |
                   +-------------+
      Setpoint  -->| PressurePID |
                   |             |--> Pressure Control
                   +-------------+
                        |
        Pressure  ------+
      Measurement
    

    其中,流量和压力各自有一个独立的PID控制回路,分别负责控制流量和压力。流量控制和压力控制之间存在耦合关系,当流量变化时会影响压力,然后压力又反过来影响流量。通过使用级联PID控制,可以更好地处理这种耦合关系,提高控制的准确性和稳定性。

    希望以上解答对你有所帮助,如果有任何问题,请随时提问。


    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论
  • 数据大魔王 2023-09-22 18:49
    关注

    限制PWM值

    if (pwm_value < 0) {
        pwm_value = 0;
    } else if (pwm_value > pwm_range) {
        pwm_value = pwm_range;
    }
    
    
    
    评论
  • 呈两面包夹芝士 2023-09-22 20:05
    关注

    引自GPT
    根据你的描述,你正在使用PID算法来控制比例阀的输出,以调节流量。你的问题是如何使用PID算法的输出结果(一个浮点数)转换成PWM信号的0-100开合度。

    首先,PID算法的输出结果是一个误差值,这个误差值是通过计算当前偏差(e(k))与上一次和上上一次的偏差之和得到的。然后,这个误差值被用来调整比例阀的输出,即pwm的值。

    要将PID算法的输出结果转换为PWM信号的0-100开合度,你需要设定一个比例系数。这个比例系数可以根据你的需求和系统的特性来设定。例如,如果你希望压力在0-100%范围内变化时,流量也在0-100%范围内变化,那么你可以将比例系数设置为100。这样,当PID算法的输出结果为0时,PWM信号的开合度为0%,当PID算法的输出结果为1时,PWM信号的开合度为100%。

    代码示例:

    float PID_Out = PID_Increase(Encoder, Target); // PID算法的输出结果
    float pwm = PID_Out * 比例系数; // 将PID算法的输出结果转换为PWM信号的开合度
    

    至于你提到的流量和压力两个参数是否要用串级PID好一点,这取决于你的系统特性和需求。串级PID是一种特殊的控制策略,它将两个独立的PID控制器串联起来,可以提高系统的响应速度和稳定性。但是,串级PID的控制逻辑相对复杂,需要对系统的特性有深入的理解。如果你的系统对响应速度和稳定性要求较高,且你对串级PID的控制逻辑有足够的理解,那么可以考虑使用串级PID。否则,你也可以先尝试使用单个PID控制器,看其效果如何,再决定是否需要使用串级PID。

    评论
  • 心梓知识 2023-09-23 01:07
    关注

    结合GPT给出回答如下请题主参考
    将PID算法的输出转换成PWM控制信号的具体步骤如下:

    1. 将PID算法输出进行缩放,将输出映射到0-100%的范围内,即将输出值乘以一个比例系数,常用的比例系数为100。

    2. 根据PWM的调制方式,将缩放后的PID输出值转换成一个占空比(duty cycle),通常采用百分比表示。

    3. 将PWM信号发送到比例阀的控制器中,使其控制阀门的开度,进而控制流量的大小。

    下面是示例代码,展示如何将PID输出转换成PWM控制信号:

    #define PWM_PERIOD 1000  // PWM周期为1000us
    #define PID_SCALE 100    // PID输出缩放系数为100
    
    double pid_output;  // PID算法输出值
    uint32_t pwm_duty;  // PWM占空比
    
    // 将PID输出值转换成PWM占空比
    pwm_duty = (uint32_t)(fabs(pid_output) * PID_SCALE);
    if (pwm_duty > 100) {
        pwm_duty = 100;
    }
    
    // 根据PWM周期和占空比生成PWM信号,发送到比例阀的控制器
    pwm_start(PWM_CHANNEL, PWM_PERIOD, pwm_duty);
    

    上述代码中,pwm_start()函数是一个示意用的函数,用于启动PWM信号输出。具体实现方式可以根据具体的硬件平台和驱动库来确定。

    评论
  • Khoo_ 2023-09-24 16:16
    关注

    把pid输出乘上pwm_max/pid_max_out

    评论
查看更多回答(7条)

报告相同问题?

问题事件

  • 系统已结题 10月3日
  • 已采纳回答 9月25日
  • 赞助了问题酬金15元 9月22日
  • 创建了问题 9月22日

悬赏问题

  • ¥15 shopify网站提速
  • ¥15 深海控制器DSE7320MKII和博世ECU间can通讯知识
  • ¥15 Ru的复折射率用于FDTD 200nm到1200nm
  • ¥15 使用Fiddler抓包,textview的乱码如何解决
  • ¥50 trio连接驱动器报错
  • ¥15 有谁懂nhanes的权重计算啊
  • ¥15 欧姆龙PLC 电机控制 限位
  • ¥30 如何处理shell命令接收到的视频流并实时播放出来
  • ¥15 虚心请教C#的代码优化问题
  • ¥15 有偿求做台风过境全过程模拟仿真