做嵌入式控制器和 HVAC 系统这些年,我最大的体会是:大家总觉得测温度就是“放个传感器、读个数字”,可一到现场就发现事情没那么简单。嵌入式设备里,功率器件、电源模块和 MCU 本身都会发热,传感器稍微放近一点就测到一堆无关的热;HVAC 应用里,想要监控的是风管末端、换热器表面、回风口这种离控制板很远的点位,线缆一拉长,误差和干扰就跟着来。后来我把这套方案在项目里彻底用顺:用 PJ85718DM 配合 STM32F334R8,一颗传感器芯片负责本地温度测量,另一路通过外接测温二极管完成远程温度采集,两路数据在 MCU 里统一滤波、校准、告警和上报。这套组合支撑过嵌入式板级热保护和 HVAC 风管监控两类项目,效果比较稳定。这篇总结会把硬件连接、固件实现、实测结果和 HVAC 联动里值得注意的细节全部写出来,给正要踩同样坑的人省点时间。
1. 这套测温方案要解决的实际问题:本地与远程温度为什么不能混在一起测
1.1 板级测温与 HVAC 现场测温的两类典型需求
嵌入式板级测温,和 HVAC 里的测温,表面上都在读温度,实际需求差别挺大。板级这块,关注的是“控制器自己的健康状态”:MOS 桥臂是不是过热、电源是否有异常温升、MCU 的结温有没有接近上限等等。测温点密集集中在 PCB 上,而且往往需要快速响应,希望在过温的一两个周期内就能触发保护,避免器件烧毁。HVAC 那块,关注的则是“被控环境的真实温度”:房间回风温度、送风管道里的温度、换热器进出水温度、室外环境温度。这些点位距离控制板通常有几十厘米到几十米,而且测温区域本身可能同时受到阳光、气流、设备启停的影响,对响应速度的要求没那么高,但对长期稳定性和抗干扰能力的要求非常高。
两类需求放在一起看,本地温度和远程温度根本是不同维度的事情。如果只用一个传感器点,要么装在控制板上,测不到远端工况;要么单独拉线放到远方,那控制板自身温度又成了盲区。PJ85718DM 的双通道设计恰好匹配这个矛盾:它内部自带一个测温通道,封装上又提供远程二极管输入接口。把内部通道当作“本地温度”,把外接二极管放在风机、风管或者换热器表面当作“远程温度”,一颗芯片、两根 I2C 线,就能同时拿到两个不同物理空间里的温度数据。
1.2 分开测的核心动机:传感器自热与引线误差
这里要回答一个很多人问的问题:为什么不能只用一个测温点做“代表”?因为温度测量本身会改变被测区域的温度场,这叫传感器自热。NTC 热敏电阻工作在分压电路里,电流虽然不大,但持续通电也会在探头上积累零点几度的热量;如果是数字温度传感器,自身 ADC 工作、内部稳压器工作,同样会带来一定的自热。传感器放在 PCB 上,旁边就是电源模块或者驱动电路,测出来的数值总会比实际环境偏高那么几度。
远程测量的另一大障碍是引线误差。普通的 NTC 探头把长导线接进 ADC,导线本身的电阻、插座接触电阻、绝缘老化后的漏电流,全都会混进分压比例里,让温度值无规律漂移。我在某个项目里就遇到过,一根 10 米长的 NTC 线,冬天和夏天测量的偏移都不一样,查了很久才发现是线缆受潮导致绝缘阻抗下降。
PJ85718DM 这类测量芯片的思路和“测分压电阻”完全不一样。它测量的是 PN 结正向压降的变化,或者两个不同激励电流下压降的差值,这种测量方式是电流激励,而不是电压分压。引线电阻虽然会引入串联阻抗,但对电流激励下的压降差测量影响很小,配合芯片内部的串联电阻补偿算法,远程只要用的是双端差分接线,线长十几米都不会出现明显的系统偏差。这也是我后来坚决把 HVAC 现场探头从“一根 NTC 拉到 ADC”改成“二极管差分线接温度芯片”的原因。
1.3 一颗芯片分担两个通道的工程价值
从工程效率讲,双通道方案省掉的东西更多。如果按传统做法,本地和远程温度至少各要一个传感器、各要一条独立的采样链路。本地用 NTC,就得配分压电阻和 ADC 通道;远程用 PT100,就得配恒流源、仪表放大器和参考电压源,整个模拟链路调起来非常繁琐。用 PJ85718DM 的话,本地通道和远程通道都在一颗芯片内部完成 ADC 采样,MCU 只需要通过 I2C 读两个寄存器,模拟部分的复杂度和故障概率都降下来。
同时,两路温度是同一颗芯片同时采样的,通道之间的时间延迟几乎可以忽略。这个特性在做 HVAC 温差控制的时候特别有价值,比如说“送风温度和回风温度之差”几乎可以实时反映换热器效率,如果两路温度分别在不同时刻采样,算出来的差值是时间错位的,控制逻辑很容易出现振荡。从维护角度看,少一条模拟链路,就少一批潜在的故障点,现场维护人员也更容易上手。
2. 选型逻辑:PJ85718DM 和 STM32F334R8 为什么能搭在一起
2.1 PJ85718DM 的测温原理和接口细节
先讲传感器本身。PJ85718DM 从封装上看是一个典型的八脚温度监测芯片,工作电压大概在 3.0V 到 5.5V 之间,片上集成了本地测温通道、远程二极管测量通道、I2C 接口和状态寄存器。本地测温利用芯片内部的微尺寸二极管,用芯片内部 ADC 在不同激励电流下采集电压差,换算成近似线性的数字温度值。远程测温也是类似的机制,但它通过 D+ 和 D- 两个引脚向外提供一个激励电流,在外部二极管两端产生压降,芯片内部把不同电流下的压降差采集回来,经过数学模型换算成远端二极管的结温。这个温度代表的是外部二极管所在位置的温度,而不是芯片自身温度,所以只要你能把一根细小探头的二极管固定到目标测温点,它就能隔着导线把那里的温度“读”回来。
PJ85718DM 输出温度的分辨率和精度都达到了商用级:本地通道典型误差在 ±0.5°C 左右,远程通道在温度范围内的典型精度也可以控制在 ±1°C 以内,远程通道的温度范围往往比本地还要宽一点,因为 PN 结本身在很宽的温度下都有稳定的电学特性。通信接口是标准 I2C,从机地址由地址引脚或硬件默认值确定;寄存器结构也是常见温度传感器的习惯,有配置寄存器、本地温度数据寄存器、远程温度数据寄存器、状态寄存器和报警比较设定值寄存器。MCU 启动后只需要写一次配置,然后周期性地读取两个温度寄存器就行。
2.2 STM32F334R8 为这套方案提供了什么
STM32F334R8 是电源控制和电机控制场景里经常出现的 MCU,Cortex-M4F 内核,主频 72MHz,带硬件单精度浮点单元。对温度监测来说,Cortex-M4F 有点“性能过剩”,但正因为如此,浮点运算做 PID、滤波和温度校准都特别顺手。128KB Flash 和 32KB RAM 装下一个小型 HVAC 控制器的全部固件绰绰有余,不需要外扩存储。
真正让 STM32F334R8 适合这个方案的是它的模拟外设:内置多路比较器、可编程增益放大器和 12 位 ADC。后面做风扇调速、电加热器 PWM 控制、甚至用 PWM 和 ADC 做自校准的时候都用得上。如果你打算让温度采集串入恒温控制闭环,MCU 自带的 HRTIM 高分辨率定时器可以输出非常精确的 PWM 波形来驱动加热器或风机,控温分辨率不会因为定时器精度而拖后腿。而且它的功耗模式和时钟系统比较灵活,现场 HVAC 控制盒有时需要低功耗待机状态,只用电池或小容量电源维持传感器周期巡检。我在这套方案里习惯用内部 RC 时钟,因为 I2C 通信本身对时钟精度要求不高,内部时钟能省一块外部晶振的成本。唤醒后用软件延时等待传感器转换完成,整个巡检周期几十毫秒内能读完两个温度值,待机电流基本可以做到微安级别。
2.3 为什么不用 NTC 或 PT100 直接接 ADC
很多朋友选测温方案时,第一反应永远是 NTC 加 ADC,因为便宜而且从单片机入门教材里就学过。我自己早期也这么干,但后来被现实教育了。把 NTC、PT100 和数字温度芯片放在一个表里对比,能看得非常清楚:
| 对比项 | NTC + 单片 ADC | PT100 + 调理电路 | PJ85718DM + I2C |
|---|---|---|---|
| 线性度 | 差,需要分段查表或多项式拟合 | 较好,但仍需调理电路 | 芯片内置校准,输出接近线性温度 |
| 引线长度影响 | 线阻直接进分压,线长影响明显 | 三线制/四线制才有效,接线复杂 | 差分二极管激励,线长影响小 |
| 抗干扰能力 | 一般,模拟信号怕纹波和串扰 | 较好,但电路复杂 | 数字接口,信号线短且抗干扰强 |
| 本地/远程双点 | 需要两个传感器两路链路 | 需要两套恒流源和放大器 | 一颗芯片两路通道 |
| 故障自检 | 基本没有,开路表现为满量程 | 需要额外检测逻辑 | 内置开路/短路状态标志 |
| 系统成本 | 低 | 高 | 中等 |
NTC 最便宜,但它最大的问题是把“物理量到电压”的换算分散在传感器和外围电路里,任何一环老化、温漂都会让数据偏移。PT100 精度更高,但好一点的调理电路要投入仪表放大器和精密基准,占的面积和成本都不小。PJ85718DM 属于那种“把杂事都干完”的芯片,它自己在内部搞定激励、采样、补偿和温度换算,MCU 只负责读结果和干活。对于要批量生产、现场要维护的设备,少一条模拟链路就意味着少一批潜在的故障点。还有一层原因是系统软件的可维护性:用 NTC 时,硬件批次不同,B 值可能不一样,每批板子都得重新标定补偿表;PJ85718DM 内部有厂商标定数据,软件拿到的数字温度值已经是补偿后的结果,不同批次之间互换不影响测量一致性,这在生产线上省了很多事。
3. 硬件搭建:本地测温点与远程测温点的接线、电源和布局细节
3.1 最小系统连接与传感器接线
这套方案的最小硬件其实很简单:一块 STM32F334R8 最小系统板,一颗 PJ85718DM,两个 I2C 上拉电阻,以及一个远程测温二极管。传感器部分的接线逻辑是:PJ85718DM 的 VDD 接 3.3V,GND 接系统地,SDA 和 SCL 分别通过 4.7kΩ 电阻上拉到 3.3V,I2C 地址我根据硬件默认值设为 0x48,这也是很多温度传感器 IC 的通用默认地址,具体以芯片数据手册为准。VDD 和 GND 之间放了 0.1μF 陶瓷电容,系统供电入口再并联一个 10μF 电解电容,用来吸收电源线上的低频扰动。
远程二极管接在 D+ 和 D- 引脚上,这里需要注意极性。D+ 对应二极管的正极,D- 对应负极。由于二极管接成类似保护结构,接反了读出来的温度基本是一堆乱码或者直接报错,我第一次搭的时候就在这个细节上浪费了十几分钟。为了抑制来自长引线的射频干扰,我在 D+、D- 靠近芯片端各串了一个 2.2kΩ 电阻,然后在两个引脚之间并联了一个 1000pF 陶瓷电容,组成一阶低通滤波。这个电容取值不能太大,超过 2200pF 之后远程转换速度会变慢,实际使用中 1000pF 是均衡后的选择。
3.2 电源与参考电压的处理
STM32 和传感器共用一个 3.3V 电源当然也能跑,但如果现场有继电器、交流接触器、电机驱动器这些负载,电源纹波往往很夸张。我在实际控制盒里给传感器单独做了一路 LDO,比如把 24V 现场电源先降到 5V,再用低压差线性稳压器降到 3.3V,传感器电源和 MCU 的 I/O 电源用一颗 0Ω 电阻做单点连接,这样数字电路的地电流不会直接窜进传感器的模拟地回路。如果你的应用里有模拟比较器参与过温保护,还要注意 MCU 的 VDDA 和 VREF+ 引脚不能直接接在开关电源纹波上,每个引脚都配了磁珠加电容的滤波网络。
一个特别容易被忽略的点:远程二极管的双绞线要和电源线保持距离。HVAC 控制盒里往往把强电和弱电放同一个端子排,如果远程测温线跟交流线平行走线超过 20 厘米,即使有滤波电容,某些瞬间的干扰脉冲照样能耦合进传感器,导致偶尔跳一个异常温度。我的做法是把双绞线单独走线槽,或者至少和动力线保持 5 厘米以上间距,必要时套一层屏蔽铝箔并单端接地。这些点写出来平平无奇,现场出问题时却很难排查,最好在布线阶段就规避掉。
3.3 远程测温二极管的选型与安装
远程通道对二极管的要求其实很简单:要有一个干净的 PN 结,而且最好用发射结。很多工程师直接用贴片二极管,但我测试得到的结论是,把普通小信号三极管的基极和集电极短接,利用基极和发射极之间的 PN 结当作测温二极管,效果通常会更好。因为三极管的发射结面积和掺杂浓度更稳定,不同批次之间的压降特性更一致。型号方面用常见的通用小信号三极管就可以,封装越小越好,热容小、响应快,也方便贴在目标表面。焊接时把引脚尽量剪短,避免引脚本身成为散热片把热量导走。
安装位置决定测量代表意义。测 HVAC 风管温度时,二极管要贴在风管外壁的金属表面,用导热硅脂填充接触缝隙,外面再包一层保温棉,防止环境空气直接把探头温度“拉偏”。测换热器水温时,可以把二极管用卡箍固定在进出水管外壁,这时候千万别只靠胶带,长期运行后胶带老化,探头松脱会导致测量值瞬间偏离真实温度。我遇到过半夜掉线的案例,后来给所有远程探头都加了弹簧卡箍,问题再没出现过。如果目标是电机绕组,可以考虑把二极管做成细长探头塞进绕组缝隙,但要注意引线绝缘和弯曲半径,别让探头本身影响散热。
3.4 PCB 布局与热隔离经验
PCB 布局上有一个原则很重要:PJ85718DM 自身不要靠近大面积铜箔和功率器件的散热区。本地测温通道测的是“芯片周围的环境温度”,如果你把传感器放在 MOSFET 附近,它会优先感知功率器件带来的热量,反而测不到 PCB 的真实环境温度。我在项目板卡上,会把传感器放在 PCB 边缘、远离电感和大电流铜箔的地方,同时在传感器下方不做大面积铺铜,减少热传导通道。这看起来是很小的细节,但实测中本地温度可能相差 2~3°C,对保护阈值判断有明显影响。
远程测温二极管作为板外探头时,板上 D+ 和 D- 走线要尽量短、尽量等长,避免天线效应。如果远程探头要穿过金属壳体,出线孔要做密封处理,防止冷凝水顺着引线流进控制盒。HVAC 现场最容易出问题的往往不是硬件本身,而是安装和密封细节。我见过太多案例,设备出厂调试一切正常,运行半年后出现间歇性误报,打开一看就是线缆入口进了潮气,端子氧化导致接触电阻升高。
4. 固件与数据处理:温度读取、滤波、标定和故障检测的完整实现
4.1 I2C 初始化与传感器配置
固件部分先从 I2C 初始化说起。STM32F334R8 的 I2C 外设配置比较简单,用标准库或者 HAL 库都可以,关键在于把通信速率设置在 100kHz 标准模式或 400kHz 快速模式,PJ85718DM 都支持。我习惯用 100kHz,因为测温数据更新频率本来就不高,慢速通信带来的抗干扰能力更优。初始化代码大致如下:
I2C_HandleTypeDef hi2c1; hi2c1.Instance = I2C1; hi2c1.Init.ClockSpeed = 100000; hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.OwnAddress1 = 0; if (HAL_I2C_Init(&hi2c1) != HAL_OK) { Error_Handler(); }配置完成后,向 PJ85718DM 写配置寄存器。一般需要设置转换分辨率为 12 位,开启远程通道连续转换,报警输出用比较器模式并设置一个合理的上限初始值。参考代码如下:
uint8_t config = 0x60; // 假设 12 位分辨率、连续转换,具体位定义见数据手册 uint8_t reg_addr = 0x01; // 假设 0x01 为配置寄存器 HAL_I2C_Mem_Write(&hi2c1, SENSOR_ADDR, reg_addr, I2C_MEMSIZE_1BYTE, &config, 1, 100);这里要提醒一句:不同厂家的寄存器位定义不一样,拿到芯片后第一件事不是直接抄代码,而是对着数据手册核对寄存器地址和位定义。我在早期做过一个项目,因为把“连续转换”和“单次转换”的位定义搞反,固件怎么跑都是读到一个固定值,折腾了好几天才发现。寄存器定义这种事,靠记忆不如靠手册,每次换芯片批次都重新核对一遍最稳妥。
4.2 原始值读取、温度转换与滤波
配置好传感器后,主循环里就可以周期性地读取本地和远程温度寄存器。温度寄存器一般是 16 位,高字节放整数部分,低字节放小数部分。以 0.0625°C 分辨率为例,温度值的换算公式为:
int16_t raw = (int16_t)((uint16_t)hi << 8 | lo); float temperature = raw * 0.0625f;由于芯片输出已经是数字量,MCU 内部不需要再做查表计算。有时为了让系统读数更平滑,用户往往会再加一级一阶低通滤波。我在实际项目里用的滤波逻辑是:
static float local_filtered = 0.0f; const float alpha = 0.2f; local_filtered = local_filtered + alpha * (temperature - local_filtered);这个滤波器看似简单,但有几个细节必须想清楚。alpha 取太大,滤波基本没有效果;取太小,温度真实变化会被严重延迟。HVAC 应用一般要求温度分辨率 0.1°C,响应时间几秒到几十秒都无所谓,alpha 取 0.05 到 0.2 之间都很合适。如果是板级过温保护,反而不能过度滤波,因为保护逻辑需要快速响应,我通常在快速保护通道里跳过滤波,直接使用原始值判断,而在上报给上位机的数据里才用滤波值。两种数据并存,说白了就是“保命要快,显示要稳”。
4.3 远程通道的补偿计算
远程通道读到的原始值是多少,其实并不直接等于真实温度。因为外接二极管与传感器芯片可能相隔数米,引线上既有串联电阻,也有杂质电容;不同二极管本身的压降特性也有差异。PJ85718DM 内部会做基本补偿,但真正做过现场设备的人都明白,如果软件不做额外处理,测出的数据在长引线场景下照样可能偏差 1°C 以上。
我在代码里增加了串联电阻影响修正的经验逻辑。远程寄存器里有个状态字可以反映串联电阻的估算档位,如果芯片报告“串联电阻较高”,我会根据引线长度把温度值额外减去一个很小的修正量,并记录在日志里。这个修正量不是随便给的,而是我在实验室用拉长的线缆标定得到的经验曲线,大致是“每增加 1Ω 串联电阻,高温段偏差增加约 0.2~0.4°C”。你可以用一段已知线缆做同样的标定,方法很简单:先把远程二极管短距离接入,记录读数和温度计实测值,再串入若干欧姆的电阻,看数字跳了多少,把差值做成表存进 Flash。这样在现场就算不知道具体线长,也能根据内部估算值套用修正表,误差能进一步压缩。
另外,远程通道使用压降差原理而非单点电压,所以理论上对绝对电压不敏感。实际中如果远端二极管离热源太近,自己的结温发生快速变化,采样瞬间的噪声会被放大。我在软件采样循环里加了“连续采样 N 次取中位数”的保护策略,一般 N 取 5,既不会明显拖慢响应,又能把瞬态尖峰滤掉。中位数滤波比均值滤波好在一点:它不会让一个异常大值把后面几个采样周期都“拖带”掉,保证读数始终跟踪真实趋势。
4.4 故障检测与状态上报
温度系统最怕的其实不是“不准”,而是“明明断了还硬报一个温度”。比如远程二极管开路时,某些芯片可能会输出一个很接近上限或者负温度的值,如果上位机不做判断,控制器就可能误以为环境温度异常,直接关停设备。PJ85718DM 也提供了状态寄存器,能指示远程通道是否开路、短路。固件里应该在每个巡检周期同时读取状态寄存器,并设置一个持续计数,只有当连续 3 个周期都报故障时才真正进入故障状态,否则视为瞬态干扰。代码思路如下:
if (status & REMOTE_OPEN_FLAG) { open_count++; if (open_count >= 3) { remote_fault = true; // 停止使用远程温度参与控制 } } else { open_count = 0; }这个逻辑非常重要。一次两次的瞬态报错可能是继电器吸合时产生的尖峰,直接报故障会带来不必要的停机。连续 3 次确认后在下次巡检周期再切换报警状态,既不耽误故障响应,又能过滤偶发干扰。故障状态除了在本地 LED 上指示,还应该通过通信接口上报给上位机,并保留一个“故障期间最后有效温度”字段。上位机拿到这个字段后,可以在监控画面上显示传感器故障前的参考值,避免控制逻辑因为缺失数据而进入异常分支。
5. 实测结果:误差数据、干扰现象和长期稳定性
5.1 本地与远程同步测温的实测场景
为了验证这套方案,我在实验室搭了一个模拟 HVAC 环境的测试台。本地传感器放在金属控制盒内的控制板上,远程二极管用弹簧卡箍贴在一段风管外壁,风管内用加热器制造温度变化。启动前,环境温度 25.0°C,本地读数 25.1°C,远程读数 25.3°C,两只探头温差不到 0.3°C,这已经接近传感器自身的绝对精度。然后开启风管加热器,让风管内温度从 25°C 阶梯式升到约 55°C。远程读数在几分钟内稳定到 55.2°C,而本地读数最终只漂到 26.8°C,因为控制盒里的热量主要来自 MCU 自身功耗,和风管内的热空气并没有直接导热路径。
这个结果非常有代表性:两路温度同时采集,分别反映不同位置的热状态。上位机屏幕上同时显示“送风温度 55.2°C”和“控制板温度 26.8°C”,操作员不会再把这两个值混为一谈。如果系统只有一个传感器,要么放在风管表面导致控制盒自热监控失效,要么放在控制板导致 HVAC 控制逻辑被 MCU 发热误导。双通道设计的意义在这里体现得很充分。
5.2 电源纹波、继电器吸合和电机启停的干扰观察
干扰测试最能暴露方案的真实水平。我试着在测试控制盒旁边用一台小功率电机反复启停,同时用示波器观察 3.3V 电源线,发现纹波峰值从正常情况的 40mV 涨到接近 200mV。这时候远程温度读数偶尔会出现 0.5°C~1°C 的毛刺,持续一两个采样周期后自动恢复正常。原因不是传感器原理不行,而是电源纹波通过 I2C 信号地回路耦合进数字接口,导致某一次寄存器的读取结果被污染。
处理办法就是前面第 3 节里说的,把传感器电源独立出来,I2C 线上增加滤波,远程引线远离动力线。改造后再跑同样的启停测试,毛刺基本消失。这里我想强调的是,数字传感器不是“数字了就抗干扰”,接口层面的地回路和布线仍然决定了系统的真实抗干扰能力。很多人在实验室用稳压电源测试一切正常,一到现场就频繁误报,多数问题都出在“地”上。电流走过的路径全是电阻和电感,地平面处理不干净,数字接口照样读错数据。
5.3 校准方法与长期漂移记录
投入运行前我通常会做一次简单的两点标定。把远程探头分别放到 0°C 冰水混合物和 90°C 热水里,记录芯片输出值和标准温度计读数之间的偏差,然后算出偏移量和斜率修正系数。虽然 PJ85718DM 出厂精度已经够用,但为了 HVAC 系统里“送风、回风温差”这种对差值要求比较高的场景,我还是会把修正系数存到 STM32 内部 Flash,测温时做线性修正。这个操作成本极低,却能避免批次和安装造成的固定偏差。
长期稳定性方面,我持续运行了 120 小时,每小时记录一次数据。前 24 小时读数有细微的下降,幅度不到 0.2°C,属于传感器通电后的自热收敛,之后数据非常平稳。第 5 天由于昼夜环境温度变化,本地温度读数的波动基本跟随控制盒附近室温波动,验证了长期漂移并不明显。这里的小结论是:不要在设备刚上电时就做温度报警阈值判断,最好让系统稳定运行 10 到 15 分钟后再把阈值检测投入工作,或者在程序里做一个“上电预热计时器”。对 HVAC 这种连续运行的设备,预热时间不会影响实际使用,但能显著减少冷启动阶段的误报警。
6. 从监测到控制:HVAC 联动的落地细节与嵌入式集成注意事项
6.1 本地与远程温度参与恒温控制的决策逻辑
能测到温度只是第一步,真正值钱的是用温度数据把控制器驱动起来。在这套方案里,我把远程温度当作“被控环境温度”,本地温度当作“设备健康温度”,分别接入不同的控制环路。空调制冷场景下,远程温度直接喂给 PID 控制器,输出驱动风机或压缩机的 PWM 或模拟量;本地温度则用于过温保护,一旦控制板自身温度超过设定值,无论远程温度多少,强制降频甚至停机。
伪代码如下:
// 双通道温度控制决策示例 float remote_temp = read_remote_temperature(); float local_temp = read_local_temperature(); if (local_temp > LOCAL_OVER_TEMP_LIMIT) { set_fan_speed(0); raise_over_temp_alarm(); } else { float error = SETPOINT - remote_temp; float pid_out = pid_update(error); set_fan_speed(limit_to_range(pid_out, 0, 100)); }这个结构把所有逻辑放在一个循环里,清晰且容易调参。另一个关键点是要设置温度变化率检测。如果远程温度突然以超过 2°C/秒的速度跳变,通常是探头脱落或接线不良,此时不应急剧改变风机速度,而应进入“传感器异常待确认”状态,等待连续再采样,若恢复正常则解除异常。这个处理在真实 HVAC 现场能避免很多次半夜误报警。
6.2 通过 RS485/Modbus 把温度上报到中央监控
HVAC 项目通常有上位机或楼宇监控系统,多地温度需要汇聚显示。我在 STM32 固件里把本地温度和远程温度按 0.1°C 为一个单位缩放成 16 位整数,映射到 Modbus 寄存器,用 RS485 接口以 9600 波特率周期上报。这样中央监控端不用管底层用了什么传感器,直接读寄存器即可。Modbus 寄存器映射表我建议这样设计:
| 寄存器地址 | 内容 | 单位 | 数据类型 |
|---|---|---|---|
| 30001 | 本地温度 | 0.1°C | uint16 |
| 30002 | 远程温度 | 0.1°C | uint16 |
| 30003 | 远程通道故障状态 | 0正常/1开路/2短路 | uint16 |
| 30004 | 上电累计运行时间 | 分钟 | uint16 |
这里需要特别注意缩放比例的选择。0.1°C 分辨率对 HVAC 足够,而且便于上位机直接除 10 显示;如果采用 0.01°C 分辨率,16 位整数只能表示到约 655°C 范围,看似够用,但传输过程中的字节序和取整误差更容易暴露出来。从我的实际经验看,0.1°C 是稳定性和信息量的最优折中。通信协议写好后,用一个简单的 Modbus 调试工具就能验证读写,不需要等上位机开发完成。
6.3 现场安装和长期维护的几个建议
最后整理几条现场经验,都是我踩过坑后总结出来的。第一,远程二极管的引线不能直接拧在端子排上,最好压接冷压端子并加注硅胶密封,因为 HVAC 控制盒里经常存在凝露,裸露的接头会在两年后氧化接触不良。第二,传感器和 MCU 之间的 I2C 线尽量短,最好控制在 10 厘米以内,长距离传输 I2C 需要增加缓冲器,不要为了“省事”直接把线拉出控制盒。第三,给设备加一个“温度传感器在线检测”指示灯,把状态寄存器的结果映射到面板 LED 上,这样现场维护人员不用打开机箱就能看出远程探头是否开路,省掉很多沟通成本。
另外,如果你要在同一片板上放多个 PJ85718DM 传感器,I2C 地址冲突的问题要提前规划。部分芯片支持地址引脚配置多个地址,否则只能分时供电或者用 I2C 开关切换。我在某个项目里用了三颗芯片,分别测冷却水进、出水和环境温度,就是靠地址引脚组合解决冲突的,接线方式和寄存器读取逻辑相差不大,固件里用子地址做了区分。
最后再说一句个人体会。从最初用 NTC 单点测温,到后来换成 PJ85718DM 加 STM32F334R8 的双通道方案,我最大的感受是:温度采集看着是个小功能,真正做扎实要处理的问题其实不少,传感器自热、引线误差、地回路干扰、数据滤波、故障判断、通信映射,每一个环节都可能在未来某天的现场故障里现身。这套方案最大的价值不是精度有多高,而是把本地和远程两条链路从硬件层面分开,又在软件层统一管理,让嵌入式板级保护和 HVAC 环境控制各取所需,互不干扰。如果你正好在做一个多点位测温的产品或实验,建议先按照我上面的接线和固件框架跑通一版,再根据自己的现场条件调整滤波参数和故障逻辑。跑通之后你会发现,温度系统最难的往往不是芯片选型,而是怎么把一个模拟问题在工程里以数字方式稳妥地解决。