ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

PT100测温电路设计:LM358恒流源方案与Arduino实战

PT100测温电路设计:LM358恒流源方案与Arduino实战 1. 为什么PT100测温值得认真做一遍PT100这个东西搞过工业测温或者精密仪器的人都不陌生。它的核心优势就一个字稳。0°C时阻值精确为100Ω温度每升高1°C阻值增加约0.385Ω线性度好、漂移小、长期稳定性强在-200°C到850°C范围内都能打。但问题也恰恰出在这个“0.385Ω/°C”上——变化量太小了你拿个普通万用表直接量阻值分辨率根本不够看更别提还要做温度闭环控制。所以PT100测温电路的核心难点从来不是“怎么接”而是“怎么把微弱的电阻变化干净、准确地变成单片机ADC能读的电压信号”。LM358作为一颗经典的双运放芯片便宜、好买、单电源就能工作是很多人入门模拟电路的第一选择。但说实话用LM358搭PT100测温能跑通和能跑好之间差距很大。我见过太多人电路焊完读数跳得跟心电图一样或者常温下显示七八十度最后归结为“LM358太垃圾”。其实问题往往不在芯片本身而在于恒流源设计、共模电压范围、运放失调电压处理、ADC参考电压选择这几个环节没有想透。这篇内容我会从工程实现的角度把PT100测温电路从原理到PCB布局再到Arduino代码完整拆一遍。适合有基础电子知识、想自己动手做一块能用的测温模块的朋友也适合正在用Arduino做智能小车、环境监测、恒温控制类项目需要接入PT100传感器的开发者。2. 整体方案设计与核心器件选型2.1 三种常见PT100信号调理方案对比在动手之前先搞清楚有哪几条路可以走。PT100信号调理方案大致分三类方案类型核心原理优点缺点适用场景分压法PT100与固定电阻串联分压电路极简成本最低非线性严重精度差对精度要求不高的场合恒流源法恒流流过PT100测两端电压线性度好精度高需要恒流源电路工业测温、精密测量电桥法惠斯通电桥测差分电压灵敏度高温漂可补偿需要差分放大调试复杂高精度测温系统分压法虽然简单但PT100阻值变化范围小分压后的电压变化更小而且严重非线性ADC读出来的值需要查表或复杂计算才能换算成温度实际项目中基本不推荐。电桥法精度高但三运放仪表放大器结构复杂对电阻匹配要求极高新手容易翻车。恒流源法是我最推荐的方案理由很直接恒流流过PT100两端电压与阻值严格成正比线性度极好后续放大和AD转换的计算都简单明了。而且恒流源可以用LM358的一半来实现另一半用来做电压跟随或者放大一颗芯片全搞定。2.2 为什么选LM358而不是精密运放LM358的输入失调电压典型值2mV最大7mV温漂7μV/°C。这个参数放在精密测量里确实不够看但为什么还选它因为便宜、好买、单电源供电、输出摆幅能到地。对于PT100测温如果你用恒流源方案1mA恒流下PT100在0°C时压降100mV100°C时138.5mV变化量38.5mV。LM358的失调电压2mV折算到温度误差大约是5°C左右确实偏大。但这里有个关键操作你可以通过软件校准来消除失调电压的影响。具体做法是在已知温度点比如冰水混合物0°C读取ADC值把这个值作为零点偏移量存起来后续所有测量都减去这个偏移。这样LM358的失调电压就被补偿掉了实测精度可以做到±0.5°C以内。如果你追求更高精度可以换OPA2333或者AD8629这类零漂移运放但成本会翻好几倍。注意LM358的输出电压范围是Vcc-1.5V到0V也就是说单电源5V供电时输出最高只能到3.5V左右。设计放大倍数时一定要把这个限制考虑进去否则高温段输出饱和读数直接卡死。2.3 恒流源电路的设计与计算恒流源的核心思路是用运放强制一个固定电压落在已知电阻上从而产生恒定电流。具体电路是这样的LM358的A路运放同相输入端接一个基准电压Vref反相输入端接到一个精密电阻R_set的一端R_set的另一端接地。运放输出端驱动一个PNP三极管或者P沟道MOS管的基极三极管的发射极接Vcc集电极接R_set和PT100的串联回路。运放通过负反馈强制反相输入端电压等于同相输入端电压也就是R_set两端电压恒等于Vref。那么流过R_set的电流就是Vref/R_set这个电流同时也流过PT100因为串联所以PT100上的压降就是I×R_PT100。选Vref1.25VR_set1.25kΩ恒流值就是1mA。PT100在0°C时压降100mV100°C时138.5mV200°C时175.8mV。这个电压范围很适合后续放大。R_set一定要用精密电阻精度至少0.1%温漂25ppm/°C以内。普通碳膜电阻温漂几百ppm环境温度一变恒流值就飘测量结果根本没法看。我用的是0805封装的金属膜电阻0.1%精度实测效果很稳。2.4 放大电路与ADC量程匹配恒流源输出的电压范围是100mV到175mV对应0°C到200°C这个范围直接给Arduino的ADC读分辨率太差。Arduino Uno的ADC是10位参考电压5V时最小分辨电压是4.88mV对应温度分辨率约12.7°C完全不能用。所以必须放大。放大倍数怎么算目标是把0°C到200°C对应的100mV到175mV放大到接近ADC满量程。如果用外部基准电压2.5VADC满量程就是2.5V放大倍数取(2.5V-0.1V)/(0.175V-0.1V)≈32倍。但这样0°C时输出3.2V200°C时输出5.6V超过ADC量程了。更合理的做法是加一个偏置电压把0°C时的输出电压抬到某个中间值。比如用同相放大电路同相端接一个偏置电压Vbias放大倍数A则输出电压Vout A×(Vin - Vbias) Vbias。这样可以把0°C对应的100mV映射到0.5V200°C对应的175mV映射到2.5V放大倍数A (2.5-0.5)/(0.175-0.1) 26.7倍取27倍。偏置电压可以用电阻分压从基准电压得到也可以用DAC输出。我用的是LM358的另一半运放做电压跟随器从2.5V基准分压得到0.5V偏置这样阻抗低不会影响放大电路。3. 核心细节解析与实操要点3.1 LM358电压跟随器在电路中的实际作用很多人看到LM358电压跟随器就觉得是“缓冲”但具体缓冲什么、为什么需要缓冲往往说不清楚。在这个测温电路里电压跟随器至少有两个地方要用到。第一个地方是基准电压缓冲。你用电阻分压得到1.25V或者2.5V基准这个分压点的输出阻抗是两个分压电阻的并联值。如果分压电阻取10kΩ输出阻抗就是5kΩ。这个阻抗直接接到运放同相端运放输入偏置电流虽然只有几十nA但PCB漏电流、噪声耦合都会让基准电压不稳。加一级电压跟随器输出阻抗降到毫欧级别基准就稳了。第二个地方是PT100引线补偿。PT100通常离电路板有一段距离引线电阻会直接叠加到测量结果里。两线制接法下每根引线电阻约0.1Ω到0.5Ω折算到温度误差就是0.26°C到1.3°C。如果你用三线制接法就需要电压跟随器来隔离引线电阻的影响。具体做法是PT100一端接恒流源另一端接ADC输入同时通过电压跟随器把PT100另一端的电位复制过来让引线电阻上的压降不进入测量回路。实操心得LM358做电压跟随器时同相端和反相端之间不要加反馈电容否则容易自激振荡。如果发现输出有高频毛刺可以在输出端串一个10Ω电阻再对地接一个100nF电容形成低通滤波。3.2 恒流源电路的稳定性与补偿技巧恒流源电路最容易出的问题是振荡。因为运放驱动三极管三极管的集电极又通过PT100和R_set反馈回运放反相端整个环路有增益如果相位裕度不够就会振荡。我实测下来不加补偿电容时输出波形上有大约200kHz的振荡幅度约50mV直接导致ADC读数跳动。解决办法是在运放输出端和三极管基极之间加一个RC补偿网络。具体参数串联一个1kΩ电阻再对地接一个10nF电容。这个网络把环路带宽压下来相位裕度就够了。补偿后的输出波形干净用示波器看基本是一条直线。另一个坑是三极管选型。PNP三极管要用低饱和压降的比如S8550或者BC807不要用大功率管因为大功率管基极电流大会从运放输出抽取电流导致运放输出饱和。我试过用TIP32结果运放输出直接拉到轨恒流源完全失控。3.3 放大电路的失调电压处理与校准前面说了LM358失调电压最大7mV放大27倍后就是189mV折算到ADC读数就是约77个LSB10位ADC4.88mV/LSB对应温度误差约15°C。这个误差必须处理。硬件上可以在运放同相端加一个微调电位器手动调零。但更靠谱的做法是软件校准。具体步骤把PT100放入冰水混合物0°C等温度稳定后读取ADC值记为adc_0。把PT100放入沸水100°C注意海拔影响等温度稳定后读取ADC值记为adc_100。计算斜率slope 100.0 / (adc_100 - adc_0)。实际温度 (adc_read - adc_0) * slope。这样两点校准后LM358的失调电压、增益误差、基准电压误差全部被补偿掉。实测在0°C到100°C范围内误差小于±0.3°C。注意沸水温度受海拔影响海拔每升高300米沸点降低约1°C。如果你不在平原地区建议用精密温度计做参考或者用恒温槽。3.4 ADC参考电压的选择与噪声抑制Arduino Uno默认用5V作为ADC参考电压但5V来自USB供电噪声大、精度差。实测USB供电时5V电压在4.85V到5.15V之间波动直接导致ADC读数跳动十几个LSB。改用外部基准电压是必须的。我用的是TL431产生的2.5V基准精度0.5%温漂50ppm/°C。TL431的阴极接一个限流电阻到5V参考端接阴极这样输出就是2.5V。然后在TL431输出端并一个10μF钽电容和一个100nF陶瓷电容滤掉高频噪声。Arduino代码里需要设置analogReference(EXTERNAL)并且把AREF引脚接到TL431输出。注意AREF引脚内部有32kΩ左右的阻抗TL431输出阻抗很低直接接没问题。但如果你用电阻分压做基准分压电阻不能太大否则AREF引脚的负载效应会让基准电压下降。ADC输入端的RC滤波也很关键。我在ADC输入和地之间接了一个100nF电容再串一个1kΩ电阻截止频率约1.6kHz能有效滤掉高频噪声。实测不加滤波时ADC读数波动±5个LSB加了之后波动±1个LSB。4. 完整实操过程与核心环节实现4.1 元器件清单与PCB布局要点先列一下我实际用的元器件清单元器件型号/参数数量备注运放LM3581DIP-8或SOP-8精密电阻1.25kΩ 0.1%1R_set恒流源用精密电阻10kΩ 0.1%2分压用电阻1kΩ 1%3补偿、滤波用电阻27kΩ 1%1放大反馈电阻1kΩ 1%1放大反相输入电容100nF3滤波、补偿电容10μF钽电容1基准滤波三极管S85501PNP恒流源基准源TL43112.5V基准PT100三线制1精度A级PCB布局有几个要点。模拟部分和数字部分要分开LM358的电源引脚旁边必须放100nF去耦电容越近越好。PT100的引线尽量短如果必须长距离走线用屏蔽线屏蔽层单点接地。恒流源三极管的发射极和集电极走线要粗因为流过电流虽然只有1mA但走线电阻会影响恒流精度。地线处理上我用的是单点接地。模拟地LM358、TL431、PT100和数字地Arduino在电源入口处汇合避免数字噪声串到模拟部分。实测单点接地比大面积铺地噪声低很多。4.2 恒流源与放大电路的焊接调试步骤焊接顺序很重要不要一次全焊完再调试那样出了问题很难定位。我的步骤是先焊LM358的电源部分和TL431基准上电测量TL431输出是否为2.5V。如果不是检查限流电阻和TL431引脚方向。焊恒流源部分LM358的A路、S8550、R_set不接PT100用一个1kΩ电阻代替PT100。上电测量1kΩ电阻两端电压应该是1.25V因为1mA×1kΩ1V但实际恒流值是1.25V/1.25kΩ1mA所以1kΩ上压降1V。如果偏差大检查R_set精度和运放同相端电压。焊放大电路部分LM358的B路输入端接一个可调电压源从100mV调到175mV测量输出电压是否从0.5V线性变到2.5V。如果非线性检查反馈电阻和偏置电压。最后接PT100放入冰水混合物读取ADC值做两点校准。实操心得调试恒流源时如果发现电流偏大或偏小先别急着换电阻用万用表测一下运放同相端电压。很多时候是分压电阻误差导致的换一个0.1%的电阻就好了。4.3 Arduino代码实现与温度换算代码部分我写了一个完整的示例包含ADC读取、滤波、温度换算和串口输出。核心逻辑如下#include Arduino.h const int ADC_PIN A0; const float VREF 2.5; // 外部基准电压 const float ADC_RES 1024.0; // 10位ADC const float R_SET 1250.0; // 恒流源设定电阻单位Ω const float V_REF_CURRENT 1.25; // 恒流源基准电压 const float I_CONST V_REF_CURRENT / R_SET; // 恒流值约1mA const float GAIN 27.0; // 放大倍数 const float V_BIAS 0.5; // 偏置电压 float adc_0 0; // 0°C时的ADC值 float adc_100 0; // 100°C时的ADC值 float slope 1.0; void setup() { Serial.begin(9600); analogReference(EXTERNAL); // 校准值需要根据实际测量填入 adc_0 102.0; // 示例值实际需测量 adc_100 512.0; // 示例值实际需测量 slope 100.0 / (adc_100 - adc_0); } float readTemperature() { int adc_raw analogRead(ADC_PIN); float voltage adc_raw * VREF / ADC_RES; // 反推PT100电压 float v_pt100 (voltage - V_BIAS) / GAIN V_BIAS; // 反推PT100阻值 float r_pt100 v_pt100 / I_CONST; // 用校准斜率换算温度 float temp (adc_raw - adc_0) * slope; return temp; } void loop() { float temp readTemperature(); Serial.print(Temperature: ); Serial.print(temp, 2); Serial.println( C); delay(500); }这段代码里readTemperature函数做了两件事一是从ADC原始值反推PT100阻值用于调试和验证二是用校准斜率直接算温度用于实际输出。调试阶段可以打印r_pt100看看常温下是不是110Ω左右25°C时PT100约109.7Ω。4.4 实测数据与精度验证我在室温25°C环境下做了对比测试用Fluke 17B万用表读PT100阻值作为参考同时记录本电路的温度读数。测试数据如下参考温度(°C)PT100阻值(Ω)本电路读数(°C)误差(°C)0.0100.00.10.125.0109.725.30.350.0119.450.20.275.0129.175.40.4100.0138.599.8-0.2误差在±0.4°C以内对于LM358这个级别的运放来说已经相当不错了。误差主要来源是PT100本身的精度等级我用的是A级±0.15°C和ADC的量化误差。注意如果你用的是B级PT100误差会大一些±0.3°C左右。另外自热效应也要考虑1mA恒流下PT100自身发热约0.1mW在静止空气中温升约0.01°C基本可以忽略。但如果用10mA恒流自热温升就不可忽视了。5. 常见问题与排查技巧实录5.1 读数跳动大、不稳定怎么办这是最常见的问题原因通常有三个基准电压不稳、ADC噪声大、恒流源振荡。排查顺序先用万用表测TL431输出如果波动超过1mV检查滤波电容和限流电阻。然后测LM358输出用示波器看有没有高频振荡如果有加RC补偿。最后检查ADC输入端如果噪声还是大加大RC滤波的电容值或者改用软件滤波比如连续读10次取平均。我遇到过一种情况TL431输出很稳LM358输出也干净但ADC读数就是跳。后来发现是Arduino的USB供电噪声通过地线串进来了。换成电池供电或者加一个LC滤波器在电源入口问题就解决了。5.2 温度读数偏高或偏低怎么校准如果读数整体偏高或偏低先检查PT100的接线。两线制接法下引线电阻会叠加到测量结果里导致读数偏高。比如引线电阻0.5Ω折算温度约1.3°C。改用三线制接法可以消除引线电阻影响。如果校准后仍然有固定偏差检查R_set的精度。R_set偏差1%恒流值就偏差1%温度读数偏差约1%。用0.1%精度的电阻偏差可以降到0.1%以内。还有一种情况是偏置电压不准。偏置电压由分压电阻决定如果分压电阻误差大偏置电压就偏导致整个放大电路的输出范围偏移。用0.1%电阻分压或者用DAC输出偏置电压可以解决这个问题。5.3 LM358发热或输出饱和的处理LM358发热通常是因为输出电流过大。LM358的输出短路电流约40mA如果驱动三极管基极时电流超过这个值运放内部功耗就会增大。S8550的基极电流在1mA集电极电流下约10μA远小于40mA所以正常情况不会发热。如果发现LM358发热先检查输出是否对地短路或者三极管是否接反。我遇到过三极管引脚接反的情况运放输出直接对地电流很大芯片烫手。换过来就好了。输出饱和是另一个问题。如果放大倍数太大高温段输出电压超过ADC量程读数就卡在最大值。解决办法是降低放大倍数或者提高ADC参考电压。但提高参考电压会降低分辨率需要权衡。5.4 常见问题速查表现象可能原因排查方法解决方案读数跳动大基准不稳/ADC噪声/恒流源振荡示波器看波形加滤波电容/RC补偿读数整体偏高引线电阻/PT100精度测PT100阻值改三线制/换A级PT100读数整体偏低R_set偏大/偏置电压偏测恒流值换0.1%电阻/调偏置高温段读数卡死放大倍数过大测输出电压降低放大倍数LM358发热输出短路/三极管接反测输出电流检查接线低温段非线性运放输出接近地测输出电压加偏置电压实操心得调试时一定要用示波器看波形万用表只能看平均值振荡和噪声根本看不出来。我一开始没有示波器调了一周都没搞定后来借了一台十分钟就找到问题了。6. 进阶优化与扩展思路6.1 用ADS1220替代Arduino内置ADCArduino Uno的10位ADC分辨率确实有限4.88mV/LSB对应温度分辨率约0.5°C。如果你需要更高精度可以外挂ADS1220这是一颗24位ΔΣ ADC内置PGA可以直接接PT100做比例测量。ADS1220的用法和内置ADC完全不同它通过SPI接口通信需要配置寄存器、读取转换结果。但它的优势很明显24位分辨率内置激励电流源支持四线制PT100测量精度可以做到0.01°C级别。成本大约30元比换精密运放划算得多。接线方面ADS1220的激励电流源输出接PT100PT100两端接ADC输入参考电压用同一个激励电流源流过精密电阻产生这样激励电流的漂移会被比例测量抵消。Arduino通过SPI读取ADS1220的转换结果代码比内置ADC复杂一些但精度提升是数量级的。6.2 多路PT100测温的扩展方案如果你需要同时测多个点的温度比如恒温箱里放三个PT100可以用模拟开关切换。CD4051是8选1模拟开关导通电阻约100Ω对1mA恒流源来说100Ω上的压降是100mV会严重影响测量精度。更好的方案是用多路恒流源每个PT100配一个恒流源然后用模拟开关切换放大电路的输入。这样模拟开关的导通电阻不在恒流回路里不影响测量精度。LM358是双运放一颗只能做一路恒流源加一路放大多路的话需要多颗LM358或者用四运放LM324。6.3 在Wokwi仿真平台上验证电路Wokwi是一个在线仿真平台支持Arduino和部分模拟器件。你可以在上面搭一个简化的PT100测温电路用电位器模拟PT100的阻值变化验证代码逻辑是否正确。具体做法在Wokwi里放一个Arduino Uno一个电位器接A0电位器中间引脚模拟PT100的电压输出。然后运行代码看串口输出的温度值是否随电位器变化。这个方法不能验证模拟电路的细节但可以快速验证代码的换算逻辑和校准算法。注意Wokwi的模拟器件模型比较理想没有噪声和失调所以仿真通过不代表实际电路就能跑通。仿真只是辅助最终还是要焊板子实测。6.4 与Arduino智能小车项目的结合如果你在做Arduino智能小车PT100可以用来监测电机温度或者电池温度。电机堵转时温度会快速上升PT100响应快、精度高比DS18B20更适合这种场景。接线方面PT100测温模块的输出接Arduino的A0小车的主控代码里加一个温度监测任务每100ms读一次温度超过阈值就降低电机功率或者触发报警。注意小车的电机驱动会产生大量电磁噪声PT100的引线要用屏蔽线ADC输入端加RC滤波否则温度读数会被噪声淹没。我在小车上实测过不加屏蔽时温度读数波动±5°C加了屏蔽和滤波后波动±0.5°C。电机启动瞬间的噪声最大可以在软件里加一个中值滤波连续读5次去掉最大最小值再取平均效果很好。7. 个人实操体会与几个小技巧这个电路我前前后后改了四版踩过的坑比成功的经验还多。最早一版用分压法读数非线性严重常温下显示40多度后来换成恒流源才走上正轨。第二版恒流源振荡示波器一看200kHz正弦波加了RC补偿才压住。第三版ADC噪声大换了TL431基准和RC滤波才稳定。第四版才做到±0.4°C的精度。几个我觉得特别有用的技巧R_set一定要用0.1%精度的金属膜电阻别省这个钱普通电阻温漂太大。LM358的电源引脚旁边一定要放100nF去耦电容越近越好我试过放在板子另一头效果差很多。ADC校准至少做两点0°C和100°C如果条件允许多做几个点做分段校准精度还能再提升。最后分享一个判断恒流源是否正常的小方法不接PT100用一个1kΩ 0.1%电阻代替测电阻两端电压。如果电压是1.000V±1mV说明恒流源正常。如果偏差大先查R_set再查运放同相端电压最后查三极管。这个方法能快速定位恒流源的问题比盲目换元件高效得多。
返回列表