1. 温度采集链路的设计思路:从传感器到远程可视化的完整拆解
标题里的“PJ85718DM”和“STM32F722VE”放在一起,本质上是在回答两个问题:温度数据从哪来,以及温度数据往哪去。
先看前者。PJ85718DM 是一颗数字温度传感器,内置 ADC,直接输出数字信号,省去了模拟前端里最让人头疼的运放校准和漂移问题。我在实际项目里见过太多人因为选了 NTC 加比较器的方案,结果在温漂和线缆压降上反复折腾。而数字传感器直接把温度转换成数字量输出,单片机的 ADC 和基准电压那部分几乎可以不用操心,这对 HVAC 这种需要长期稳定运行、现场环境又不友好的场景来说,吸引力非常大。
再说后者。STM32F722VE 是意法半导体 A7 系列里带硬件浮点单元的一颗芯片,主频 216MHz,动态功耗控制在很低的水平,而且片内集成了以太网 MAC 控制器。这两点加在一起,意味着它可以在完成本地温度采集、滤波、PID 运算的同时,还能把数据打包上传到远端的监控平台。你不需要外挂一颗网络协议芯片,也不用额外做一套数据转发逻辑,一颗片内就全部搞定。这是整个方案能够保持简洁最关键的硬件原因。
这套组合典型的应用场景是这么两类:一类是嵌入式设备内部的温度管理,比如电机控制器、变频器内部的散热监测;另一类是 HVAC 系统里对机房、空调箱、冷却塔回水温度的采集与上传。前者对实时性和稳定性要求高,后者对远程运维和故障预警要求高。PJ85718DM 负责把温度变成数字,STM32F722VE 负责把数字变成决策,两者各司其职,衔接得非常顺。
温度数据从传感器到最终被远程 Web 页面展示出来,链条其实不长:传感器输出数字温度 → 单片机通过 IO 读取 → 软件滤波和单位换算 → 本地 LCD 或串口屏显示 → 通过以太网封装成 JSON 或 MQTT 消息 → 远端服务器接收并存储 → 浏览器或手机 App 展示。这条链路的每一环,在后面的章节里我都会给出可以落地的细节。
2. 硬件选型背后的逻辑:为什么是这两颗芯片组合
2.1 PJ85718DM 的关键参数与接线细节
PJ85718DM 最常见的封装是 SOIC-8,供电电压推荐 3.0V 到 5.5V,我实际用的比较多的是 3.3V 供电,这样可以直接和 STM32 的电平系统对接,省去电平转换电路。
它的关键参数包括:
- 测温范围:-55℃ 到 +125℃
- 分辨率:可以在 9 到 12 位之间配置,默认 12 位意味着分辨率大约是 0.0625℃
- 通信接口:单总线协议,和 DS18B20 兼容
- 掉电模式:支持,但工业场景我一般很少用,因为电源本来就在
单总线协议最大的优势就是省 IO。一个 GPIO 就能挂多颗传感器,每个传感器有自己的 64 位序列号,MCU 可以通过 ROM 指令枚举总线上挂载的所有设备。这在 HVAC 场景里非常实用,比如一台空调箱需要采集送风温度和回风温度,你只需要布一根三芯线(电源、地、信号)到两个测点即可,不需要每路传感器占用一个独立 IO。
接线时我有一条经验要优先分享:单总线信号线上的上拉电阻务必要接。PJ85718DM 和 DS18B20 一样,总线处于释放状态时需要外部上拉才能保证逻辑高电平。有人图省事不接,结果就是读出来的温度随机飘,尤其在长线传输时,逻辑电平被电容拖垮,数据完全不可信。
上拉电阻的阻值选择也有讲究。短距离(仪器内部走线 10 厘米左右)我一般用 4.7kΩ;长距离(大于 5 米)则要用 1kΩ 左右,因为长线的分布电容更大,需要更强的上拉能力才能保证信号边沿够陡。我这几年做远程温度采集时,把这条原则当成默认规则来执行,几乎没有再被时序问题坑过。
2.2 STM32F722VE 的选型理由:以太网与外设的协同
STM32F722VE 这颗芯片可能有人会觉得“杀鸡用牛刀”,毕竟测温本身对算力要求并不高。但你要考虑到另一层需求:如果以后项目要升级,加入振动采集、电流谐波分析,或者多路 PID 温控,那么 MCU 是否还有余量?F722 的主频 216MHz 加上单精度浮点运算单元,意味着它可以同时跑温度滤波、控制算法和网络协议栈,三段任务之间互不干扰,这是很多低端款 MCU 做不到的。
另外一个关键点是 STM32F722VE 内置了以太网 MAC 控制器,搭配一颗外部的 PHY 芯片(我常用的是 LAN8720A)就可以直接跑 TCP/IP 协议栈,无论是 lwIP 还是直接走裸机协议,实现成本都非常低。如果用串口转以太网模块的方案,成本虽然低一些,但数据吞吐量和实时性都会打折,而且调试起来还要关心模块内部的固件行为,不如直接用片内 MAC 简单透明。
F722VE 的另一亮点是片内的温度传感器。虽然它的精度不如外部数字传感器,但可以用来做参考校准。我在项目初始化阶段会同时读取 MCU 内部温度和 PJ85718DM 的读数,通过两者在室温下的偏差来做一个粗校准,这个做法在设备保养和维修时非常有用。平时运行中,我也定期对比内部温度和外部采集值,当作一种传感器失效的快速诊断手段。
2.3 硬件搭配的常见踩坑点
- 共地问题:传感器和 MCU 之间必须确保参考地一致。如果传感器由单独的 5V 电源供电,而 MCU 由 3.3V 供电,两者不共地时,单总线的逻辑电平会完全乱套,这属于新手最常见的低级错误。
- UPS 电源干扰:工业环境里传感器信号线尽量不要和变频器输出线、电机电源线走同一根线槽。我实际测量过,变频器启动瞬间,未屏蔽的信号线上可以感应出几十伏的干扰脉冲,直接打坏 GPIO。所以信号线务必用屏蔽双绞线,屏蔽层一端接地。
- ESD 保护:HVAC 运维时传感器探头经常被插拔,插拔瞬间的静电很容易击穿 GPIO。建议在信号线上加 TVS 管和串联限流电阻。TVS 管选 5V 的即可,串联电阻 100Ω 到 220Ω,否则上拉电阻会被分压,影响通信时序。
3. 软件层面的温度采集与滤波实现
3.1 单总线时序:读温度的核心细节
单总线协议虽然只有一根信号线,但它对时序要求比较严格,需要 MCU 精确控制电平持续时间。实际写驱动时,我通常使用定时器中断来保证微秒级延时,避免依赖空循环延时的不稳定性。比如复位脉冲要求拉低 480μs 至 960μs,然后释放总线,等待从设备拉低 60μs 至 240μs 应答。如果延时不准确,读到的全是 0xFF。
写一位数据和读一位数据的时序窗口都是 60μs 到 120μs,关键区别是采样点位置。读数据时,MCU 拉低总线 1μs 后释放,从设备会在 15μs 到 60μs 之间把总线拉低(表示 0)或保持高电平(表示 1)。你必须在这个时间窗内完成 GPIO 采样,太早读到的是 MCU 自己拉低时的低电平,太晚就错过了数据窗口。我一般做法是:拉低 2μs 后释放,再等 8μs 左右去读 GPIO 状态,这个采样点基本稳。
驱动稳定后,读温度的完整流程是:初始化(复位 + 存在检测)→ 跳过 ROM(只有一个传感器时)→ 启动温度转换 → 等待转换完成(12 位分辨率下约 750ms)→ 复位 → 跳过 ROM → 读取 9 字节暂存器 → 提取低字节和高字节,按 12 位格式拼接成有符号整数 → 乘以 0.0625 得到摄氏温度值。
注意:12 位分辨率下转换时间最长约 750ms,如果系统需要更快的轮询频率,可以考虑配置成更低的 9 位分辨率,转换时间会缩短到 93.75ms,但分辨率下降到 0.5℃。做温控场景可以用,做计量场景就有点粗糙了。
3.2 软件滤波:抛开毛刺,保留趋势
任何数字传感器都不可避免会有毛刺或偶发跳变,PJ85718DM 也不例外,尤其在工业现场和强电设备共存的场合。直接拿原始数据去参与 PID 控制,温度波动会很大,系统会来回振荡。我推荐一种组合滤波方案:
第一步,滑动窗口中值滤波。取最近 5 次采样值排序,去掉最大值和最小值,对剩余 3 个求平均。周期按 1 秒算,延迟 5 秒左右。好处是对脉冲式干扰抑制性极强,而且不依赖运气成分。
第二步,一阶低通滤波。用公式 newValue = oldValue + alpha * (sample - oldValue),alpha 取 0.2 到 0.5 之间。中值滤波负责消除脉冲,低通滤波负责平滑趋势,两者串联起来,数据曲线非常干净。如果你用 F722 的 FPU,这里可以放心用浮点,计算开销可以忽略不计。
反过来我要提醒一句:滤波别过头。如果 alpha 太小且窗口太长,系统的响应时间会变得迟钝。比如温度从 20℃ 突变到 30℃ 时的阶跃响应,你希望 10 秒内能看到接近真实值,而不是拖到一分钟。这个平衡要根据你具体的温控周期来调整,先设 alpha=0.3,然后看实测响应曲线再微调。
3.3 单位换算与显示格式化
温度数据最终要么显示在本地,要么上传到远端,所以格式化要做好。我的建议是全链路统一用摄氏度小数点后两位的字符串格式,避免在接收端再做一遍精度处理。如果只是纯数据帧,也可以直接用原始值乘以 10 的整数形式传输,这样可以省去浮点序列化的开销,数据量也更小。比如 25.0625℃ 可以传 250(0.1℃ 精度),显示端再除以 10。
| 精度要求 | 推荐格式 | 传输占用量 |
|---|---|---|
| 0.5℃ | 整数摄氏度,如 25 | 1-2 字节 |
| 0.1℃ | 10 倍整型,如 250 | 2 字节 |
| 0.01℃ | 100 倍整型,如 2506 | 2 字节,需注意溢出 |
在 HVAC 场景里,0.1℃ 的传输精度已经完全足够,毕竟风阀和水阀的执行机构本身就有滞回区,更精细的数值更多是心理安慰。
4. 本地显示与远程上传的实操记录
4.1 本地端:LCD 显示卡片与告警灯
本地显示我优先推荐用串口屏或者 I2C OLED,依赖于 STM32F722VE 丰富的串口资源,不会占用主循环太多 CPU 时间。显示内容一般分为三个区域:
- 顶部:当前时间和系统运行状态(正常/告警)
- 中部:各通道温度值,大号字体,便于运维人员快速读取
- 底部:历史最低最高温度记录,用于查故障前后环境是否有剧烈变化
另外告警逻辑要在 MCU 里做。我设定类似这样的触发条件:温度高于上限持续 10 秒,或低于下限持续 10 秒,才进入告警状态。这种迟滞设计可以避免温度短暂越限就引发误报,否则空调箱开个门,探头附近温度瞬间升高,系统就响个不停,运维人员会崩溃。
本地端还有个容易被忽略的细节:告警时除了屏幕闪烁,尽量要有一个继电器或蜂鸣器物理输出。屏幕闪烁在没人经过时毫无作用。我一般把告警输出引脚接到一个 LED 灯板或蜂鸣器,同时串口上报给远端平台,形成多级告警链。
4.2 远程端:以太网 + MQTT + 云端展示
远程通信协议方面,我的默认选择是 MQTT。原因有三:一是 MQTT 基于 TCP,可靠性有保证;二是消息体积小,非常适合温度这种小数据量高频上报;三是各类物联网平台原生支持,接入成本低。
STM32F722VE 上跑 lwIP,然后通过 MQTT 客户端库连接远端 broker,配置非常简单:
// 伪代码:MQTT 参数配置示例 struct mqtt_connect_opts opts; opts.client_id = "hvac_01_f722"; opts.username = NULL; opts.password = NULL; opts.keepalive = 60; opts.clean_session = 1;数据载荷我建议用 JSON,虽然比裸数据字节大一些,但字段语义清晰,下游解析方不用猜。一帧典型的温度上报数据:
{ "device": "hvac_01", "ch1": 25.06, "ch2": 18.50, "alarm": false, "ts": 1700000000 }上报周期一般设 10 秒到 30 秒。HVAC 系统温度变化本身很慢,没必要 1 秒一报。有人担心 30 秒太长看不到实时性,但实际上热惯性和滤波已经磨平了高频变化,30 秒的间隔完全能还原趋势,还能有效降低云端存储压力和流量的消耗。
4.3 时间同步的重要性
温度数据如果没有准确的时间戳,事后排查故障会非常痛苦。MCU 上电后应该通过 NTP 对时,或者从串口调试工具手动写入时间。如果网络不可用,至少也要用片内 RTC 保存时间,否则重启后时间归零,整个数据链路的分析价值会大打折扣。
我在实际项目中遇到过一种情况:现场设备放在没有互联网的内网环境,MCU 无法访问 NTP 服务器。我的处理方案是在本地网段里放一个广播的 UDP 时间同步服务,由维护电脑启动时自动广播当前时间,MCU 收到后校准 RTC。这样既不依赖互联网,又能保证时间基本同步,虽然和 NTP 比有秒级偏差,但查温变趋势完全够用了。
5. 工业与 HVAC 场景下的进阶功能扩展
5.1 多通道温度轮询的调度设计
当单总线上挂了多颗 PJ85718DM 时,要合理设计轮询调度。由于每颗传感器的转换时间最长为 750ms,如果按顺序遍历所有传感器,每个周期都要等最长的转换时间,轮询效率会非常低。更好的方案是:同时启动所有传感器的转换,等待一次最长时间,然后依次读取所有传感器的结果。
具体实现方式:复位总线 → 跳过 ROM → 写转换命令 → 保持总线释放 750ms → 然后对每个传感器依次执行“复位 → 匹配 ROM → 读暂存器”流程。这样多颗传感器的总耗时只比单颗传感器多出读取所需的时间,而不是成倍增加,整个系统的响应能力一下子就上来了。
另外,如果某些传感器损坏或者被拔掉,总线上会出现一个设备不复位的情况,读取流程就可能阻塞。所以我在驱动里加了超时判定:每次复位后检测存在信号,如果超过 100ms 没有应答,就标记该传感器离线,并切换到下一个,不要卡死在读取上。无人值守的 HVAC 机房设备经常被清洁工人误碰插头,这个容错逻辑非常必要。
5.2 温控联动与故障诊断
温度采集的意义不只是显示,更多是参与控制。比如 HVAC 里的冷却塔回水温度,如果超过设定值,MCU 就要提高风扇转速或旁通阀开度。STM32F722VE 的浮点单元做标准 PID 几乎是零压力,但我要强调一点:执行机构的死区设置一定要比传感器分辨率大。
我遇到过案例:某项目用 12 位分辨率传感器,温度波动幅度 0.05℃,PID 输出非常敏感,风阀电机频繁动作,结果执行机构几个月就报废了。后来我把死区加大到 0.5℃,电机动作频率降了一个数量级,温度控制精度仍然是合格的 0.3℃以内。
同时,我还维护了一个故障诊断表,每次采集到异常值(如超过量程、连续多秒不变、数据跳变超过 5℃)就自动记录计数,配合运维机制判断是传感器故障还是线缆问题。这个诊断信息通过 MQTT 上报到远程平台,技术人员可以在机房主机上直接看到设备故障预警,不用跑现场。
5.3 断网续传与数据补传
工业场景最怕的就是边缘设备采集了数据,远端却断网了。正常思路是本地把数据缓存起来,网络恢复后再补传。STM32F722VE 有足够的 SRAM,也可以通过 SDIO 接口外挂 TF 卡做存储。
我在项目里的做法是:在内存中维护一个环形缓冲队列,预设超时阈值。当网络断开超过 30 秒后,MQTT 客户端进入离线模式,温度数据按正常周期写入 TF 卡上的日志文件;网络恢复后,MCU 先读取缓冲区的旧数据,按时间戳顺序补传,再切换到实时上报状态。这样即使中断一小时,远端也能获得完整的数据曲线。
// 伪代码:断网补传逻辑 if (mqtt_connected) { upload_realtime(temp); } else { log_to_sd(temp); // 记录到本地 } if (mqtt_reconnected) { upload_buffered(temp_log); // 按序补传 }注意文件系统的磨损均衡问题,TF 卡反复写同一个扇区容易坏块。建议日志文件用环形命名,比如 log_0.dat 写到 log_9.dat,轮换覆盖,这样能显著延长存储介质寿命。
5.4 工程部署中的线缆选择与防护
HVAC 现场的线缆防护往往是项目成败的分水岭。温度传感器探头虽然抗干扰能力强,但线缆还是会成为弱点:
- 短距离(仪器柜内部)用普通屏蔽线即可
- 长距离(百十米)必须用带屏蔽层的双绞线,单总线信号用一对,电源用一对,屏蔽层单端接地
- 从室内穿墙到户外部分,线缆要套波纹管或线槽,避免被鼠咬和机械损伤
我还有一个习惯是:传感器排线接头全部用镀金端子或做防水处理。机房和空调箱环境湿度大,普通的排针插头时间久了会氧化接触不良,导致读到的温度跳变严重或者直接离线。如果现场条件允许,优先用航空插头,成本高一些,但长期稳定运行的优势非常明显。
6. 常见问题与故障排查速查表
这一节是我把这几年在嵌入式温度采集和 HVAC 远程监控项目里积累的常见问题集中整理一下,格式做成了速查表,方便你在现场快速对照定位。
| 故障现象 | 大概率原因 | 排查手段 |
|---|---|---|
| 所有通道读值都是 85℃ | 传感器上电复位异常,或者总线短路拉低 | 检查供电和上拉电阻,重新上电,再看是否恢复 |
| 单个通道读值随机跳变 | 接头氧化或线缆接触不良 | 重插接头,拧紧螺丝,检查屏蔽层接地 |
| 读值整体偏大或偏小 | 传感器标定偏差或探头安装位置不当 | 在 0℃ 冰水混合物中校准,检查探头散热环境 |
| 单总线枚举只能发现一半设备 | 上拉电阻过小,某些设备驱动能力不足 | 更换合适阻值上拉,测试线缆长度 |
| MQTT 频繁掉线 | 网络不稳或 keepalive 参数过小 | 增大 keepalive,检查网线质量和 PHY 通讯 |
| 同一数据既本地正常又远程异常 | 数据打包格式不一致或字节序问题 | 在 MCU 端打印原始帧,对比云端解析结果 |
| 长时间运行后采集周期变慢 | 内存泄漏或任务优先级问题 | 用 RTOS 任务栈检测工具,查看堆栈使用率 |
排查时的第一原则是从物理层往上层查。先看传感器供电是否正常,信号线上电平时序是否满足要求,再查协议层和网络层。很多人上来先怀疑代码,结果折腾半天发现是端子松了,这类教训我经历过太多次。
另外一个高频问题:单总线时序对中断响应有干扰。如果你开着高频率的定时器中断,单总线的微秒级延时可能被中断打断,导致读出错误数据。解决方法是把单总线数据读取放在高优先级任务里,或者在进行单总线通信时暂时屏蔽低优先级中断。我实际测试下来,用 F722 的定时器通道来做单总线时序,配合 DMA 读取,稳定性最好,但这个方案比较复杂,适合产品化场景。
7. 一些赶工期的实用经验
说点题外话,也是实操里最容易让人加班的部分。
第一,PCB 布局时务必把传感器接口放在板边。这个决定能省很多事。温度探头线缆要接到外面,接头必须在板边才方便走线。我见过有人把接口放在 PCB 中间,结果整机结构上没法出线,最后只能飞线加转接板,既丑又不可靠。
第二,硬件调试时先把单总线读温度跑通再搞网络。很多人习惯先把 MQTT 架起来,结果物理层有问题,温度数据全是乱码,这时候你根本分不清是网络问题还是上游采集问题。先本地串口打印读到的温度,确认数据稳定了,再接入网络协议栈,问题会简单得多。我在项目里一直坚持这个顺序,调试效率提升非常明显。
第三,软件代码里把版本号写进日志或 MQTT 消息。设备远端升级后,你得能看出它跑的是哪个版本,否则排查问题时连“这个设备有没有新固件”都搞不清。我现在的习惯是在启动时把 firmware_version 字段通过 MQTT 上报一遍,之后每次数据帧里也带上版本号,这样远端的监控平台能直接区分新旧设备。
第四,给温度数据加上符号位处理。有些地区冬天会出现 0℃ 以下温度,PJ85718DM 的温度寄存器有符号整数格式。如果你忘了处理符号位,负温会读成 200℃ 以上的正温,这在制冷场景里很容易被忽视。我在代码里专门写了一个函数处理补码转有符号数值,每一步都用串口打印验证过,这块细节千万别跳。
从我的整体体感来看,PJ85718DM + STM32F722VE 这套组合并不算最便宜的方案,但它胜在容错率高、调试周期短、后续扩展空间大。单总线传感器的布线简单,F722 的算力和网络能力又给将来加功能留了余量。如果项目预算允许,我建议你在早期设计时直接按这套组合做,而不是在低成本方案上反复试验。等到真上了产线、跑到现场,再去折腾传感器协议兼容或网络稳定性,代价远比做好初始选型要高得多。