做嵌入式的人都知道温度监测是看起来最简单、实际上坑最多的一类活。你以为是读一个寄存器结果硬件上要面对传感器漂移、总线干扰、远距离传输、强电启停冲击软件上还要处理滤波、协议、重复采样。最近我在一个暖通空调HVAC控制项目里用 PJ85718DM 数字温度传感器配合 STM32F415ZG 主控同时做本地温度读取和远程节点温度回传整条链路跑了一段时间也有些超出预期的收获。这篇文章就围绕这套组合把需求拆解、硬件连接、软件逻辑、实测数据和踩坑记录都摊开讲一遍。适合正在做HVAC控制器、机房监测或嵌入式设备热管理的朋友参考。1. 本地与远程温度监测的需求拆解不是距离问题是拓扑问题1.1 本地温度与远程温度的定位差异先不说芯片先想清楚你要测的是什么。标题里的“本地与远程”不是简单按距离划分。本地温度通常指主控板附近、能通过I2C或SPI直接访问的传感器距离在厘米级到一米左右和主控共用一个电源域远程温度则指传感器节点放在不同房间、管道或配电柜附近可能是另一条供电回路甚至隔着几十米双绞线。在HVAC系统里本地可能测控制箱内部温度、电源板温度远程测送风、回风、盘管进出口、冷媒管道表面温度。两类数据用途完全不一样本地更偏设备保护和板级热管理远程更偏环境控制。如果一开始就把它们混在一个采集逻辑里后面做轮询和故障隔离会很难受。确定核心需求时我习惯先列一个问题清单每个测温点要测什么介质、温度范围多大、精度要求是多少、传感器离主控多远、现场有没有强电干扰、数据最终供控制还是仅显示。比如控制回风温度做PID精度要求可能要到±0.3°C而测机柜外壳温度±1°C也能接受。远程测点通常数量多、位置分散如果每路都拉一根模拟线施工量和维护成本会非常难看。这也是我最终选择数字传感器加总线组网的原因把复杂留在板内把简单带给现场。1.2 为什么是PJ85718DM STM32F415ZG为什么最后选了 PJ85718DM我手上的这颗是数字I2C接口测量范围覆盖-55°C到125°C典型精度±0.5°C分辨率能到0.0625°C。单总线读回来的就是工程值不需要做ADC参考校准也不需要像热敏电阻那样做非线性查表。多个传感器还能靠A0/A1/A2地址位挂在同一条I2C总线上本地扩容很自然。至于STM32F415ZG选用理由是主频168MHz、带FPU和DSP指令做HVAC里的PID、滤波和Modbus轮询有余量板上有多个I2C、UART、SPI方便把本地传感器、RS-485通信、显示模块全接在一颗主控上。之前我也考虑过用低成本的M0但项目还需要在上面跑数据记录和简单界面最后妥协选了F4。对比原来的NTC加ADC方案数字传感器省了两个电阻和一根线但代价是接口时序必须写对、上拉电阻要调好。选型这个东西没有银弹只有对你当前场景最合适的选择。如果项目测温点很少、距离很近、精度又不敏感NTC反而更省钱如果像HVAC这样既要多点测量又要长期维护少出问题数字传感器加总线就是更合适的路径。2. 硬件设计与连线PJ85718DM怎么接才能避免干扰2.1 本地传感器的典型接法与布局硬件部分先说本地传感器的接法。PJ85718DM标准连接很简单VDD接3.3VGND接GNDSCL和SDA各接一个上拉电阻到3.3V上拉阻值取4.7k左右比较常见。如果I2C总线上挂了多颗传感器每颗的A0/A1/A2引脚通过跳线接高或接低组合出不同地址最多可以接8颗。我在PCB上习惯预留三组排针方便现场改地址。电源脚加0.1µF退耦电容并且让电容尽量靠近芯片电源脚如果总线上还有其他设备最好再并一个10µF电容避免长线供电导致的电压毛刺。布局方面尽量别让I2C线与继电器线圈、交流接触器控制线平行走线这些强电信号边沿很陡容性耦合容易让通信出错。传感器要放在被测量介质附近同时远离大功率发热元件尤其是电源MOS管和变压器。第一次做时我把传感器放在主控板中央结果读数比环境高2°C后来把传感器挪到PCB角落问题才缓解。另外一个容易被忽略的点是I2C总线长度机箱内部走线超过20cm就应该考虑降低速率或者加缓冲器不要指望数字接口能无限容忍走线电容。2.2 远程节点的RS-485组网远程节点不能直接把PJ85718DM拉几十米线。I2C是为板内通信设计的线长超过两三米后上拉电阻、总线电容和地电位差都会让你收到一堆NACK和错数据。所以远程测温我采用RS-485总线每个远端节点由一颗小MCU加PJ85718DM和RS-485收发器组成小MCU负责本地读取传感器然后把温度放进Modbus寄存区STM32F415ZG作为主站通过UART外接RS-485收发器轮询各个节点。组网时用屏蔽双绞线A/B一对差分信号最远两端各接一个120Ω终端电阻。总线空闲时所有收发器都处于接收态如果线上没有数据A/B之间电平不确定需要加偏置电阻把空闲电平拉到确定状态。通常取5V经10kΩ接到A端B端经10kΩ接到GND。每个节点的地址拨码开关设置成1、2、3……主站按地址顺序轮询。这种主从模式很成熟好处是从机不需要主动上报总线不会冲突排查故障也简单哪个节点不回数据单独查那一路就行。2.3 电源与地线处理这部分最容易被低估。HVAC现场往往有多个电流回路压缩机一启动电网电压被拉低RS-485收发器或传感器供电如果跟着抖读数就会出现毛刺。我给远程节点用的是隔离DC-DC输入24V直流输出5V再转3.3V并且把RS-485收发器的地线与节点内部地分开只通过通信线的屏蔽层单端接地。主站侧也加了TVS管和自恢复保险丝防止雷击浪涌顺着屏蔽线传进来。经验是如果发现远端某个节点偶尔通信失败先别怀疑协议打开电源测量一下上电瞬间的电压波形。之前一次现场调试中有一路供电线太长远端节点上电时掉到2.8V传感器直接复读0xFFFF把偏置电容加大以后问题就没再出现过。另外现场的地线不一定干净不要想当然把各个节点的GND都连在一起地环路造成的共模电压经常会超过RS-485收发器的承受范围。3. 软件配置与处理算法让温度数据变成可信数据3.1 I2C初始化和寄存器读取软件部分使用STM32的HAL库开发。初始化I2C1作为本地总线速率先定为400kHz如果传感器离主控稍远可以降到100kHz。读温度用寄存器函数一次读两个字节可以拿到原始温度值。参考伪代码uint8_t temp_reg[2] {0}; uint16_t dev_addr 0x9E; // 由实际地址引脚决定 if (HAL_I2C_Mem_Read(hi2c1, dev_addr, 0x00, I2C_MEMADD_SIZE_8BIT, temp_reg, 2, 100) HAL_OK) { int16_t raw (temp_reg[0] 8) | temp_reg[1]; float tempC (raw 4) * 0.0625f; }注意HAL_I2C_Mem_Read的地址参数要带方向位也就是addr1。第一次调试时这个细节浪费了半天。温度寄存器的高字节在前低字节在后把两字节拼成int16_t再右移4位丢掉小数低位最后乘0.0625就是摄氏温度。如果需要更高精度可以改用14位读出模式具体看手册配置。这也是数字传感器比模拟方案麻烦的地方必须把时序和地址机制搞清楚而模拟方案只要把ADC值算对就行。上电后不要立刻读PJ85718DM内部ADC需要时间稳定至少等50ms。如果单次转换模式每次发起转换后也要留出转换完成时间否则第一次读到的可能是旧值。3.2 滤波、校准与异常识别数字传感器虽然比模拟方案省心但读数还是会抖特别在HVAC场景里风机会把温度吹得上下起伏。我用了去极值滑动平均连续采样8次去掉最大最小值剩余6次平均。这个滤波器计算量小还能抑制异常尖峰。做控制用的温度值我还会再套一个一阶低通系数取0.2左右让进入PID的值变化更平滑。注意不要过度滤波否则温度响应太慢看现场曲线会感觉系统“发闷”。校准方面数字传感器出厂有标定但PCB热环境不同最好做一次偏置校准。方法很简单把传感器和参考温度计放到同一环境等读数平衡后记下差值作为软件偏移。HVAC控制器一般只要求±0.5°C单点偏置修正就够了。更讲究的做法是两点校准在15°C和45°C各记录一次拟合线性修正系数。异常识别也要做连续读回0xFFFF要重试重试三次仍失败就标记传感器故障温度变化率超过每10秒5°C时大概率是通信或供电毛刺不要直接用这个值参与控制暂时保持上一次有效读数。3.3 Modbus远程轮询与数据解析远程读取我走了Modbus RTU。主站发03功能码读保持寄存器从机节点把PJ85718DM的温度值放在寄存器0x0000单位0.01°C。比如温度25.37°C寄存器值存2537。为什么这么做用整数协议避免浮点字节序问题也方便从机端处理。请求帧大概是从机地址 1字节 功能码 0x03 起始地址 0x00 0x00 寄存器数量 0x00 0x02 CRC16 低字节 高字节从机返回后主站解析数据寄存器值除以100得到浮点温度。要处理超时从机不响应时等待超过100ms就认为本次超时连续超时3次标记节点离线。轮询周期根据节点数决定一般500ms到2s轮一遍就够了。CRC校验不能省现场干扰偶尔会翻转几个字节只要CRC错一帧就丢弃重发不会污染温度数组。我习惯把Modbus驱动封装成独立模块上层只传节点地址和寄存器地址返回结构体里带状态码。这样后面增加节点类型或者改成CAN总线主流程几乎不用动。3.4 本地与远程数据的统一管理本地和远程的温度最终要进同一个处理流程。我定义了一个结构体编号、类型、原始温度值、滤波后温度值、状态、时间戳。本地传感器直接按I2C地址填编号远程节点按Modbus地址填编号。控制逻辑不关心温度来自哪里只管遍历这个数组做报警判断和PID输入。这样上层代码变简单调试时也可以从数组里一次性把全部温度打出来。另外建议把温度值统一用int16_t存储单位0.01°C只在显示或者控制输入的时候再转float。这种做法的好处是节省内存、协议解析快也不会因为在不同编译器里浮点格式化产生告警。实测在STM32F415ZG上50个温度点的轮询加滤波CPU占用不到5%。如果以后需要扩展更多测点这个数据结构还能直接沿用不至于推倒重写。4. 实测数据与调优记录这套组合在现场的真实表现4.1 恒温箱内的精度测试做完软硬件后我在恒温箱里做了一组测试。恒温箱设定值分别为15°C、25°C、35°C、60°C每个温度点稳定30分钟记录本地传感器、远程节点数值和参考温度计读数见下表。设定温度(°C)参考温度计(°C)本地PJ85718DM(°C)远程节点(°C)1515.015.115.22525.024.925.13535.035.234.96060.059.860.1可以看到偏差基本在±0.3°C以内符合HVAC的控制精度要求。远程节点经过RS-485长线传输后数值和本地传感器相比没有明显额外偏移说明通信链路没有引入数据错误。这个结果也比较符合数字传感器加差分总线的预期。需要注意的是测试环境毕竟没有压缩机启停、变频器辐射这类干扰现场能不能保持这个精度还要看供电和布线。4.2 现场运行中遇到的3个典型问题真正让人头疼的是现场问题。第一个是压缩机启动瞬间温度值偶尔跳成-55°C后来发现是强电干扰导致传感器供电毛刺传感器内部采样出错。解决办法是在传感器供电处并联一个大电容并且把读到的温度变化率限制在每10秒不超过5°C超过就维持上一次数值。第二个是远程节点一段时间后失联排查发现是RS-485的屏蔽层两端都接地了形成地环路。改成单端接地后通信就恢复正常。第三个是本地传感器放在通风道旁边读出的风温比实际高1.5°C原因是传感器没有和风道壁隔热辐射影响太大加了一片隔热垫才好。这几个问题有一个共同点都不是传感器本体精度造成的而是周围环境通过电源、地线、热辐射把读数拉偏。所以调试温度系统时别只盯着代码和芯片把现场当成一个整体来看。我后来在每个测点都加了一条调试注释记录供电方式、线长、附近有没有强电设备后续排查效率高了很多。4.3 告警阈值与滞回控制报警逻辑不要用单点阈值直接触发。HVAC现场温度波动正常设定回风温度25°C你设个高于27°C报警风机启动瞬间可能到27.5°C结果误报一整天。建议加滞回报警触发点27°C恢复点25°C并且要求连续采样3次都超阈值才确认报警。这样人为噪声、尖峰都被过滤掉。滞回值的设置需要根据系统惯性调整惯性大的系统可以设到2°C惯性小的设0.5°C即可。另外远程节点离线也要纳入报警体系。温度读数正常但节点不响应说明通信链路出了问题这时应该给出“节点离线”而不是“温度超限”的告警。如果你把离线当成超低温处理控制逻辑可能误开加热现场会更乱。我的做法是给每个节点维护一个离线计数器在状态结构体里单独标记与控制告警分开。5. 常见故障排查与避坑清单给后来人的一些建议5.1 读不到传感器数据时的排查顺序如果I2C读不到数据按下面的顺序查。先量SCL/SDA空载电平如果电压不足3.3V上拉电阻可能没焊或阻值太大。再查看总线地址拿逻辑分析仪看ACK位没有ACK基本就是地址错或芯片没上电。然后检查器件供电正常时VDD脚电压不能低于3.0V。最后确认时钟速率长线时400kHz容易出错改成100kHz再试。我碰到过一次问题出在代码里复用引脚没配置成开漏输出导致总线被拉死。之前还有一个容易踩的坑多个传感器地址冲突。PJ85718DM的地址引脚如果全部浮空某些芯片默认地址会重复I2C上两个从机回同一个ACK主设备完全懵掉。所以每一颗传感器都必须明确接高接低不要想着靠软件区分。建议在PCB上丝印标注每个位置的跳线组合生产装配时按表设置避免批次混乱。5.2 RS-485通信出错的排查顺序RS-485通信出错先排查终端电阻。线上A、B之间电阻应该在60Ω左右如果测到120Ω说明另一端终端电阻没接或接掉。然后查偏置电阻空闲时A对B电压应为正用万用表直流档测一下。接着确认每个节点地址没有冲突拨码开关重复会导致总线上地址碰撞。再检查地线屏蔽层只能单端接地如果不确定就先断开屏蔽层测试。最后看波特率是否完全一致。多数RS-485异常问题都出在物理层协议层反而嫌疑最小。如果发现某个节点上电后占用总线可能是收发器使能引脚写反了一直在发送状态。软件里要保证除发送期间外收发器都处于接收模式。还有一个不起眼的经验从机的RS-485收发器供电最好和MCU供电分开一点或者至少加个瓷片电容不然主站一发请求从机供电纹波变大可能直接导致从机复位。5.3 温度数值异常与硬件布局的关系已经打印出正确的寄存器值但温度不对一般不是代码问题。先看传感器附近有没有强热源比如LDO、变压器、功率电阻。一个LDO在3.3V输入5V时压降1.7V电流50mA就有85mW热耗紧贴传感器足够把读数抬高几度。再看传感器封装和被测介质接触是否良好如果要测铝管表面温度要使传感器探头与管壁贴合中间涂导热硅脂否则空气层会带来很大误差。最后排查采样时刻如果长时间在强电磁干扰下运行可以把转化模式改成慢速高精度提高抗扰能力。另外传感器自热效应也值得一提。PJ85718DM工作电流很小常规情况下自热可以忽略但如果把它放在密闭不通风的盒子里长时间运行后环境温度会缓慢升高读数会因此偏高。这种偏差不是突然出现的而是慢慢漂移容易被当成正常现象。建议在密闭空间里校准到预期工作状态而不是在桌面环境里校准。5.4 设计上值得保留的几处细节总结几条实际设计中值得保留的细节。PCB上给传感器地址脚预留跳线现场改地址不用动烙铁。I2C总线上拉电阻不要焊死先用排阻留好位置遇到长线或慢速设备时方便调整阻值。UART转RS-485时收发器方向控制引脚一定要接好并在软件里发送前后留一小段延时。远程节点固件里加独立看门狗即使主站长时间不轮询从机自己也要能恢复。调试日志里把原始温度、滤波后温度、状态标志一起打出来方便对比。还有一点是固件升级。如果远程节点数量多最好预留I2C接口的烧录座或者干脆设计成支持通过RS-485做Bootloader升级。现场拆卸节点是一件非常麻烦的事能远程更新固件会省下大量差旅成本。STM32F415ZG本身有充足的Flash放一个简易IAP引导程序并不是难事值得在项目初期就规划进去。最后聊几句自己的体会。如果重新做这套系统我会在项目一开始就把本地和远程分开设计数据结构而不是等现场调试时再拆。温度系统的价值不在读数有多精细而在于长时间运行后给你的数字仍然可信。PJ85718DM配合STM32F415ZG这套组合功能上足够覆盖中小型HVAC控制器的测温需求但真正的工程量在硬件防护和故障处理上。希望这篇文章里的接线、代码和排查记录能帮你少走一点弯路。
阅读完成 · 觉得有帮助?