1. 从一颗温度传感器说起为什么HVAC场景需要本地与远程双路监测做过暖通空调控制板的人大概都有体会温度采集这件事看起来简单真要做到稳定可靠坑比想象中多得多。尤其是商用中央空调、冷库机组、恒温恒湿箱这类设备控制板往往装在一个温度相对稳定的电控柜里但真正需要被监测的温度点却分布在风道、水管、回风口甚至几十米外的远端房间。这就带来一个很现实的问题本地温度和远程温度必须同时采集而且两路数据的处理策略完全不同。本地温度通常用来做板级补偿和过温保护比如功率器件附近的温度一旦超过阈值系统要立刻降载或者启动风扇远程温度则更多用于闭环控制比如根据回风温度调节压缩机频率或者水阀开度。这两路信号如果混在一起处理轻则控制精度下降重则因为本地温升误判导致机组频繁启停。我这次做的方案核心就是用一颗PJ85718DM作为远程温度采集前端配合PIC18F86J15这颗8位MCU做本地温度监测和整体控制逻辑。选这个组合不是拍脑袋决定的背后有几层考虑PJ85718DM本身是带数字接口的远程温度传感器适合把探头拉到远处PIC18F86J15自带多通道ADC和比较丰富的片上外设本地温度用它的内部通道或者外接热敏电阻都能搞定而且这颗MCU在工业控制领域用了很多年供货和工具链都比较成熟。整篇文章我会围绕这个组合把硬件连接、通信协议、采样策略、校准方法、抗干扰处理这些实际动手环节讲透。不管你是刚接触嵌入式温度采集的新手还是做过类似项目想找参考的老手应该都能从里面找到能直接用的东西。下面先从这两颗器件的分工和选型逻辑讲起。2. PJ85718DM与PIC18F86J15的分工逻辑与选型依据2.1 为什么远程温度不直接用MCU的ADC拉长线很多人第一反应是既然PIC18F86J15有ADC那我直接把热敏电阻或者热电偶用长线拉到MCU引脚上不就行了理论上可以实际用起来问题很大。模拟信号走长线第一个遇到的就是压降和噪声耦合。热敏电阻分压后的电压本身幅度就不大线缆电阻会直接叠加到分压网络里导致读数偏移再加上工业现场变频器、接触器动作产生的共模干扰ADC读出来的值可能跳得没法看。PJ85718DM这类远程温度传感器的思路是把模拟前端直接放到探头附近在本地完成ADC转换然后通过数字总线把温度值传回来。数字信号抗干扰能力比模拟信号强得多而且传感器内部通常已经做了线性化和校准MCU拿到的就是直接可用的温度数据。这个思路上的转变很关键把模拟信号的长度缩短到最短把数字信号的长度拉长这是远程温度采集的基本原则。2.2 PIC18F86J15在本地温度监测中的角色定位PIC18F86J15在这套方案里承担的是“本地感知全局调度”的双重角色。本地温度监测方面它可以用内部温度指示模块做粗略的芯片温度读取也可以用外部ADC通道接一颗贴片热敏电阻或者数字温度芯片来监测板级关键点温度。我实际用的是外部NTC热敏电阻加分压电路接ADC通道原因是内部温度指示模块的精度和一致性在批量生产时不太够看而NTC成本低、响应快配合MCU的ADC做查表或者Steinhart-Hart公式换算精度能做到±0.5℃以内。全局调度方面PIC18F86J15要负责轮询PJ85718DM的远程温度、执行本地温度采样、跑控制算法、驱动继电器或者PWM输出。这颗MCU的指令周期在16MHz晶振下是250ns对于温度这种慢变量控制来说绰绰有余。它的ADC是10位精度13个通道用来做本地温度采集完全够用。更重要的是它的工作温度范围覆盖工业级-40℃到85℃的版本在HVAC场景里很常见。2.3 两颗器件的接口匹配与电平兼容PJ85718DM和PIC18F86J15之间的通信接口需要重点确认。PJ85718DM通常提供I2C或者SMBus兼容的数字接口工作电压一般在3.3V或者5V可选。PIC18F86J15的I/O口在5V供电时是5V逻辑如果传感器是3.3V逻辑直接连接会有电平不匹配的问题。我实际处理时用了电平转换电路或者更简单的办法是把PIC18F86J15的I2C引脚配置成开漏输出加上拉电阻到3.3V这样两边都能正常工作。这里有个细节容易被忽略I2C总线的上拉电阻值要根据总线电容和通信速率来算。远程温度传感器如果通过排线连接线缆电容可能达到100pF以上上拉电阻太大波形上升沿会变缓太小则增加功耗。我一般用4.7kΩ作为起点实测波形如果上升沿超过1μs就适当减小到2.2kΩ。这个计算过程是上升时间t≈0.8×R×C假设C150pFR4.7kΩt≈0.56μs在100kHz速率下是安全的。3. 硬件连接与信号链设计中的关键细节3.1 远程温度探头的选型与布线规范PJ85718DM本身是芯片真正接触被测环境的是外接的温度探头。HVAC场景里常用的探头有NTC热敏电阻、铂电阻PT100/PT1000、以及集成数字输出的温度芯片。PJ85718DM如果支持模拟输入那探头选型就决定了整个远程通道的精度和响应速度。我这次用的是10kΩ B值3950的NTC原因是成本低、互换性好而且HVAC温度范围通常在-20℃到80℃之间NTC在这个区间的灵敏度足够。布线方面探头引线我用了屏蔽双绞线屏蔽层单端接地。双绞线的作用是让两根信号线耦合到的干扰尽量一致变成共模信号而传感器前端的差分输入或者滤波电路可以把它抑制掉。屏蔽层单端接地是为了避免形成地环路如果两端都接地地电位差会在屏蔽层上产生电流反而引入干扰。线缆长度我实测过20米以内再长的话分布电容和线阻的影响就需要重新评估了。3.2 本地温度采样电路的设计取舍本地温度采样我用了NTC加分压电阻的方案。具体电路是3.3V参考电压经过一个10kΩ的精密电阻再串联NTC到地NTC两端的电压接到PIC18F86J15的ADC通道。这个分压点的电压随温度变化MCU通过ADC读取后换算成温度。选10kΩ串联电阻的原因是它在25℃时和NTC阻值相等分压点电压在参考电压的一半附近ADC的利用率最高灵敏度也在这个点附近比较均衡。这里有个经验分压电阻要用精度1%以内的金属膜电阻温漂要小。普通碳膜电阻的温漂可能达到几百ppm/℃在温度变化大的环境里会直接引入测量误差。我吃过这个亏早期用了一颗便宜的碳膜电阻结果在高温老化测试时读数漂了将近2℃。后来换成25ppm/℃的精密电阻问题就解决了。3.3 电源与地去耦对温度测量的影响温度测量对电源噪声其实挺敏感的尤其是用ADC采样的时候。PIC18F86J15的ADC参考电压如果直接用VDD那VDD上的纹波会直接调制到ADC读数上。我一般会在VDD和VSS之间靠近MCU的位置放一个10μF的钽电容并联一个100nF的陶瓷电容钽电容负责低频储能陶瓷电容负责高频去耦。ADC参考引脚如果单独引出还要再加一个1μF加100nF的组合。PJ85718DM的供电也要注意。如果它和MCU共用一路电源那MCU数字开关噪声会通过电源耦合到传感器。我的做法是在传感器的电源引脚前串一个磁珠再并一个10μF电容形成一个简单的LC滤波。磁珠选100MHz时阻抗600Ω左右的型号对数字噪声的抑制效果比较明显。实测下来加了这级滤波之后远程温度的读数跳动从±0.5℃降到了±0.1℃以内。4. 通信协议与采样时序的实操配置4.1 I2C总线初始化与传感器寄存器配置PIC18F86J15的I2C模块配置需要设置几个关键寄存器。首先是SSPCON1要设置成I2C主模式时钟极性根据传感器要求来定。PJ85718DM一般支持标准模式100kHz和快速模式400kHz我建议先用100kHz跑通稳定之后再尝试提速。SSPADD寄存器决定时钟频率计算公式是SSPADD (Fosc / (4 × Fscl)) - 1。假设晶振16MHz目标100kHz那SSPADD (16M / 400k) - 1 39。传感器内部通常有配置寄存器、温度数据寄存器和阈值寄存器。上电后第一步是写配置寄存器设置分辨率、采样速率、报警阈值等。比如把分辨率设成12位那转换时间会相应变长但精度更高。我一般把远程温度传感器的分辨率设成12位本地ADC用10位因为远程温度是控制的主反馈量精度要求更高。4.2 本地与远程温度的轮询策略轮询策略直接影响到控制的实时性和CPU占用率。我的做法是用一个定时器中断作为时基比如每100ms触发一次采样任务。任务里先启动本地ADC转换等转换完成中断后读取结果然后再发起I2C读取远程温度。这样本地和远程的采样在时间上错开避免ADC转换和I2C通信互相干扰。为什么不把两个采样放在同一个中断里连续做因为I2C通信是阻塞式的如果传感器没有响应MCU会一直等在那里影响其他任务的执行。我用了状态机的方式中断里只置标志位主循环里根据标志位分步执行ADC启动、ADC读取、I2C启动、I2C读取。这样即使某一颗传感器临时掉线也不会把整个系统卡死。4.3 温度数据的格式转换与单位统一PJ85718DM输出的温度数据格式需要确认常见的有两种一种是直接输出摄氏度比如0.0625℃/LSB另一种是输出原始ADC码需要自己换算。我用的这款是直接输出摄氏度12位模式下分辨率是0.0625℃。读取到的16位数据里高12位是温度值低4位是状态标志。处理的时候要先右移4位再乘以0.0625得到摄氏度。本地NTC的换算稍微麻烦一点。ADC读到的电压值要先换算成电阻值公式是Rntc Rseries × (Vadc / (Vref - Vadc))。得到电阻值之后再用Steinhart-Hart公式或者查表法换算成温度。Steinhart-Hart公式是1/T A B×ln(R) C×ln(R)³其中A、B、C是NTC厂家提供的系数。如果嫌浮点运算麻烦可以用查表加线性插值的方式把-20℃到80℃每5℃一个点做成表格中间用线性插值精度也能做到±0.2℃以内。5. 校准、滤波与抗干扰的实战处理5.1 本地温度通道的校准方法NTC的标称阻值和B值都有公差分压电阻也有公差所以每个板子的本地温度读数都会有偏差。批量生产时如果每块板都单独校准成本太高如果不校准一致性又没法保证。我的做法是在PCB上留一个校准焊盘产线测试时把板子放到一个已知温度的恒温槽里读取ADC值然后计算出一个偏移量存在EEPROM里。实际运行时MCU读取ADC后先减去这个偏移量再换算温度。这个偏移量校准法只能修正零点误差如果NTC的B值偏差大斜率误差是修不掉的。所以选NTC的时候要选B值公差小的型号比如±1%以内的。我对比过几家供应商的样品B值公差从±1%到±5%不等价格差不了多少但一致性差别很大。选型的时候一定要看数据手册里的B值公差参数不要只看阻值精度。5.2 远程温度的软件滤波策略远程温度经过长线传输即使有数字接口偶尔也会出现个别数据跳变。我用了两级滤波第一级是限幅滤波如果本次读数和上次读数的差值超过2℃就认为这次数据无效丢弃不用沿用上次的值第二级是滑动平均滤波用一个长度为8的环形缓冲区每次存入新数据后取平均值输出。这样既能抑制突发干扰又不会让响应变得太迟钝。限幅阈值设2℃是有讲究的。HVAC系统的温度变化率通常不会超过1℃/秒100ms采样周期内温度变化不会超过0.1℃。如果读数跳了2℃那基本可以确定是干扰而不是真实温度变化。滑动平均的长度也不能太长8个点对应800ms的延迟对于温度控制来说是可以接受的。如果控制要求更快可以缩短到4个点。5.3 工业现场常见干扰的排查与抑制工业现场最常见的干扰源是变频器、接触器和继电器。这些设备动作时会产生强烈的电磁干扰通过空间辐射或者电源线传导进入温度采集电路。我遇到过最典型的现象是压缩机启动的瞬间远程温度读数突然跳高5℃然后慢慢恢复。排查下来是I2C总线受到了干扰导致一次通信错误读到了错误的数据。解决方法是多管齐下。硬件上I2C总线加TVS管做浪涌保护线缆用屏蔽双绞线屏蔽层接机壳地。软件上每次I2C读取后做CRC校验或者PEC校验校验不过就重读连续三次失败就报传感器故障。另外在压缩机启动前主动暂停一次温度采样等启动完成后再恢复也能避开干扰最严重的时刻。这个策略在软件里加一个“干扰窗口”标志位就能实现。6. 从采样到控制温度数据如何驱动HVAC执行机构6.1 本地过温保护与远程闭环控制的优先级本地温度和远程温度在控制逻辑里的优先级是不同的。本地温度主要做保护一旦超过阈值不管远程温度是多少都要立即执行保护动作比如关闭输出、启动风扇。远程温度做闭环控制根据设定值和实际值的偏差调节执行机构。这两者的优先级关系要在代码里明确体现我一般把本地过温保护放在最高优先级的中断里确保响应时间在毫秒级。具体实现上本地温度采样后立即和阈值比较如果超过阈值就置一个保护标志位。主循环里检测到这个标志位后无条件关闭PWM输出和继电器。远程温度的PID控制则放在常规任务里即使PID计算有延迟也不会影响保护动作的实时性。这种分层设计在功能安全要求高的场合很重要。6.2 温度变化率在故障诊断中的妙用除了绝对温度值温度的变化率也能提供很多信息。比如远程温度在短时间内快速上升可能是制冷剂泄漏或者风道堵塞本地温度缓慢持续上升可能是散热风扇老化或者滤网积灰。我在代码里加了一个变化率计算模块每秒钟计算一次温度变化率超过设定阈值就触发相应的诊断报警。变化率的计算用差分法rate (T_now - T_1s_ago) / 1s。为了避免噪声导致误报变化率也要做滤波我用的是指数移动平均。这个功能在实际运维中很有用很多故障在温度绝对值还没超限的时候变化率就已经异常了提前报警可以避免设备损坏。6.3 执行机构驱动与温度控制的联动测试温度采集最终要落到控制执行上。我这次控制的执行机构包括一个继电器输出的压缩机接触器、一个PWM驱动的电子膨胀阀、以及一个风扇调速输出。联动测试的时候我用一个可调温的恒温槽模拟远程温度变化观察压缩机和膨胀阀的响应。测试重点是看控制死区、超调量和稳定时间这三个指标。实测下来PID参数用Kp2.0、Ki0.05、Kd0.1的时候系统在设定值变化10℃时超调量在1℃以内稳定时间大约3分钟。这个响应速度对于HVAC系统来说是比较合适的太快了会导致执行机构频繁动作太慢了又影响舒适性。参数不是固定的不同机组的热惯性不一样需要根据实际系统整定。7. 调试过程中踩过的坑与排查思路7.1 I2C通信失败从波形入手逐层定位调试初期遇到最多的问题就是I2C通信失败。现象是MCU发送起始条件后传感器没有应答。排查的时候我养成了一个习惯先用示波器看波形不要急着改代码。看波形主要看三点起始条件是否正常、时钟频率是否在传感器支持范围内、数据线在上拉电阻作用下能否正常拉高。有一次波形看起来都正常但就是没有应答。后来发现是传感器的地址搞错了。PJ85718DM的I2C地址有多个可选由地址引脚的电平决定。我硬件上把地址引脚悬空了以为默认是某个地址实际上悬空状态不确定导致地址随机。把地址引脚明确拉到GND或者VCC之后通信立刻正常。这个坑告诉我任何配置引脚都不要悬空一定要有明确电平。7.2 温度读数跳变地区分真实变化与干扰温度读数跳变是另一个高频问题。排查的时候首先要区分是真实温度变化还是干扰。方法很简单同时用一颗独立的温度计放在同一个位置对比读数。如果独立温度计稳定而采集系统跳变那就是干扰或者电路问题。我遇到过一种情况是读数周期性跳变周期和变频器载波频率一致那基本可以确定是传导干扰需要在电源和信号线上加滤波。还有一种跳变是电源纹波导致的。用示波器看ADC参考电压引脚如果纹波超过10mV那ADC读数就会不稳定。解决办法是在参考引脚加RC滤波电阻用10Ω电容用1μF截止频率大约16kHz对数字噪声有很好的抑制。这个RC滤波的电阻不能太大否则参考电压的建立时间会变长影响ADC的启动速度。7.3 长期运行后的漂移连接器与焊点的隐性故障设备运行几个月后出现温度读数缓慢漂移这种问题最难查。我遇到过一例本地温度读数每个月漂0.5℃左右查了电路和代码都没问题。后来用热成像仪看PCB发现NTC焊点附近温度比周围高2℃原因是焊点有微裂纹接触电阻变大电流流过时发热。重新补焊之后漂移问题消失。这个案例说明长期可靠性问题往往出在连接器和焊点这些机械结构上而不是芯片本身。预防措施包括选用镀金连接器、焊点做应力释放设计、关键模拟通道的焊点做X光检查。对于HVAC这种需要长期连续运行的设备这些细节比电路设计本身更重要。8. 这套方案还能怎么扩展温度采集做稳定之后我在这套基础上做了几个扩展效果不错。一个是把采集到的本地和远程温度通过UART上传到上位机用简单的文本协议每秒钟发一帧格式是“L:25.3,R:24.8\n”上位机用串口助手就能看方便现场调试。另一个是加了历史数据存储用MCU内部的EEPROM每10分钟存一次温度掉电不丢失事后可以分析温度趋势。如果要做产品化还可以考虑把PIC18F86J15换成带CAN控制器的型号把温度数据挂到CAN总线上这样多台机组之间可以共享温度信息实现更复杂的联动控制。不过那是另一个话题了先把单机的温度采集做扎实后面的扩展都是水到渠成的事。