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的值会不同,如下:
PT100 | PT1000 | CU50 | |
R0 | 100 | 1000 | 50 |
A | 0.0039083 | 0.0038623139728 | 0.00428 |
B | -0.0000005775 | -0.00000065314932626 | -0.0000000931 |
C | 当T≤0时 -0.000000000004183 当T>0时,0 | 0 | 0.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比较合适。