做嵌入式测控这些年我对“温度采集”这类需求已经形成条件反射先别急着选型而是把现场环境彻底跑一遍。很多项目在原理图上看着挺简单不过是传感器加 MCU真正决定成败的往往是传感器装哪儿、线缆怎么走、远程节点怎么供电、现场有没有强干扰源。最近用 PJ85718DM 和 PIC18F86J10 做了一套同时兼顾本地与远程测温的模块用在嵌入式和 HVAC 应用里中间踩了不少坑也总结出一些可以复用的经验。这篇就把完整的设计思路、硬件布局、固件实现和实测过程记录下来。先说清楚这里“本地温度”和“远程温度”指什么。本地温度是设备内部控制板上、机箱内部的环境温度远程温度则来自分布在风管、回风口、水管表面或者车间现场的远端测温点。HVAC 系统里这两种温度必须同时看只测控制器附近的环境温度根本反映不出整个空气处理单元的工况。PJ85718DM 负责把温度点变成数字信号PIC18F86J10 作为主控负责总线调度、数据滤波、故障判定和对外通信。这套组合的好处是传感器采样和主控逻辑分离温度点的数量和部署位置可以根据项目灵活调整不局限于一块板子。1. 这个项目要解决的远不只是“读个温度”1.1 嵌入式温控和 HVAC 工况的差异普通嵌入式设备的温度监测思路相对简单板子上放一颗传感器主控定期读一次温度高了降频或者报警。但 HVAC 场景完全不同测温点分散在整个系统里有的在室内机组内部有的在风管深处有的在室外冷凝器旁边。这些位置的工作环境差异很大线缆长度从几十厘米到几十米都有可能而且现场经常有变频器、接触器、电磁阀这些强干扰源。更麻烦的是温度变化特性不同。板级测温面对的是热容很小的对象温度变化快但变化幅度有限HVAC 里的风管和水管温度变化虽然慢却可能跨越很大的范围而且对采样稳定性的要求更高。一个典型的场景是组合式空调机组控制器需要知道回风温度、送风温度、盘管进出口水温还要知道控制箱内部温度。前几个是典型的远程温度最后一个是本地温度。如果只用一颗传感器、一种采样策略根本覆盖不了这种多点、多距离、多变化速率的需求。1.2 为什么选“数字传感器 通用 MCU”而不是一体化方案市面上也有一些集成多通道测温功能的专用控制芯片可以直接接热电阻或者热电偶。但这类方案有几个问题通道数固定扩展不灵活对线缆长度和传感器类型的适配比较死板而且一旦选型定死后续想增加测温点就要重新改硬件。所以这套项目采用了数字温度传感器加上通用 MCU 的组合。PJ85718DM 内置测温前端和数字接口把模拟信号处理在传感器内部完成主控只需要通过数字总线读取结果。PIC18F86J10 则负责更上层的逻辑轮询多个测温点、做滤波和跳变抑制、根据温度状态输出控制信号、维护与上位机的通信协议。传感器的更换和增加只影响从机地址配置不影响主控的整体架构后期维护成本低很多。1.3 PJ85718DM 和 PIC18F86J10 的分工逻辑从系统层面看这两颗芯片的分工非常明确。PJ85718DM 是温度感知层负责把物理温度变成数字量PIC18F86J10 是决策执行层负责读取数据、判断状态、控制执行机构。前者精度和环境适应性直接决定整套系统的测量上限后者的实时性和稳定性决定系统的响应质量。我把两者的关系类比成“现场巡检员”和“值班调度员”。PJ85718DM 是散布在各个角落的巡检员把看到的温度数字上报PIC18F86J10 是调度员不关心巡检员内部怎么测量只关心上报的数据可不可信、变化是否合理、需不需要做出动作。这种分层让故障定位变得非常直接温度不准先查传感器端通信异常再查总线和主控端不会出现两边搅在一起无从下手的情况。2. 硬件布局从传感器到主控的通道设计2.1 本地测温点PJ85718DM 与 PIC18F86J10 的连接本地温度传感器放在主控板上距离 MCU 一般不超过十厘米这是最简单的部署场景。PJ85718DM 使用数字接口与 PIC18F86J10 连接按照数据手册的推荐电路传感器供电脚附近要放一个 0.1 微法的陶瓷电容电源入口再放一个 10 微法的电解电容做低频去耦。我习惯在传感器附近再留一个 0 欧电阻位实测如果发现地电位有干扰可以根据需要改成磁珠。数字总线的上拉电阻是第一个容易出错的地方。当时参考设计用的是 10 千欧上拉在样板测试时发现波形上升沿偏慢把速率从 400k 降到 100k 才能稳定通信。后来换成 4.7 千欧上拉波形明显改善。这里的关键逻辑是上拉电阻越小上升沿越陡但功耗也越大。短距离板内连接一般 4.7 千欧比较合适如果传感器通过接插件和排线引出距离超过二十厘米建议改成 2.2 千欧。2.2 远程测温点长线连接的两种主流做法远程温度点的部署方式需要根据线缆距离来定。距离在三米以内的可以直接用数字总线连到主控传感器作为从机挂在总线上。这个方案最简单成本最低每个从机通过地址引脚编码区分。但数字总线直接拉长线有个隐患总线电容增大后信号边沿变缓抗干扰能力下降。距离超过三米我倾向采用“远端采样 长线传输”的分级架构。远端一个小节点板板上放 PJ85718DM 和一颗负责总线通信的接口芯片节点板先把温度读出来再通过差分方式的现场总线把数据发回主控。主控侧通过另一颗接口芯片转回普通逻辑电平给 PIC18F86J10 处理。这样测温模拟部分完全被隔离在远端长线上传输的是抗干扰能力更强的差分信号不会出现模拟信号在长线上衰减的问题。部署方式适用距离抗干扰能力成本工程难度数字总线直接挂载3 米以内一般依赖线缆质量和布线低低远端采样 差分总线传输3 米至数百米强适合工业现场中高中无线传感器节点灵活受频段和环境遮挡影响较高中高HVAC 现场很多远程测温点装在风管保温层里面或者水管表面布线环境很复杂我最终采用的是第二种方案。一组设备里有两个远端节点分别用屏蔽双绞线连到主控板PIC18F86J10 轮流读取两个节点上报的数据互不干扰。2.3 供地和隔离远程节点最容易忽略的部分长距离连接时地电位差是个很容易被忽略又非常致命的问题。两个设备供电来自不同回路时地线之间的电位差可能达到几伏轻则读数不准重则损坏接口。处理这个问题的标准做法是使用带隔离的收发器或者至少保证整个系统采用单点接地。我在现场遇到过类似情况远端节点一接上主控这边读数直接跳了接近两度板子上的其他通信也出现偶发错误。排查后发现是现场地线布局不规范远近两点地电位相差约 1.8 伏。后来在远端节点板上加入了隔离电源模块和隔离收发器问题才彻底消失。这里有一个标准原则只要远程传感器和主控不在同一个配电回路里就必须考虑隔离方案别抱着“应该没问题”的侥幸心理。3. 固件侧的核心实现读取、滤波与断线识别3.1 底层驱动的稳定读取逻辑固件方面PIC18F86J10 的底层驱动直接操作硬件模块。PJ85718DM 的读取流程分为三步配置工作模式、等待转换完成、读取温度寄存器。不同厂家的传感器在寄存器定义上略有差别我这里给出的是通用的读取时序框架具体寄存器偏移以 PJ85718DM 数据手册为准。/* 伪代码PJ85718DM 温度读取流程 */ uint16_t pj_read_temperature_reg(uint8_t reg_addr) { uint16_t value 0; /* 发送寄存器地址 */ i2c_start(); i2c_write_byte(PJ_DEV_ADDR 1 | 0); /* 写地址 */ i2c_write_byte(reg_addr); i2c_stop(); /* 重复起始切换为读模式 */ i2c_start(); i2c_write_byte(PJ_DEV_ADDR 1 | 1); /* 读地址 */ value i2c_read_byte(ACK); /* 高字节 */ value (value 8) | i2c_read_byte(NACK); i2c_stop(); return value; }读取时序本身不难真正容易出问题的是读回来的数据是否可信。主控每次读完原始值还需要做三个判断数值是否在合理范围内、数值跳变是否过大、连续多次读数是否一致。PJ85718DM 这类数字传感器通常内置了基本的温度转换逻辑但总线上的毛刺、供电波动、寄存器读串位都可能造成异常值。固件里必须把这些判断写进去而不是直接拿原始数据去当控制依据。3.2 数字滤波和跳变抑制策略HVAC 现场的温度变化通常没有传感器响应那么快但采集到的原始数据经常出现毛刺。特别是远程节点经过长线传输后偶发的噪声可能让一次读数偏差一到两度。直接用这个偏差值去控制风机或阀门会导致系统频繁启停。我采用的策略很简单远程温度每 5 秒采一次主控维持一个长度为 5 的滑动窗口每来一个新数据先做中值滤波再做滑动平均。中值滤波能干掉孤立毛刺滑动平均能进一步平滑温度曲线的抖动。本地温度变化相对快滑动窗口缩短到 3保证响应速度。#define TEMP_WINDOW_SIZE 5 float temp_filter(float new_value) { static float window[TEMP_WINDOW_SIZE]; static uint8_t index 0; window[index] new_value; index (index 1) % TEMP_WINDOW_SIZE; /* 1. 中值滤波排序后取中间值 */ float sorted[TEMP_WINDOW_SIZE]; memcpy(sorted, window, sizeof(sorted)); /* 简单插入排序窗口小所以排序开销可忽略 */ insertion_sort(sorted, TEMP_WINDOW_SIZE); float median sorted[TEMP_WINDOW_SIZE / 2]; /* 2. 对窗口内数据做滑动平均 */ float sum 0.0f; for (uint8_t i 0; i TEMP_WINDOW_SIZE; i) { sum window[i]; } /* 中值和平均值按 7:3 加权兼顾平滑与实时性 */ return median * 0.7f (sum / TEMP_WINDOW_SIZE) * 0.3f; }这里有个工程细节如果两次连续采样的温度差值超过设定的阈值比如 2 度我会先判定为疑似干扰直接丢弃本次采样等下一次采样结果。如果连续多次都出现超阈值跳变再判定为真实温度突变。这样可以防止把一次总线错误当成真实的温度变化。3.3 断线、短路和传感器故障的落地判断温度传感器在现场最常出的故障就是断线和短路。断线时传感器读不到数据总线可能出现无应答短路时读回来的温度常常是电源电压或者接近零度的异常值。固件里必须有明确的故障检测状态机。typedef struct { uint8_t sensor_enabled; uint8_t consecutive_error_count; uint8_t fault_status; float last_valid_temp; } temp_channel_t;我在每次读取之前设置一个超时定时器如果总线在指定时间内没有应答就认为该通道本次读取失败。连续读取失败次数累计到设定值后把该通道标记为断线故障控制逻辑切换到预设的安全温度值。这个安全值不是随便定的要根据系统特性来——比如判断盘管防冻时安全值要设得让系统倾向于开大阀门而不是关死避免冻裂水管。另外还要对传感器读值设定上下限。PJ85718DM 的测温范围按手册标称是 -40 到正 125 度HVAC 系统里一般不会有超出这个范围的正常工作场景。如果读到的值超出量程直接判为传感器损坏进入故障保护状态。这套逻辑在实验室里看着简单但真到了现场能挡住大量“温度莫名其妙跳到几百上千度”的诡异问题。4. 实测效果、校准过程和几处值得记录的坑4.1 校准流程和最终精度表现系统装好后我用一个恒温槽配合高精度参考温度计做了校准。校准时把远程探头和参考温度计同时放进恒温槽设定多个温度点记录每个点下 PJ85718DM 的读数偏差。校准结果分两种误差零点误差和斜率误差。如果传感器在所有温度点都偏一个固定值就是零点误差可以通过在固件里加一个偏移补偿掉。如果低温偏小、高温偏大偏线性变化就是斜率误差需要在固件里按比例修正。实测下来PJ85718DM 的主要偏差集中在零点偏移补偿后整体误差控制在正负 0.3 度以内。这个精度在 HVAC 温控里完全够用。恒温槽设定温度补偿前读数补偿后读数参考温度计补偿后偏差0.0 度-0.6 度0.1 度0.0 度0.1 度25.0 度24.4 度25.2 度25.0 度0.2 度50.0 度49.5 度50.1 度50.0 度0.1 度80.0 度79.3 度79.8 度80.0 度-0.2 度需要注意的是校准补偿参数应该存放在非易失存储区而且最好在出厂测试环节写进去。每台设备的传感器个体偏差可能不同如果所有设备都烧录同一个固定偏移量校准就失去意义了。4.2 现场干扰导致的远程读数漂移上一个项目里遇到过一个很典型的干扰问题。远程探头固定在风管内部信号线从风管旁走过与一段三相动力线并行了几十厘米。设备运行后PIC18F86J10 读到的远程温度明显偏高而且数值在上下抖动幅度一度达到 1.5 度。最开始还以为是传感器坏了换了个新的问题依旧。后来用示波器挂在总线上观察发现数据线在动力线启动瞬间出现明显的噪声脉冲干扰长度正好覆盖温度数据的传输过程。处理方式分三步首先把信号线改成屏蔽双绞线屏蔽层单端接地其次调整布线路径让信号线与动力线保持至少二十厘米间距最后在接口上加了一级共模滤波。改造完再测读数恢复稳定。这里要特别强调屏蔽层接地方式。屏蔽层应该只在主控侧单端接地不能在远端节点也接地否则屏蔽层反而会形成一个地环路引入更大干扰。这个坑我踩过第一次做系统时两端都接地了结果干扰从原来的一两度变成四五度。4.3 长时间运行的稳定性验证验证系统的长期稳定性时我让设备连续运行了七天每十分钟记录一次数据。重点看两个指标读数是否有缓慢漂移远程与本地温度关系是否合理。测试期间发现一个有意思的问题本地传感器和远程传感器在夜间都出现了一个缓慢的升温趋势。排查后确认不是传感器漂移是现场设备控制箱自身温度升高了箱内安装了多台发热设备夜间没有空调冷却环境温度整体上涨。这个案例从侧面说明本地测温点虽然离主控近但它测的是“控制箱温度”而不是“环境温度”在实际工程里要有意识地选择参考物理量不能笼统地说测得准不准。长时间运行的另一个收获是故障恢复逻辑的验证。测试中人为拔掉一个远程传感器的接线固件在五次采样后正确判定断线故障控制逻辑切到安全值重新插上后传感器在恢复通信的下一轮采样即恢复正常。这组测试说明重试机制和故障恢复机制配合得比较合理不会因为一次瞬时故障就永久锁死通道。5. 工程化落地时的一些模块划分和现场经验5.1 固件模块怎么切才方便后续维护整套固件我划分成了传感器驱动、温度管理、故障处理、通信协议、控制输出五个模块。传感器驱动最底层只负责收发字节和寄存器读写温度管理负责轮询通道、滤波、换算、输出经过处理的温度值故障处理独立成一个状态机专门跟踪每个通道的健康状态。这样切有一个明显好处现场如果要换一种传感器只需要替换传感器驱动温度管理和故障处理逻辑完全不动如果要加一个测温点只需要在温度管理模块里加一条通道配置不用改上层控制逻辑。我在第一个版本里把故障检测散落在各个功能代码里结果出问题时到处埋判断逻辑改起来非常痛苦。后来统一收敛到故障处理模块调试效率立刻上来了。5.2 现场调试的几条实操建议调试远程温度节点时我习惯先短接主控侧的接口做自环测试确认主控通信波形正常再接远端节点。这个步骤能快速区分问题出在主控板还是出在远端节点。如果短接后通信正常接上远端就出错优先怀疑接线顺序、供电和地电位如果短接就不正常问题在主控侧固件或硬件。另一条建议是把每个传感器的原始寄存器值和经过滤波后的工程温度值都通过调试口同时输出。只输出最终温度值是看不出问题的必须能对比原始数据和滤波数据才能判断到底是传感器本身异常、总线传输干扰还是滤波策略不合适。我后来加了这个输出之后远程读数的很多疑难杂症才算真正定位到根因。5.3 如果还要扩展更多测温点做完这套系统后我的一个突出体会是硬件通道的数量不是瓶颈真正决定扩展能力的是固件架构。PIC18F86J10 的主频和资源对于几十个测温点、每秒轮询一次的场景绰绰有余但前提是驱动层做好抽象不让传感器细节渗透到上层业务逻辑里。如果将来要接更多远程节点我会在现有架构上增加一个简单的查询式协议主控周期性地向每个远端节点发送地址帧节点返回自身的温度数据。这样每个节点的固件几乎不需要修改只需要配一个新的地址系统整体照样稳定运行。如果想再进一步还可以把每个节点的温度数据通过主控汇总后统一上报上层系统形成一张全局温度分布表这对 HVAC 系统的能效分析也很有价值。最后再说一个容易被忽视的点所有远程测温节点的发热和功耗也要关注。传感器自身功耗虽然很低但如果节点里有隔离电源、驱动芯片和通信接口长时间放在封闭风管里也要注意温升对测温结果的影响。我在第一版节点设计里把通信接口芯片直接放在传感器旁边结果节点工作时自身发热把传感器读到的温度抬高了接近 0.8 度。后来把传感器挪到离发热器件稍远的位置并在结构上避开热气流路径这个问题才解决。做这种本地与远程温度同时监测的项目我的核心体会是传感器选型只是起点真正的功夫花在感知通路能不能在复杂现场稳定工作。隔离设计、滤波策略、故障处理、校准补偿每一项单独拿出来看都很普通但合在一起直接决定了现场设备是能用还是好用。如果你也在类似的嵌入式和 HVAC 项目里做多点温度监测希望这些经验和踩坑记录能帮你少走一段弯路。