嵌入式工业温湿度采集编程:实现多测点的温度误差控制在±0.1℃以内
±0.1℃不是“读个传感器取平均”能到的。DS18B20、SHT30类数字传感器分辨率够但系统精度通常落在±0.3℃级;要做到±0.1℃,工业做法一般是PT100/PT1000 + 恒流源激励 + Σ-Δ ADC + 多点校准。 湿度走电容式湿敏元件,温度做补偿就行,别指望湿度也到0.1级。
一、信号链:恒流源+差分ADC
PT100在0℃是100Ω,每1℃约变0.385Ω。MCU内置12位ADC有效位只有10位上下,温度分辨率约0.2℃,不够用。 正经配置:
激励电流 0.5~1mA(1mA自热约0.1℃,严控场合取500μA)
三线制消去引线电阻,四线制最准
仪表放大器或ADC内置PGA做差分放大
24位Σ-Δ ADC(ADS1220/ADS1248),20SPS+50Hz陷波
参考电阻用0.01%低温漂,比例法测量
/* ADS1220读PT100原始码值 */
int32_t rtd_read_raw(uint8_t ch){
ads_set_mux(ch, ch+1);
ads_start();
while(!ads_drdy());
return ads_read_24();
}
/* 比例法:R = CODE * R_REF / 0x7FFFFF */
float rtd_resistance(int32_t code, float r_ref){
return ((float)code / 8388607.0f) * r_ref;
}
二、PT100分度转温度
IEC 60751标准分度用Callendar-Van Dusen,工程上常用简化查表+线性插值,避免浮点多项式:
typedef struct { float r; float t; } rt_t;
const rt_t LUT[] = {
{100.00f,0},{119.40f,50},{138.51f,100},
{157.33f,150},{175.86f,200}
};
float rtd_to_temp(float r){
for(int i=0;i<4;i++){
if(r>=LUT[i].r && r<=LUT[i+1].r){
float k=(r-LUT[i].r)/(LUT[i+1].r-LUT[i].r);
return LUT[i].t + k*(LUT[i+1].t-LUT[i].t);
}
}
return r<100?0:200;
}
范围更宽就补-50/0/25/75/100/150点,插值误差远小于0.1℃。
三、多测点轮询+滤波
多路靠模拟开关切换,每路采样时间拉满,别用最短采样周期:
#define N_CH 8
float temp[N_CH];
void temp_scan(void){
static int ch;
int32_t raw = rtd_read_raw(ch);
float r = rtd_resistance(raw, R_REF);
float t = rtd_to_temp(r);
/* 中值+滑动平均双滤波 */
temp[ch] = iir_filter(ch, t);
ch = (ch+1)%N_CH;
}
IIR一阶足够:
float iir_filter(int ch, float v){
static float f[8];
f[ch] = f[ch]*0.8f + v*0.2f;
return f[ch];
}
强干扰工位加一级中值滤波剔毛刺,别只用算术平均——偶发尖峰平均不掉。
四、多点校准:两点起步,五点更好
出厂只做单点偏移,全温区会偏。标准做法放恒温槽,跟标准铂电阻比对:
0℃冰水混合物
25℃室温点
50/75/100℃工作区主段
高温点按工艺补
每通道存斜率a和截距b:
float calib[N_CH][2]; // a,b
float temp_cal(int ch, float t){
return calib[ch][0]*t + calib[ch][1];
}
非线性明显就分段存表,按当前温度选区间插值。
校准值存EEPROM/FRAM,带校准日期;现场每6个月复校一次,换探头必须重校。
五、湿度采集与温度补偿
湿度用HDC3021/SHT30类数字模块走I2C,读数本身带厂内校准:
i2c_read(SHT30_ADDR, 0xE000, buf, 6);
float rh = -6+125*((buf[0]<<8)|buf[1])/65535.0f;
float t = -45+175*((buf[3]<<8)|buf[4])/65535.0f;
湿度精度受温度影响,露点计算用温度值:
float dewpoint(float t, float rh){
float a=17.27,b=237.7;
float g=a*t/(b+t)+logf(rh/100);
return b*g/(a-g);
}
温度测点准了,湿度才好算;别拿未校准温度去补湿度。
六、硬件避坑清单
两线制PT100长线→引线电阻直接漂0.25℃/0.1Ω
激励电流走滤波电阻→引入压降误差
模拟数字地混接→工频干扰跳码
参考电压用MCU内部→温漂吃掉0.1℃
采样时间过短→放大器未建立,读数抖
传感器贴功率器件旁→自热+热延迟
屏蔽层两端接地→地环路串进50Hz
校准只做25℃单点→高低温偏
换PT100不重校→分度曲线变了
滤波只平均不剔野值→尖峰留尾巴
七、落地顺序
PT100三线制+500μA恒流源
ADS1220类Σ-Δ ADC,PGA+20SPS
每通道独立滤波RC,模拟区单点接地
轮询读码→比例法算电阻→分度表插值
IIR+中值滤波,1~2SPS足够温度场
恒温槽多点校准,存a/b或分段表
湿度走I2C数字传感器,温度补偿露点
校准系数存FRAM,定期复校
多测点±0.1℃的本质是信号链别拖后腿:恒流源稳、引线误差消掉、ADC有效位够、参考低温漂;软件只负责滤波和校准修正。数字传感器方便但精度天花板就在那,真要工业级温度闭环,PT100+Σ-Δ ADC这套虽然麻烦,却是能把误差压进0.1℃的唯一靠谱路径;湿度别硬凑同精度,温度准了湿度自然稳。





