☰
基于PIC18F97J60与PJ85718DM的嵌入式远程温度监测系统设计
2026/10/22 12:17:25 网站建设 项目流程

前阵子给一个机房暖通改造项目做温度监测,工期紧、预算也压得比较死,还要同时满足现场值班人员的本地查看和运维中心的远程集中监管。最后打磨下来,选定了 PJ85718DM 测温采集模块加 PIC18F97J60 这颗自带以太网 MAC/PHY 的 MCU 组合,一套硬件同时打通“本地显示 + 远程网络访问”两条链路。今天把从需求分析、硬件设计到固件联调的全过程记录下来,适合正在做嵌入式温控、HVAC 工程改造、机房环境监控以及远程数据采集这类项目的朋友参考。文中涉及的调试细节和踩坑记录,都是实际动手时才碰得到的东西,希望能帮大家少走弯路。

1. 先看清需求:这套温控监测到底要解决什么问题

1.1 HVAC 现场的温度监测为什么难做

HVAC 场景和一般桌面级开发板玩测温完全是两码事。普通嵌入式项目测一个点、看一个串口就够了,工程现场面对的往往是十几个、甚至几十个温度点,分布在风管、回水管、机房角落、设备层等完全不同的物理位置。

走线距离一长,温度传感器的信号就会出各种幺蛾子;现场还有变频器、压缩机、交流接触器这些大功率干扰源,一个处理不好,读数跳来跳去,系统根本没法用。而真正让人头疼的不只是测到温度,而是“测到了之后给谁看”。

现场运维人员需要的,是站在设备旁边就能看到当前温度、能判断这路传感器是否正常;远程运维中心需要的,则是坐在办公室里就能批量看到所有点位温度、能异常告警、能做趋势记录。很多项目的失败,不在于测温本身,而在于这两套需求没有同时考虑周详。

1.2 为什么选“前端采集模块 + 带以太网 MCU”的组合

传统做法我也用过:PLC 加模拟量输入模块,测温点接 PT100 或者 4-20mA 变送器。稳定是稳定,但一套下来光硬件成本就相当可观,而且编程环境封闭,数据要上传给别的系统时,通信协议还得小心翼翼地和第三方掰扯。

后来在几个成本敏感的项目里,我重新梳理了需求,把方案固定成“分立式前端采集 + 轻量级网络汇聚”的结构:

  • 前端用 PJ85718DM 这类测温采集模块,它把传感器探头、信号调理、模数转换、通信接口集成在一小块板上,MCU 直接以数字量方式读温度,省掉了自己搭模拟放大电路的标定和温漂烦恼;
  • 网络汇聚端用 PIC18F97J60,这颗 8 位 MCU 内部直接集成了以太网 MAC 和 PHY,外围只需要一个网络变压器和 RJ45 座就能接入以太网,成本比一个独立以太网控制芯片加一片主控 MCU 的方案低得多。

实际对比下来,这套组合在 14 个测温点的项目里,硬件成本大概是传统 PLC 方案的 30% 左右,开发周期也显著缩短。最关键的是,本地通道和远程通道是在同一颗 MCU 上并行处理的,现场数据一边刷新到显示屏或串口,一边打包成网络报文供远程读取,逻辑上非常顺。

2. 硬件搭建:PJ85718DM 与 PIC18F97J60 的配合细节

2.1 PJ85718DM 这类测温模块的接入思路

先说清楚,PJ85718DM 这种“即插即用”的测温采集模块,不同厂商出的东西引脚定义差别很大,有的是单总线接口,有的是 I2C,有的直接输出 4-20mA,所以拿到模块之后第一件事永远是查手册确认引脚,千万别凭经验直接接线。

我这次用的模块是单总线式接口,核心接法如下:

模块引脚接到 PIC18F97J60说明
VCC3.3V 电源模块供电,注意部分模块支持 5V,要看清手冊
GND公共地与 MCU 共地,不能省
DQRD0单总线数据线,必需接 4.7kΩ 上拉电阻
外壳屏蔽层单端接 GND探头线是屏蔽线时,屏蔽层只在 MCU 端接地

单总线上拉电阻是一个非常容易被忽视的点。短线连接时 4.7kΩ 没什么问题,但 HVAC 现场传感器探头经常要拉出去十几米甚至几十米,总线电容变大、上拉电阻太大时信号上升沿会变钝,导致通信时序失败。我的做法是:短线用 4.7kΩ,超过 10 米时改用 2.2kΩ,并且把通信波特率适当调低。这个经验值是基于常见实践的补充,具体还是要看模块手册的电气参数。

如果项目里测温点不止一个,PJ85718DM 这种单总线架构还有一个天然优势:每个模块有独立的 64 位序列号,可以在同一条总线上挂多个探头,MCU 用 ROM 指令逐个点名读取。我在项目里 14 个测温点分成两条总线,每条 7 个点,均摊了总线负载,也避免一条线拉得过长。

2.2 PIC18F97J60 的资源与接口设计

PIC18F97J60 这颗芯片,关键点在于“内置以太网 MAC 和 PHY”。对搞嵌入式的朋友来说,这意味着不需要外接一个独立以太网芯片,也不用在两颗芯片之间做 SPI 或并行总线通信,主控直接通过内部寄存器访问网络外设即可。

硬件资源上,它有大约 80KB 的 Flash 和接近 4KB 的 RAM,对于跑一个轻量级 TCP/IP 协议栈、同时处理少量传感器数据来说完全够用。IO 口也比较充裕,除了接传感器总线,还能带一个本地显示模块、几个按键和一个蜂鸣器。

网络部分的电路,我直接说一下成熟做法:PIC18F97J60 的以太网差分信号线接到一个隔离变压器,然后到 RJ45 座。差分对要做等长走线,变压器中心抽头按照器件手册的推荐电路接上拉电阻和电容,保证共模电平正确。RJ45 选带变压器一体式的座子,可以省不少布线空间,也少了很多焊接隐患。

为了方便现场维护,我还留了一路 SPI 接口,用来接一个 MicroSD 卡座,后续做本地温度记录用。整体硬件结构上,我刻意按“采集板 + 核心板 + 显示板”的模块化思路分了三块独立小板,中间用排针连接,这样调试时哪块出问题可以直接拆下来换,不用整机返工。

2.3 电源方案和布线里最容易忽略的三件事

HVAC 现场和实验室最大的不同,是电源环境比较脏,而且常用的不是 5V USB 供电,而是 24V 交流或直流电源。直接从 24V 取电给 MCU 的话,必须先从整流滤波开始处理:

  • 如果是 24VAC,先用整流桥整流,加大电容滤波,再接一颗稳压芯片降到 5V,最后用低压差线性稳压器稳定到 3.3V 给 MCU 和模块供电;
  • 如果是 24VDC,也要加反向保护二极管,防止现场接错极性直接烧板子;
  • 在靠近 MCU 电源引脚处,每一对 VCC/GND 都要放 100nF 去耦电容,靠近网络变压器供电脚还得放一个 10μF 电解电容,这是网络通信稳定性的基本保障。

另外三件事是我吃过亏后总结出来的,值得重点说:

  1. 传感器线和动力线绝对不能扎在一起走长距离。我曾在项目里为了省一根线槽,把传感器线跟 380V 动力线并排走了 20 米,结果温度读数每隔几秒钟就跳一次,排查了两天才发现根因,后来全部改走独立线槽,问题才消失。
  2. MCU 地和传感器地必须单点或星型接地,避免形成地环路。现场多点接地会让地电位差变成干扰信号,直接打在传感器线上。
  3. 要给每个 PJ85718DM 模块加一个 100nF 陶瓷电容,放在模块供电引脚附近。模块和 MCU 之间距离稍远时,供电线上的电感会因为数字信号切换引起瞬态跌落,这个电容能有效缓冲。

3. 固件侧的核心实现:读温度、组报文、开放远程访问

3.1 温度数据读取与异常过滤

固件工程上,我以“10ms 定时中断作为全局心跳”的方式来组织程序。主循环里跑网络协议栈,定时中断里做数据采集和标志置位,这样网络收发不会因为耗时较长的传感器读取而被长时间阻塞。

PJ85718DM 的读取逻辑大概是这样(以单总线为例):

// 读取一路温度值,成功返回1,失败返回0 uint8_t read_temperature(int16_t *temperature) { // 跳过 ROM 匹配(单探针场景),发起温度转换 onewire_reset(); onewire_write_byte(0xCC); onewire_write_byte(0x44); // 等待转换完成,一般需要几十毫秒 delay_ms(80); // 读取暂存器,共 9 个字节 onewire_reset(); onewire_write_byte(0xCC); onewire_write_byte(0xBE); uint8_t temp_lsb = onewire_read_byte(); uint8_t temp_msb = onewire_read_byte(); // 校验:读取 CRC 并验证,CRC 失败则返回错误 uint8_t crc = onewire_read_byte(); if (crc != calculate_crc8(temp_lsb, temp_msb)) { return 0; } *temperature = (int16_t)((temp_msb << 8) | temp_lsb); return 1; }

读取到的原始数据换算成摄氏度时,要注意模块的分辨率配置。常见配置下分辨率是 12 位,即 LSB 代表 0.0625℃,但这个 12 位不是配置项而是出厂设定,具体要对照模块手册。换算公式是温度 = 原始值 * 0.0625,负温度则要按补码处理。

MCU 内部维护一个全局的temp_table[14]数组,每 500ms 轮巡一次全部 14 个点。每次轮巡后做一次“去极值滑动平均”:取最近 5 次数据,去掉一个最高值和一个最低值,剩下 3 个求平均。这个做法对付现场随机毛刺非常有效,代价只有几行代码,比重做大复杂度滤波算法划算得多。

轮巡时还要记一个失败计数。连续 3 次读取失败,我就判定这个探头“断线”或“损坏”,在数组中写入一个特殊值 0x7FFF,后续的显示和网络输出都能针对这个值做告警处理。

3.2 给本地上位机用的串口和显示通道

本地通道我做了两个出口:一个是物理的串口,另一个是可选的 LCD 显示屏。

串口走的是简单文本帧,方便现场工程师拿串口助手直接看:

SN01:23.4C SN02:22.1C SN03:ERR ...

帧头不用复杂的协议校验,因为本地串口主要用于调试和临时连接,远程数据可靠性交给网络层去保证。串口波特率固定 115200,每 2 秒打印一轮所有点的温度,异常点直接输出 “ERR”。这样现场人员只要带个笔记本打开串口助手,就知道哪一路传感器出了问题。

LCD 显示我用的是 128x64 点阵屏,分成两页,每页显示 7 个点的温度。持续按住按键 2 秒可以切换显示页,这样 14 个点都能在本地看到。刷新逻辑放在主循环中,每 500ms 刷新一次,不在定时中断里做耗时的刷屏操作,避免拖累网络协议栈的中断响应。显示缓冲区是独立的内存区域,刷屏过程中再插入一次新的温度更新也不会乱。

线路上有一个很重要的细节:LCD 刷新这类耗时操作放在网卡数据包收发的空闲时段执行。因为 PIC18F97J60 的 RAM 资源不算宽裕,网络缓冲区必须保证不被其他任务拖得太久,否则路由器会认为设备异常,直接把 ARP 表项踢掉,然后就是莫名其妙地掉线重连。

3.3 HTTP 页面与 Modbus TCP 双通道远程服务

远程访问我用的是芯片原厂随协议栈一起提供的 TCP/IP 库,它内置了 ARP、IP、ICMP、TCP、UDP 等基础协议。工程配置时只需要重点关注几个参数:

配置项本项目取值说明
MAC 地址00:04:A3:xx:xx:xx用厂商 OUI 段,避免和现场其他设备冲突
IP 地址192.168.1.200静态分配,简化现场部署
子网掩码255.255.255.0常规局域网配置
网关192.168.1.1跨网段访问时需要
最大 TCP 连接数4网页和 Modbus 同时服务够用

上面地址只是示例,实际部署时按照自己现场网段规划设置即可。

远程服务的第一个通道是 HTTP 网页。协议栈收到浏览器的 GET 请求后,会回调到我们注册的动态页面处理函数,在这里我动态拼接 HTML 字符串,把temp_table里的 14 个温度点逐行嵌进表格。页面里传感器状态分了三种颜色:正常显示黑色、越限显示红色、断线显示灰色。远程运维人员打开浏览器直接输入 IP 地址就能看到全站所有点位的温度状态,无需任何客户端软件。

第二个通道是 Modbus TCP,这个是给上位机或 SCADA 系统用的。我把每个测温点映射为一个保持寄存器,寄存器地址从 0x0000 开始,先存温度值(乘以 10 取整,保留一位小数),再在下一个寄存器存状态字。Modbus 从站逻辑直接在原厂协议栈的 TCP 回调之上开发,监听 502 端口,收到请求后解析功能码、检查地址范围、从全局温度表取数,然后组响应帧返回。

支持的功能码我只开了三个:读保持寄存器 0x03、写单个寄存器 0x06、读设备标识 0x2B。功能码越少,出错概率越低,这是工控现场的一个基本守则。实测下来,上位机通过标准的 Modbus 调试工具连接,轮询周期设为 500ms,跑一整夜没丢过一帧数据。

4. 双通道联调:本地显示与远程访问一起跑通的验证方法

4.1 本地通道的验证步骤

联调第一步是先不管网络,把本地链路完全打通。我接上 PJ85718DM 模块后,先用串口助手观察原始数据是否正常输出。注意一个很容易搞混的点:刚上电时模块要等大约 750ms 的复位时间,过早发送指令只会得到无响应,这不是器件坏掉了,而是时序没给够。

串口数据稳定后,再用 LCD 显示做交叉验证。拿一个经过校验的工业水银温度计,和探头放在同一个恒温块里对比温度读数。如果误差偏大,先查模块配置里的传感器偏移量寄存器,做一阶校准:校正后温度 = 原始读数 + 偏移值。我这边 14 个探头逐个校验,正常都在 ±0.3℃ 以内,个别偏差大的用偏移值修正到 ±0.2℃。

本地通道还有一个测试技巧:用手反复握紧探头再松开,观察显示数值能否快速跟随变化。这个动作能同时验证传感器的响应速度和滤波算法是否过度滞后。去极值滑动平均如果窗口开得太大,温度会显得“肉”,迟钝得让人难受;窗口太小又滤不掉毛刺。我在 14 个点位的现场试验中最终选中了 5 点去极值平均,滞后时间约 2 秒,既能稳定显示又不会明显影响体感判断。

4.2 远程通道的验证步骤

远程通道路径是:PIC18F97J60 的以太网口接交换机 → 电脑接同一个交换机 → 浏览器访问 192.168.1.200。第一步先 ping 设备 IP,能通说明 ARP 和 ICMP 已经正常;ping 不通的时候,优先检查网线是否插到绿灯亮、设备是否获得正确 IP。

然后浏览器打开设备 IP,能看到一个很朴素的 HTML 温度表。这时刷新页面,观察每个点的值是否和本地 LCD 一致。两边数据如果对得上,说明本地采集和网络取数共用的是同一个temp_table,数据一致性没有问题。

Modbus TCP 验证我用了一个网络调试助手,手动组协议报文测试。读取保持寄存器的请求帧大致是:

事务标识符: 00 01 协议标识符: 00 00 长度: 00 06 单元标识符: FF 功能码: 03 起始地址: 00 00 寄存器数量: 00 1C

对应响应里,长度字段减去 3 后除以 2,就是返回的寄存器个数。读取结果和网页显示的数值逐一比对,验证协议解析是否正确。特别要注意字节序,有一部分上位机是大端模式,一部分走小端,我在这上面翻过一次车——本来温度应该是 23.4℃(寄存器值 0x00EA),解析出来却成了 0xEA00 也就是 59904,明显不合理。后来在固件端统一按 “高字节在前” 输出,并且在文档里写清楚,问题才彻底解决。

4.3 联调中出现的三个典型问题和处理记录

第一个是网络反复掉线。设备接入路由器一小时后失联,但本地串口一切正常。排查下来发现是 DHCP 租约到期后没有续期成功——设备当时用的是 DHCP 动态分配,而现场路由器 DHCP 服务不稳定。后来改成静态 IP 配置,问题消失。这种情况在工程现场很典型,工控设备尽量少依赖动态地址分配。

第二个是温度曲线偶发跳变。同一个点每隔一两分钟会蹦出一个完全不合理的值,比如 85℃。排查后发现是这个点位的 PJ85718DM 模块供电线太长,模块瞬间电流导致电压跌落,读回的数据 CRC 出错。我在模块端加了一颗 100μF 电电容,再把读取失败重试次数从 1 次改成 3 次,跳变彻底消失。

第三个是浏览器访问页面时设备卡死。复现后发现是 HTTP 长连接没有及时关闭,TCP 连接被占满后,其他协议请求就进不来了。解决办法是在网页响应头中显式标明Connection: close,同时把最大 TCP 连接数从默认值改成 4,并在连接空闲超时 30 秒后主动断开。改完之后,手机、电脑、上位机三路同时访问,设备也稳如泰山。

5. 在 HVAC 现场部署后的复盘与扩展

5.1 现场干扰、长线和电源问题复盘

设备完整跑了一个夏天,经历了几轮压缩机启停和变频器满负荷运行,说几个现场暴露出来的真实问题。

传感器线最开始用的屏蔽双绞线,屏蔽层只在 MCU 端接地,这个做法是对的。但后来有一路传感器因为施工队改了路径,有一段和变频器输出电缆并行走了约 6 米,温度读数瞬间变得不稳定。我重新规划走线,把传感器线绕开变频器电缆,恢复屏蔽层单端接地后读数立刻稳定。所以现场施工的走线路径,比选什么高级屏蔽线更关键。

电源方面也遇到过一次隐患。24V 供电链路中稳压芯片前面的滤波电容容值偏小,在压缩机启动瞬间,电网电压瞬跌导致 3.3V 出现短时跌落,网络模块偶发数据随机复位。解决办法是加大前级储能电容容值,并且在稳压芯片输入端串了一个小电感,构成简单 LC 滤波,吸收瞬态尖峰。这之后设备经历了多次压缩机启停,都平稳度过。

5.2 温度告警与断线检测的价值

HVAC 项目里,热异常往往不是第一个发生的故障,而是某个设备失效后的结果,所以温度监测系统必须连带做告警判断。

我在阈值设置上留了四组参数:低温告警、低温解除、高温解除、高温告警,避免温度在两个阈值边缘反复跳动导致告警抖动。每路传感器独立配置阈值,比如机房环境温度设在 28℃ 告警,冷却水供回水温度则按具体工艺设定。本地用 LED 闪烁加蜂鸣器提示,远程网页用红色标记,Modbus 状态字里每个传感器用两个 bit 表示“越限”和“断线”状态。运维中心拿到状态字后,可以精确知道哪一路探头出了问题,而不是等到设备故障了才发现。

断线检测的实用价值在于感知“传感器本身坏了”和“温度真的异常”之间的区别。PJ85718DM 的 CRC 校验机制天然支持这个功能:连续读取失败三次,模块就标记为断线,显示层输出 “ERR”,网络层返回一个特殊状态位。现场维护人员看到后直接检查探头线和接插件即可,不用猜测系统是否死机。

5.3 后续扩展的几个方向

这套结构跑顺之后,扩展方向其实很清晰。

如果项目后期测温点数量超过单网关容量,可以部署多台 PIC18F97J60 网关,每台负责一段区域,上位机通过 Modbus TCP 逐台轮询。因为每台都是独立 IP,扩容只是增加设备数量,不用改动原有节点。唯一要做的是合理规划 IP 地址段和传感器地址编号,并做成一张点位表,方便后期运维定位。

如果客户后续要求远程手机查看,有两种省力路径:一种是在网关后面加一台 Linux 边缘盒子,把 Modbus TCP 数据采集上来转存数据库,再对接现有的监控平台;另一种是选带 Wi-Fi 功能的透传模块,将网页直接映射到云端。这里要特别提醒,凡是涉及公网访问的部分,都必须做好设备认证、数据加密和访问控制,确保系统在网络安全边界内运行。

数据记录方面,后期我用 SPI 接口接了一个 MicroSD 卡,每 5 分钟把 14 个温度点写入一个 CSV 文件,保存最近半年的历史数据。这个功能对 HVAC 系统特别有价值,因为设备故障往往是个缓慢退化过程,长期温度趋势能反映出换热器结垢、风机效率下降等隐蔽问题。数据记录不占网络带宽,也不受网络断线影响,属于低成本高回报的扩展。

另外,如果产品要批量复制,网关的配置信息(IP、传感器编号、阈值)建议做成一个配置文件放在 SD 卡上,上电时 MCU 读取配置。这样现场安装时不用修改固件,只需要准备对应项目的配置文件即可。我这次还是直接把配置写死在固件里,一两个项目无所谓,真要量产的话这是第一件要改掉的事情。

最后说一个和我个人习惯有关的建议:凡是这样的小批量自研设备,我会在出厂前给每台设备预留一小时的连续网络 ping 测试和温度数据稳定性观察,确认网络丢包率为零、温度曲线平滑后再交付现场。这比现场出问题再跑一趟省心太多。设备安装完成后,把所有网线的插头固定处打上标签,标注对应 IP 和传感器编号。这一点在后期维护里救了我好几次命。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询