做嵌入式温度采集的人,很多时候图省事直接拿现成的测温模块接开发板,能用是能用,但一到现场批量部署就露馅:探头线一拉长数据就飘、风管里温度波动大读数像心电图、上位机要数据还得每个节点单独调参。这次项目里我用一颗PJ85718DM数字温度传感器加PIC18F4550单片机,把本地和远程双路测温链路完整做了一遍,覆盖嵌入式板卡监控和HVAC风管、回风温度采集两个典型场景,中间踩了不少坑,也把驱动、滤波、通信和现场调试的细节都捋顺了。这篇就把整套设计思路、硬件连接、固件实现和常见故障排查过程完整记录一遍,给同样在选型或调测温方案的工程师做个参考。
先说清楚一个容易混淆的点:标题里的“本地与远程”,指的是PJ85718DM这颗传感器能同时测本地芯片温度和外接远端测温二极管、热敏电阻的通道温度,而不是说数据要传到千里之外。很多项目一开始把这个理解成WiFi远程监控,后面才发现走偏了。真正的远程数据上报是MCU侧再做RS485或USB转上位机,跟传感器的“远程通道”是两码事,设计时要分清楚。
1. 先把需求拆明白:这个系统到底在测什么
1.1 嵌入式场景的温度监测要解决什么问题
嵌入式设备里的温度监测,重点不是测环境温度,而是盯住发热源。电源模块的MOS管、CPU散热片、功率电感这些位置,工作温度能直观反映负载状态和散热是否正常。做过硬件可靠性的人都有体会,70度以下和85度以上的长期运行,器件失效率完全不是一个量级,风扇灰尘堵了之后机箱内温度能一天涨十几度。
这类场景对测温的实时性和稳定性要求很高。一是采样不能太慢,至少1秒左右刷新一次,否则温度过冲了你还在用上一秒的数据;二是数据要能做趋势判断,单个突变值不能直接触发报警,要结合连续几个周期的均值;三是传感器本身不能成为新的热源,所以探头尽量靠近被测物体但不要直接接触带电节点,PJ85718DM这种数字输出方案比NTC配ADC的模拟方案省去了不少校准功夫。
嵌入式这块我的切身体会是:宁可温度测出来有1度以内的偏差,也不接受数据忽高忽低。现场排障时,一个来回跳动的温度值比一个偏高但稳定的值难处理得多,因为它没法判断是真实过温还是采样链路有问题。
1.2 HVAC场景的测温难点与特殊需求
HVAC场景跟嵌入式完全是两个世界。风管里风速大、换热快,温度波动比设备内部剧烈得多;回风口的温度受新风和房间负荷共同影响,变化周期长但幅度大;冷热通道之间的温差可能超过20度,传感器探头本身还会被冷凝水影响。
这类应用里最大的痛点是探头距离主机远。风管可能在高空吊顶里,控制器在设备间,走线距离从几米到几十米都很正常。普通NTC测温电路在这种长线下容易引入噪声和压降误差,而PJ85718DM把模拟前端做在传感器内部,远端通道只要接对极性、线缆带屏蔽,抗干扰能力比运放电路强很多。
HVAC项目还特别看重读数的稳定性和重复性,因为温控逻辑通常靠绝对值判断,比如回风温度超过设定值1.5度就开机、低于设定值1度就停机。如果读数的随机波动就有正负0.5度,控制逻辑就会频繁启停压缩机和风机,设备寿命和能耗都受影响。实际测试中我发现PJ85718DM的多周期累加和均值滤波机制对这类场景非常合适。
1.3 为什么选PJ85718DM加PIC18F4550这套组合
选型阶段我对比过几种方案。最简单的是DS18B20,单总线一根线就能带多个传感器,便宜好用,但单总线的时序要求严格,PIC18F4550如果用汇编或普通延时做时序,CPU占用率高,且多点挂载时现场排查故障点不方便。I2C接口的多通道传感器更符合需求,一条总线挂多颗,从设备地址天然区分节点。
PJ85718DM典型的本地加远程多通道结构,能同时测芯片附近背板温度和外接探头温度,一颗芯片顶多颗单点传感器,对PCB面积和BOM成本都友好。而且它内置了较完整的寄存器配置能力和可编程阈值,报警逻辑可以下放到传感器本身,MCU不用一直轮询。
PIC18F4550这边,选它主要看中两点:一是内置全速USB控制器,调试阶段可以直接虚拟成串口跟PC通信,省掉USB转串口芯片,烧录和调试非常方便;二是I2C、SPI、UART这些常用接口齐全,后续要扩展继电器控制、OLED显示、RS485网关都很顺手。虽然现在ARM Cortex-M系列的MCU更流行,但在这种中小规模测温节点上,8位机性能和功耗完全够用,开发难度还低。
2. 硬件设计与连接:从传感器引脚到MCU
2.1 PJ85718DM关键特性与引脚分配
PJ85718DM的测温范围我按数据手册典型参数设计,本地通道可以覆盖-40到125摄氏度,远程通道在接对了合适的二极管或热敏元件时可以到更高温度。分辨率方面它支持可配置的位数,高分辨率模式下实测稳定性能做到0.1度以内。
引脚方面,除了电源和地,核心就是I2C总线那两根线。芯片的地址引脚可以外接电平组合出多个地址,一条I2C总线上挂几颗传感器做多点监测很方便。报警输出脚我单独接到了PIC18F4550的INT口上,平时不用轮询传感器,温度越限时芯片自己拉低引脚,MCU直接进中断处理。
电源这里有个细节容易被忽略:PJ85718DM如果是3.3V供电,信号脚电平就按3.3V来,I2C上拉电阻要接到3.3V而不是5V。我一开始图省事把上拉电阻接到5V,结果读回来的数据全是0xFF,后来查手册才意识到电平不匹配。
2.2 PIC18F4550的接口资源分配
PIC18F4550在这个项目里承担三个任务:通过I2C接口轮询传感器数据,把数据换算成实际温度值,再通过UART或USB转发给上位机,同时驱动继电器或蜂鸣器做本地报警。
我实际用到的资源如下:
- I2C模块配置为主模式,时钟设为100kHz标准模式,接PJ85718DM;
- INT0外部中断接传感器报警脚;
- UART1接RS485收发器,用于长距离数据上报;
- USB接口调试阶段启用,用虚拟串口方式直接配PC上位机;
- RB口接了三个LED指示状态:电源、通信、报警。
RB口要注意的是,PIC18F4550的RB口带电平变化中断功能,如果用RB口做普通IO,要把中断控制寄存器对应位关掉,不然现场干扰脉冲会误触发中断。这个问题我第一次调试时浪费了大半天。
2.3 PCB布线与探头连接细节
PCB布局上,PJ85718DM要尽量靠近被测发热源,但又不能直接贴在散热器上导致自身结温升高超过工作范围。电源和地之间我加了100nF和10uF两级去耦电容,I2C引脚上拉了4.7k电阻到3.3V。
远程探头的连接是重点。PJ85718DM的远程通道对探头引线比较敏感,走线长了之后感应的噪声会叠加到温度信号上。我做了几轮实验后的结论:
- 一米以内的短距离可以只用双绞线,噪声影响很小;
- 超过一米建议用带屏蔽层的双绞线,屏蔽层单端接地;
- 探头线尽量避开电源线和继电器控制线,尤其不能跟220V强电走同一个线槽;
- 如果走线距离超过十米,建议改用恒流源方式驱动的探头或加一级滤波。
另外远程探头跟被测表面之间一定要保证良好接触。HVAC风管测温时,探头要固定在风管外壁或者插入风管内部的测温套管内,中间涂导热硅脂,否则测的是空气温度而不是管壁温度,两者差距能到好几度。
3. 固件实现:把温度变成可用的数据
3.1 驱动初始化与配置流程
PIC18F4550的固件我用的C语言,配合厂商提供的库函数。初始化顺序是:配置系统时钟优先,因为I2C和UART波特率都依赖它;然后是IO方向寄存器、I2C模块、UART或USB模块、外部中断,最后初始化传感器。
PJ85718DM的初始化配置逻辑如下:
- 先发复位命令让传感器回到默认状态;
- 配置测温分辨率,选择高分辨率模式;
- 配置报警阈值,低温阈值一个,高温阈值一个;
- 配置报警输出极性,默认是越限输出低电平,我保持默认没改;
- 写配置寄存器后读回校验,防止写失败。
这里建议每次上电都重新写一遍配置,而不是依赖传感器默认值。因为出现异常复位后芯片可能回到默认配置,报警阈值和分辨率全部丢失,现场排查时多一个隐患。
3.2 读取与数据转换
驱动写好后,读取流程就是标准的I2C读操作:先发传感器地址加写位,再写温度寄存器地址,接着发读位连续读两个字节,最后按分辨率系数换算成实际温度。换算公式根据不同分辨率有不同的LSB权重,比如14位模式下每个LSB对应0.03125摄氏度,16位模式下更高,把读到的原始值乘以对应系数即可。
本地通道和远程通道的寄存器地址不同,需要分别读取。我写了一个通用读取函数,把通道号作为参数传入,这样后续加新传感器时不用改动上层逻辑。
原始温度值这层换算比较简单,但直接用原始值做控制是有问题的。实测中传感器读数会有一个大约正负0.3度的随机抖动,这是正常现象,不是硬件故障。直接把这个值发给上位机或参与控制逻辑,很容易造成误报警。
我的处理办法是在固件里加了一个滑动平均滤波:
- 每次读到新值先跟上一值比较,若偏差超过5度则认为是异常跳变,丢弃本次数据;
- 正常数据进入长度为8的FIFO,取平均值作为最终输出;
- 报警判断用平均后的值与阈值比较,而不是单次采样值。
这样既保留了响应速度,又滤掉了随机噪声。读者可以根据自己的刷新周期调整FIFO长度,采样越快长度可以越长。
3.3 滤波、报警与数据上报
报警逻辑有两种实现方式,我最终选择了“传感器报警脚加MCU复核”的双保险方案。传感器内部有阈值比较器,一旦越限立即拉低报警脚,MCU收到中断后重新读当前温度并跟自己设定的阈值复核一遍。之所以要复核,是因为现场干扰可能造成一次虚假越限,中断触发后正常读取结果没有越限,那就不需要动作,清除报警标志继续运行即可,这个方法我实测下来能减少很多误报。
上位机数据上报的协议,我定义了一个非常简单的Modbus仿真的帧结构:设备地址加命令字加数据体加CRC校验。UART的波特率设为9600或19200,具体根据RS485总线长度来定。数据体包括本地温度、两个远程通道温度、报警状态字、固件版本号几个字段。
如果走的USB虚拟串口做调试,那就不需要额外协议,直接可读文本输出,比如一行输出“L:25.31,R1:42.18,R2:38.52”这种格式,上位机按行解析就行。现场调试用串口助手看这个文本日志非常直观。
3.4 远程通道参数校正与探头的选型
远程通道使用的是热敏元件作为感温头,不同型号之间器件离散性比板上集成的本地通道大不少。PJ85718DM内部针对常用器件类型做了一些补偿,但换用非标准探头时偏差依然明显。我在实际项目中做了两点校正:一是在常温下用标准温度计和被测表面比对,记录一个固定偏差,在固件里加上这个偏移量;二是用两点校准,分别测低温和高温两个点的误差,做一次线性映射,这样在中段温度区间内精度更好。
有个陷阱容易踩:探头跟被测面接触不实的时候,读数偏低,而且响应变慢。你拿红外枪比对时可能只差一两度,但动态响应完全跟不上,制冷启停的瞬间数据变化缓慢。这个问题在HVAC温控逻辑里很致命,因为控制算法可能因此出现很大的超调量。我后来在固定探头的方式上全改用弹簧压紧式安装,接触压力稳定,读数一致性明显好转。
4. 调试实录与常见问题速查
4.1 远程通道读数跳变甚至读到离谱值
我在实验室拉了三米双绞线做远程探头测试,发现读数偶尔会跳到零下四十多度。一开始怀疑探头接触不良,换了好几个探头问题依旧,后来示波器一看,远程通道引脚上有一簇簇的窄脉冲干扰,是旁边一台开关电源的谐波耦合进来的。
对策有三层:第一层硬件上把探头线换成双绞屏蔽线,屏蔽层单端接地;第二层在传感器远程通道引脚对地并联一个小容量电容,形成低通滤波;第三层固件上把突然跳变到物理不可能范围的数据丢掉并重新采样。三层都上了之后,连续跑了48小时没有再出现异常值。
4.2 本地通道温度比预期高好几度
有次客户反馈机箱温度显示45度,实际开盖摸起来并没有那么热。我检查后发现是PJ85718DM的摆放位置太靠近一个功率电阻,电阻本身在满载时表面温度超过80度,辐射热把传感器周围空气烘热了,传感器测到的其实是局部微环境温度,不是机箱平均温度。
这个问题的本质是测温点选择错误,不是传感器质量问题。我把传感器挪到靠近通风孔的位置,同时加了一个小的导流罩,让气流经过传感器周围,读数跟实测环境温度基本吻合。设计阶段就要想清楚:你要测的是器件温度还是环境温度,同一颗传感器放在不同位置含义完全不同。
4.3 I2C通信不稳定,时好时坏
I2C总线调试报错中断可以算嵌入式老生常谈的问题。在传感器和MCU之间距离稍远、或线缆较长时,高速模式下的时序余量就不足了。我在这块出过的问题是总线上同时挂了其他I2C器件,某个器件的地址跟PJ85718DM冲突。
排查方法很简单:用示波器抓地址字节,看总线上实际发出的设备和应答情况;或者把其他器件从总线上逐一断开,直到找到冲突点为止。另外I2C上拉电阻的取值也会影响通信稳定性,阻值太大信号上升沿太慢,太小则灌电流过大,4.7k到10k之间的典型值都正常,但如果线长或器件多可以改用到3.3k左右,具体看波形调整。
4.4 上位机长时间运行后收不到数据
这个故障排查的过程让我印象很深。现象是RS485连接的上位机一开始正常,跑半天后就不再刷新了,重启节点又好。查来查去发现是PIC18F4550的UART在接收缓冲区溢出后没有正确恢复,中断标志没有清理干净,MCU在等待状态里出不来了,而看门狗被关掉了,所以程序挂死没人管。
对策是打开看门狗定时器,喂狗周期设置在1秒左右;同时UART接收中断里对溢出错误做显式处理,清掉错误标志位重新使能接收。这类问题在长时间无人值守的HVAC控制器里非常典型,一定要养成开看门狗的习惯。
5. 我的几点实操建议
如果照着这个方案做自己的测温节点,建议再注意几个细节。
第一,传感器配置建议做成可外部修改的参数表,放在EEPROM或Flash里。原来我写死阈值和校准值,现场要调一个下限温度都得重新烧录固件,效率太低。改成参数表后,用上位机命令直接在线改,设备不用断电拆壳。
第二,通信协议里一定要带上CRC校验,而且收到CRC错误时不要一律丢弃,有些丢包率高的场合可以重发一两次。我见过同事的设备就是因为串口误码率稍高就直接丢帧,结果上位机长期显示旧数据,特别误导人。
第三,远程探头线缆用标准规格,不要用细的电子线,电阻值会拉开探头本身的激励电流偏差。线缆选型错误会把好端端的温度链路搞成现场最难排查的软故障之一。
做温度和暖通控制这块,越基础的东西越考验工程素养。选一颗多通道数字传感器把本地和远程温度都采集进来,再用8位单片机的资源把它转化成可靠的控制信号和数据流,这一套做完之后,你会发现大多数场景的真正难点不在驱动,而在怎么把“传感器读数”变成“现场可信赖的温度”,而那恰好是数据手册不会告诉你的部分。