热敏电阻测温电路,惠斯通电桥

  1. 简介   

   惠斯通电桥(Wheatstone bridge)电路是性能出众的通用测试电路,一般是应用于测量应力与张力、压力、流体流量和温度等物理量。

搭建一个电桥,其中R2,R3,R4都为120Ω,R1是阻值随温度变化的电阻,假设R1的电阻为250Ω(因为温度变化导致电阻增加了130Ω),假设Vs为2.5V,此时根据公式Vo = Vs * (R2 / (R1 + R2) - R4 / (R3 + R4))计算得出,Vo ≈ -439mV,仿真结果如下:

2. 热电阻温度与阻值计算

  先说一下热电阻的型号定义,以PT100举例,PT指的是铂,100指的是该电阻在0℃时呈现的阻值为100Ω,那么CU50指的就是该电阻的材料是铜,在0℃时的阻值为50Ω。

  铂热电阻(常见的如PT100,PT1000等)温度与阻值的关系为 RT = R0(1 + AT + BT² + C(T-100)T³) ,铜热电阻(常见的有CU50等)温度与阻值的关系为 RT = R0(1 + AT + BT(T-100) + C(T-100)T²),其中R0表示该电阻在0℃时的阻值,单位Ω,对于不同的电阻A,B,C的值会不同,如下:

PT100PT1000CU50
R0100100050
A0.00390830.00386231397280.00428
B-0.0000005775-0.00000065314932626-0.0000000931
C

当T≤0时 -0.000000000004183

当T>0时,0

00.00000000123

网上的那些分度表都是用这个公式生成的,下面的程序可以直接生成这3种型号的分度表:

#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <math.h>
#include <string.h>

/* 定义热电阻的型号 */
//char RES_TYPE[16] = "PT100";
//char RES_TYPE[16] = "PT1000";
char RES_TYPE[16] =    "CU50";

/**
 * \brief 铂热电阻温度与阻值的关系为 RT = R0(1 + AT + BT² + C(T-100)T³)
 *          铜热电阻温度与阻值的关系为 RT = R0(1 + AT + BT(T-100) + C(T-100)T²)
 * 其中R0表示该电阻在0℃时的阻值,单位Ω
 * 对于不同的电阻A,B,C的值会不同
 */

int main(int argc, const char *argv[])
{
    double R0, A, B, C;
    double min_t, max_t, step;    /* min_t是最小测量温度,max_t是最大测量温度,step是温度步长 */
    double result = 0;
    double i, j;

    int k;
    int fd;
    char buff[256] = { 0 };
    char acc[16] = { 0 };    /* 打印精度 */

    if (argc == 2) {
        strcpy(RES_TYPE, argv[1]);
    }

    if (!strcmp(RES_TYPE, "PT100")) {
        R0 = 100;
        A = 0.0039083;
        B = -0.0000005775;
        C = -0.000000000004183;
        min_t = -200;
        max_t = 660;
        step = 1;
        strcpy(acc, "%.02f,");    /* 保留2位小数 */
    } else if (!strcmp(RES_TYPE, "PT1000")) {
        R0 = 1000;
        A = 0.0038623139728;
        B = -0.00000065314932626;
        C = 0;
        min_t = -50;
        max_t = 300;
        step = 0.1;
        strcpy(acc, "%.03f,");    /* 保留3位小数 */
    } else if (!strcmp(RES_TYPE, "CU50")) {
        R0 = 50;
        A = 0.00428;
        B = -0.0000000931;
        C = 0.00000000123;
        min_t = -50;
        max_t = 150;
        step = 1;
        strcpy(acc, "%.03f,");    /* 保留3位小数 */
    } else {
        printf("暂不支持该型号!\n");
        return 0;
    }

    //printf("A = %f\nB = %f\nC=%f\n", A, B, C); //可以看浮点数有截断误差

    strcpy(buff, RES_TYPE);
    strcat(buff, "热电阻常用阻值对应表.csv");
    fd = open(buff, O_CREAT | O_RDWR | O_TRUNC, 0666);
    if (fd < 0) {
        printf("open failed\n");
        return 0;
    }
    memset(buff, 0, sizeof(buff));

    /* 写入横轴 */
    strcpy(buff, "温度℃,");
    write(fd, buff, strlen(buff));
    for (k = 0; k < 10; k++) {
        sprintf(buff, "%f,", k*step);
        write(fd, buff, strlen(buff));
    }
    write(fd, "\r\n", 2);

    for (i = min_t; i <= 0; i += 10 * step) {
        sprintf(buff, "%f,", i);
        write(fd, buff, strlen(buff));
        for (j = 0; j < 10; j += step) {
            if (!strcmp(RES_TYPE, "CU50")) {
                result = R0 * (1 + A * (i - j) + B * (i - j) * (i - j - 100) + C * (i - j - 100) * (i - j) * (i - j));
            } else {
                //result = R0 * (1 + A * (i - j) + B * pow((i - j), 2) + C * (i - j - 100) * pow((i - j), 3));
                result = R0 * (1 + A * (i - j) + B * (i - j) * (i - j) + C * (i - j - 100) * (i - j) * (i - j) * (i - j));
            }
            sprintf(buff, acc, result);
            write(fd, buff, strlen(buff));
            if (i == min_t) {
                break;
            }
        }
        write(fd, "\r\n", 2);
    }
    for (i = 0; i <= max_t; i += 10 * step) {
        sprintf(buff, "%f,", i);
        write(fd, buff, strlen(buff));
        for (j = 0; j < 10; j += step) {
            if (!strcmp(RES_TYPE, "CU50")) {
                result = R0 * (1 + A * (i + j) + B * (i + j) * (i + j - 100) + C * (i + j - 100) * (i + j) * (i + j));
            } else {
                //result = R0 * (1 + A * (i + j) + B * pow((i + j), 2));
                result = R0 * (1 + A * (i + j) + B * (i + j) * (i + j));
            }
            sprintf(buff, acc, result);
            write(fd, buff, strlen(buff));
            if (i == max_t) {
                break;
            }
        }
        write(fd, "\r\n", 2);
    }

    close(fd);

    return 0;
}

3. PT100和PT1000精度比较

  通过上一节算出来,当温度从0℃增加到1℃时,PT100的电阻增加0.39Ω,PT1000的电阻增加3.862Ω(网上的表是3.908Ω),可见PT1000增加的电阻是PT100的10倍,是不是意味着PT1000精度是PT100的10倍呢?从第1节的计算结果得出,当电阻值越大时,惠斯通电桥对电阻的变化越不敏感,它们是一个反比例函数的关系。

  假设我们需要测量的温度不会大于150℃,此时PT100的阻值是157.33欧姆,PT1000的阻值是1564.651Ω,根据第1节算出来的电阻选取规则,使用PT100时,其他电阻选用56Ω比较合适,使用PT1000时其他电阻选用560Ω比较合适。

  假设PT100的电阻是k,那么相同温度下PT1000的电阻就为10k,Vo的值用下面的公式计算:

  

   这时就发现一个问题,Vo的值是一模一样的。也就是说,如果使用惠斯通电桥测温度,PT100和PT1000在精度上没有任何差别

4. 放大倍数及电路确定
 

以PT100为例,固定电阻为56Ω,假设使用温度范围为-20℃~150℃,PT100的阻值变化范围为92.16Ω~157.33Ω,Vo的值范围为305mV~594mV(取绝对值)。而一般的ADC能采集0~3.3V的电压(单端电压),因此为了提高精度,可以将电压放大5倍(需要选用差分放大器),这样电压范围会变为1.525V~2.97V,更好的利用的ADC的采集范围,以此提高精度。

  可以使用INA128U对信号进行放大,INA128U的放大倍数为1+50K/RG,取RG为12.5k,那么放大倍数就是5,仿真如下图:

其中INA128U的6号引脚输出电压是经过放大后的电压值再加上5号引脚的电压,因此,如果想要继续提示精度,可以算出温度变化范围内电压的差值,为594-305=289mV,为了尽可能达到3.3V的满量程,可以将放大倍数调整到11倍,同时在5号引脚施加一个偏置电压,让INA128U的输出电压落在0~3.3V的区间内,按照下图所示方法连接,当温度达到最大值150℃时,放大器输出最小值(-0.594*11)+6.6=0.066V,当温度达到最小值-20℃时,放大器输出(-0.305*11)+6.6=3.245V

5. 使用惠斯通电桥与电阻分压测电阻的优点分析

热敏电阻使用3线制接法,先看直接分压的情况,如下图:

 Vo的计算公式为:

可见Vo是Rx的反比例函数。随着Rx的增加,Vo的变化会越来越不明显。

  再看惠斯通电桥的情况:

 Vo的计算公式为:

 这与电阻直接分压的算法差不多,只不过是括号里多减了个1/2,而且它们的导数是相同的,并且它们受到线上电阻a的影响是一样的,这意味着从计算方法上看,惠斯通电桥法与电阻分压法是完全一样的。

5.2 从特殊情况考虑

  我们知道惠斯通电桥有一种平衡状态,就是Vo为0的情况,此时有一个特性,就是:

一般让R2,R3,R4都相等,记作R,此时

化简之后得到Rx=R,此时式子里没有a,也就是说当电桥平衡时,即Vo=0时,惠斯通电桥可以完全消除线上电阻的影响,得到的结果是最精确的。

  但是电阻分压法就不能有这个优点吗?

  电阻分压法的特殊情况是Vo=1/2Vs,此时Rx+a=R2+a,Rx=R2,同样消除了线上电阻的影响。

  但是!当惠斯通电桥达到平衡状态时,不需要考虑参考电压Vs,无论Vs的值为多少,Vo的值都是0,而电阻分压法的平衡状态是Vo=1/2Vs,Vo的值会受Vs的影响。所以惠斯通电桥真正的优点是:在平衡状态时消除了参考电源的影响

   不过话又说回来,因为被测电阻是变化的,要使惠斯通电桥达到平衡状态,需要改变其他3个电阻的值,在实际情况下这是不现实的。

6. 推荐使用方法(使用运算放大器)

  既然惠斯通电桥的优点那么不明显,那就直接用简单的电阻分压法吧。

  将PT100串联一个56Ω的电阻测量2个电阻之间的电压,当温度变化范围为-20℃~150℃时,PT100的阻值变化范围为92.16Ω~157.33Ω,Vo的值范围为656mV~945mV,假设ADC的采样范围为0~3.3V,那么可以将电压放大3倍,得到的电压范围为1.968V~2.835V,这样虽然将采样精度提高了3倍,但是0~1.968V这个区域浪费了。最好的情况就是656mV~945mV这个范围刚好能对应上0~3.3V的范围,这时就要用运算放大器了,将其作为一个减法器放大。具体接法如下图:

   必须用电压跟随,否则Ux的值会随着放大倍数的改变而改变。

  Ux的值最小为657mV,那么就在另一端造一个657mV出来,如下图:

  

   为了留点余量,这里造出来的电压是639mV。然后将这两个电压接到减法器里,如下图:

 根据运放的特性,得到以下2个式子:

   联立化简得到如下式子:

   现在认为制造一种特殊情况,就是R1=R2,R3=R4,那么上面的式子就可以化简为:

   

   如果再让R3=R1,那么此时Uo=Ux-Ua,这就是减法器。

  但是我们还是要利用一个R3/R1这个数,因为Ua是我们造出来的电压,它等于Ux的最小值,此时Uo的值为0,而当,Ux变化到945mV时,我们希望Uo的值尽可能接近3.3V,那么就可以取R3=11R1,此时放大倍数为11倍,最大输出电压为3.179V,尽可能的利用了ADC的采样范围。

   而实际情况需要留一些余量,按照上面的接法,让Ua的值为639mV,比Ux的最小值再小一点,放大倍数设为10倍,理论上输出电压值范围在180mV~3.06V之间,尽可能的利用了ADC的采样范围。

补充:

  虽然理想运放最大输出电压接近电源电压,但是要根据实际情况而定,比如我使用的LM324,手册上说的是:Large Output Voltage Swing: 0V to VCC-1.5V,因此他的输入电源要大于3.3+1.5=4.8V,取5V比较合适。

  • 8
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值