打印
[程序源码]

过零开关的功率控制精度与时间延迟精度的悖论

[复制链接]
990|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 shipeng1989 于 2020-7-22 10:47 编辑

使用PID控温差不多有4年了,有一个问题一直困扰我至今。曾经以为这个问题是个悖论只能寻找此消彼长的微妙平衡再无任何解决方案,但其实我错了就在前不久一个**乍现的清晨我在睡梦中居然找到了答案。具体问题是这样的:“有一个可调温控温装置(其实是热风拆焊台)调温范围:100~500摄氏度,要求控温精度±1℃以内。”    根据以上问题描述,由于控制温度高低的唯一办法是控制单位时间T内平均加热功率P,也就是假定供电电压不变加热占空比D的大小决定恒温的温度。也就可以得到温度和加热占空比D呈一一对应的关系,100~500度就需要至少400分之一的功率控制精度,但实际上由于市电的频率只有50Hz还要做到过零开关,最小功率控制精度是半个市电周期th=10ms,根据 “P=D*发热丝饱和功率/400” 得400分之一的精度对应占空比周期为:400*10ms=4秒,这对于控制热风这种比热小的介质来说是根本无法容忍的,你会发现无论你怎么调整PID的参数都始终不能实现恒温。当然如果采集温度的AD分辨率足够高你可以不需要如此高的功率分辨率,你可以在温度还在1度以内变化时提前做出功率补偿使温度始终在1度以内上下浮动这样也能满足要求。经过实验我发现功率精度最低可以降到1/50,此时的加热周期T=50*10ms=0.5秒,但肉眼还是可以明显的看到发热丝的红暗交替,可能是由于采温热电偶的滞后性导致实际AD却是平稳的,如用热电偶测温仪实测温度也是稳定的。以上就是我四年前的解决方案,只是发热丝的红暗交替问题让我不太舒服。
    直到我看到了某大厂做的热风控温产品,在保证控温精度的前提下肉眼几乎看不出发热丝的红暗交替现象。我便知道这个问题另有出路,于是我便开始一直在寻求这个终极解决方案也就有了前文所提到的**乍现的瞬间。这个思路说来也简单:如下图假如占空比周期T为10个市电半周,占空比D=5,按照通常的控制思路是这样的:


每次打开5个半周后会有5个半周关闭,如果按照1/50的功率控制精度就有:250ms开加热,250ms关加热这样做当然会造成热风温度的短时波动。终极解决方案是这样的:将上图中的ON和OFF打散再让他们充分混合得到你中有我我中有你的效果:

这样整体效果还是5个市电半周开5个市电半周关,也就是占空比依然是5/10.当然5/10是个特例,如果1/50的功率精度占空比为27/50应该怎么办呢?可理解为27个开和23个关,将27/23等于1余4,即为开和关为1:1余4,也就是一次开后就有一次关但23个开关周期后还多余4个开没有打开,这应该怎么办呢?办法就是把这4个开再分散到那23个开关周期中去:也就是23/4=5余3,现在可以把余数忽略了,最后输出结果是每5个ONOFF周期多插入一个ON这样就可以得到最大限度分散的27/50的占空比了。当然口说无凭为了直观的验证这个方案特引入一个验证算法的好方法:利用微软的Visual Studio验证并打印出实验结果:
实验代码:
实现1/100功率分辨率的分散占空比控制效果:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

int main(void)
{
        for (uint8_t heat_duty = 0; heat_duty <= 100; heat_duty++)
        {
                uint8_t i, j, k, l, m, sub_t, pos_nag,on_cycles=0,off_cycles=0; _Bool HEAT1ON_A;
                i = heat_duty;
                if (i > 50) { j = 100 - i; pos_nag = 1; }
                else { j = i; i = 100 - j; pos_nag = 0; }
                sub_t = i == 0 || j == 0 ? 100 : i / j + 1;
                l = j != 0 ? i % j : 1; if (l == 0)l = 1;
                for (uint8_t period = 0; period < 100; period++)
                {
                        k = period; m = k / (j / l * sub_t + 1);
                        m = j==0 ? 0 : m > l ? k - l : k - m;
                        HEAT1ON_A = m % sub_t == sub_t >> 1 ? !pos_nag : pos_nag;
                        if (HEAT1ON_A)on_cycles++;
                        else off_cycles++;
                        printf(HEAT1ON_A!=0?"*":"-");
                }
                if (heat_duty!=on_cycles || on_cycles+off_cycles!=100)printf("%d,%d/%d\n", heat_duty,on_cycles,off_cycles);
                else printf("\n");
        }
        return 0;
}

运行结果:( ‘ * ’ 表示开,‘ - ’表示关)
                                           占空比0~50

                                         占空比51-100

经过以上验证后发现逻辑上是没有问题的可以实现0-100内任意占空比的分散混合开关效果,但实际控温效果却差强人意,温度居然还没有原来不分散的稳定。这个脸实在打的让人猝不及防,本着严谨的求知态度步步为营却依然被现实打脸。哪位高人过来解释一下问题究竟出在哪里?在这里我也给出一个我的解释:可能是由于我的占空比控制是实时更新的,我并不会等到整个占空比周期结束后再更新占空比值,而是每次过零我都会根据当前的温度AD值重新计算占空比,我认为这样才能保证快速的反应能力,否则加热时负载的变化就不能及时的做出反应。但是在分散开关占空比控制中由于开和关是错开的,在一个占空比周期中占空比的邻近抖动可能会得到意想不到的效果:本来是降低加热功率反而会得到更高的功率,因此就会导致温度的不稳定。





使用特权

评论回复

相关帖子

沙发
chongdongchen| | 2020-7-23 08:47 | 只看该作者
按照你的想法,要PID何用?


使用特权

评论回复
评论
chongdongchen 2020-7-23 09:52 回复TA
@shipeng1989 :控制导通角,无需高分辨率占空比,达到你的控制精度应该没多大问题 
shipeng1989 2020-7-23 09:35 回复TA
兄嘚不要抬杠,PID就是用来计算这个占空比D的,否则你怎么知道某个设定温需要给多少占空比值?红框中这个结论是假设温度已经恒温在设定温度了在其他条件变化之前占空比是不是也应该是一个恒定值? 
板凳
xiaoxiong1988| | 2020-7-23 10:27 | 只看该作者
PID 计算占空比   占空比转换为导通角  
你试试看看还忽明忽暗么?温度还会控制不住么

使用特权

评论回复
评论
shipeng1989 2020-7-23 18:12 回复TA
说导通角有逃避问题的嫌疑,过零开关是原则不能动摇。因为必须考虑EMI和安规 
地板
xiaoxiong1988| | 2020-8-11 11:45 | 只看该作者
xiaoxiong1988 发表于 2020-7-23 10:27
PID 计算占空比   占空比转换为导通角  
你试试看看还忽明忽暗么?温度还会控制不住么 ...

逃避不逃避  你找一个相对应的产品 看一下 是如何控制导通角的 从而如何控温的  ,忽明忽暗  必然是 加热时间过长

使用特权

评论回复
5
AVRx007| | 2020-8-11 16:47 | 只看该作者
PDM

使用特权

评论回复
6
wlzeagle| | 2020-8-12 12:45 | 只看该作者
顶一下

使用特权

评论回复
7
zhxzhxzzhhxx| | 2020-8-13 19:21 | 只看该作者
11100 和 10101 比例一样,但是均匀度可不一样

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

29

主题

134

帖子

1

粉丝