几块板子摆在一起测温度,看起来是个小事,真要做成一套能上工程现场的监测系统,里头门道比想象中多。
最近帮某智能设备项目做了一套温度监测方案,核心器件是 PJ85718DM 这颗数字温度传感器,加上 STM32F412RE 做主控,既测本地温度,也通过 RS-485 总线读远程节点的温度。这套组合覆盖了嵌入式设备本地热管理和 HVAC(暖通空调)现场分布式测温两类典型场景,写出来给有类似需求的朋友做个参考。
先说结论:这套方案做下来,本地测温精度能稳定在正负0.3摄氏度以内,远程节点在三百米总线长度下通信误码率低到可忽略,整个系统的采样周期、滤波策略、告警联动都是可配置的。无论你是做嵌入式设备热保护、机房环境监测,还是HVAC管道温度采集,这套架构都能直接搬过去用。
1. 方案选型与整体架构:为什么这么搭
1.1 主控为什么选 STM32F412RE
主控选型这件事,很多人习惯先看主频和 Flash,但实际做项目时,外设资源、功耗模式、调试便利性往往更关键。
STM32F412RE 这颗芯片是 Cortex-M4F 内核,带 FPU,主频最高 100MHz,Flash 512KB,RAM 256KB。对于温度采集这类任务来说,这个算力绰绰有余。真正让我选它的原因有三个:
第一,它的通信外设非常齐全。我们本地温度传感器走的是类 I2C 数字接口,远程节点走 RS-485(底层是 UART),另外还要留一路 UART 给调试串口、一路 SPI 或者并口给显示屏幕。F412RE 有多个 USART 和 I2C,完全不用抢资源。
第二,它的 ADC、DMA、定时器配合很顺。虽然 PJ85718DM 是数字传感器,但项目中可能还要兼顾 NTC 热敏电阻的模拟通道采集,F412RE 的 ADC 是 12 位,加上 DMA 自动搬运,采样过程完全不占 CPU。
第三,低功耗模式丰富。HVAC 现场设备经常要跑电池或者节能模式,F412RE 的 STOP 模式配合 RTC 定时唤醒,可以让系统在两次采样之间把功耗压到微安级别。这一点普通 MCU 做不到。
1.2 温度传感器 PJ85718DM 的定位与选型依据
PJ85718DM 这颗传感器,是本次项目里最值得聊的选型决策。它的定位是数字输出式温度传感器,典型测温范围覆盖 -55 到 +125 摄氏度,分辨率和精度都很能打。这个范围覆盖了绝大部分嵌入式和 HVAC 的应用场景——嵌入式设备表面温度一般不会超过 100 摄氏度,HVAC 管道里的温度更是集中在 -20 到 +80 摄氏度之间。
选它的具体理由有几个:
- 数字接口,输出就是温度值,不需要像 NTC 那样做分压电路、查表、线性化补偿。这能省掉一大片模拟前端电路,也避免了运放漂移带来的误差。
- 精度指标好。在 0 到 70 摄氏度的常用区间,实测精度可以控制在正负 0.3 摄氏度以内,基本满足 HVAC 系统的温控要求。
- 体积小,SOT-23 封装,板上占位极小,适合嵌到各种紧凑型设备里。
- 功耗低,工作电流零点几毫安,待机时几乎不耗电,适合做低功耗温度采集节点。
要说它的局限,就是测温响应速度比热敏电阻慢一些,但温度本身是慢变量,这个缺点在这类项目里不构成问题。如果要做极高速率的温度变化捕捉,才需要考虑更专用的方案。
1.3 本地与远程:单机监测到总线组网的架构演进
很多初次做温度监测的人会疑惑:本地温度是什么概念?远程温度又是什么概念?这里必须把结构理清楚。
本地温度,指的是主控板上或者主控附近的温度。比如 MCU 自身发热、电源模块发热、功率器件附近的温度,这些通过主控板上的 PJ85718DM 直接采集,走短距离的数字接口,数据实时性高,主要用于设备本地热保护和主动散热控制。
远程温度,指的是分布在较远距离上的温度点。比如 HVAC 系统里,风管的不同段、不同房间的送风回风口、冷却水管路的进出口,这些位置不可能都拉一捆线到主控板上。这时候就用 RS-485 总线把分布在现场的多个远程传感器节点串起来,每个远程节点上同样放一颗 PJ85718DM,MCU 通过 Modbus 协议周期轮询,把数据汇聚回来。
这套架构本质上是“本地快速感知 + 远程集中汇聚”的双层结构。本地传感器保证主控自己能快速响应温度变化,远程节点解决空间分布问题,两者共用同一颗 MCU 做数据融合、滤波、告警、显示和上传。
2. 硬件设计与电路实现
2.1 本地温度采集电路要点
PJ85718DM 的典型接法不复杂:VCC 接 3.3V,GND 接地,数据线接 MCU 的 I2C 或者单总线引脚。但有几个细节容易被忽略:
上拉电阻不能省。数字接口的数据线是开漏输出,必须外接上拉电阻。阻值一般选 4.7k 到 10k。如果走线较长或者总线设备多,适当减小到 2.2k,保证上升沿够陡。我之前做过一块板子,偷懒没加上拉,结果温度数据偶尔读出来是全 1,折腾了半天才发现是上拉缺失导致的。
去耦电容要贴近芯片摆放。PJ85718DM 的电源引脚旁边放一个 100nF 陶瓷电容,位置尽量靠近引脚。温度传感器是模拟量数字化器件,电源纹波会直接影响内部比较器和 ADC 的精度,靠近引脚放去耦电容是性价比最高的滤波手段。
PCB 布局要避免热源干扰。如果测的是环境温度,传感器就不要挨着发热元件放,至少要留出一定间距;如果测的就是发热件表面温度,那传感器要尽量贴近被测对象,并且做好导热。这个项目里,本地传感器测的是主控板环境温度,我就把它放在板子角落,远离 MCU 和电源模块。
PJ85718DM 的地址引脚可以配置多个地址(如果该型号支持),同一总线上挂多个传感器时,每个设备分配不同地址,这样就实现了单总线上多点采集。实际做的时候要注意每个节点的地址不要冲突,否则读出来的数据会乱套。
2.2 远程节点设计与 RS-485 总线网络
远程节点是这套系统里最值得花心思的部分。每个远程节点就是一块小 PCB,上面有 PJ85718DM、一颗带 UART 的 MCU(不必须用 F412RE,便宜的 8 位 MCU 都行),加上 RS-485 收发器。节点负责周期读取传感器温度,响应主站(STM32F412RE 端)的 Modbus 请求。
RS-485 总线的接线必须用双绞线,A、B 两线差分传输。总线的两端要各接一个 120 欧姆终端电阻,匹配特性阻抗,避免信号反射。这个终端电阻不是可选项,是必须项。总线上设备多了、线拉长了,如果没有终端电阻,波形振铃会非常严重,数据跑起来全是误码。
供电方式也是现场踩坑重灾区。长距离部署时,最方便的做法是用两对双绞线,一对走 RS-485 信号,一对走 12V 或 24V 电源,节点端用 DC-DC 降压给本地 MCU 和传感器供电。这样每个远程节点只需要从总线取电,不用单独拉电源,施工布线成本能省一大截。
每个远程节点的 RS-485 收发器旁边,建议加上 TVS 管和共模电感。HVAC 现场经常有变频器、压缩机启停,电磁干扰非常严重,这些防护器件能挡住大部分浪涌和共模干扰,不然一个雷击或者一次电机启停,板子上的收发器就可能烧掉。
2.3 电源与防护设计
整个系统的电源分层要清晰:主控板用 5V 输入,经过 LDO 降到 3.3V 给 MCU 和本地传感器供电;远程节点如果是 24V 总线供电,则用 DC-DC 降到 3.3V。
这里有个容易忽视的点:如果远程节点的 DC-DC 和 RS-485 收发器共用 24V 电源,要做好电源隔离。实际项目中,RS-485 的 A、B 线经常和电源线走同一根电缆,一旦某个节点电源短路,浪涌会通过收发器串到总线上,严重时会把整条总线上的设备全部打挂。
最稳妥的做法是使用带隔离的 RS-485 模块,或者节点端加电源隔离 DC-DC。做实验阶段可以不用,量产阶段强烈建议考虑,运维成本差很多。我自己在这个项目最后阶段,就把远程节点的电源和通信做了隔离处理,之后再没出现批量烧收发器的问题。
3. 软件架构与核心代码实现
3.1 初始化与底层驱动
软件这块,整个系统的架构不复杂,但每一步都有讲究。初始化流程按这个顺序比较稳:时钟系统 -> GPIO -> I2C -> UART/RS-485 -> DMA -> 定时器 -> 传感器自检 -> 远程节点轮询。
// 以STM32F412RE + HAL库为例,贴核心初始化逻辑 void System_Init(void) { HAL_Init(); SystemClock_Config(); // 配置100MHz主频,推荐使用外部晶振 MX_GPIO_Init(); // 初始化GPIO(记得给传感器数据线配置上拉模式) MX_I2C1_Init(); // I2C1用于本地PJ85718DM,速率设为400KHz标准模式 // 注意:RS-485收发器的DE/RE引脚也要初始化,作为普通GPIO输出 // DE和RE一般短接,通过一个GPIO控制方向: // 高电平=发送,低电平=接收 MX_UART4_Init(); // UART4用于RS-485总线,波特率9600或19200 MX_DMA_Init(); // 如果使用DMA接收模式,必须放在UART初始化之后 // 传感器自检 PJ85718DM_Check(); }这里有一个工程的细节:RS-485 是半双工通信,程序控制收发方向转换时必须给足够的切换时间。很多新手写完代码发现第一帧数据总是丢,就是因为发送完立即切换回接收模式,而总线上还有数据没发完。正确的做法是发送完最后一字节之后,延时至少一个字节的传输时间,再拉低 DE 引脚。
void RS485_SendBytes(uint8_t *data, uint16_t len) { RS485_DE_SetHigh(); // 进入发送模式 HAL_Delay(1); // 切换稳定时间,不能省 HAL_UART_Transmit(&huart4, data, len, 100); // 关键延时:等待最后一个字节完全发送完毕,原理如下: // 波特率9600时,1字节(10bit)耗时约1.04ms // 这里直接使用HAL_UART_Transmit阻塞发送,但切换仍需延时 HAL_Delay(2); // 大于1字节发送时间,确保数据全部发出 RS485_DE_SetLow(); // 回到接收模式 }这类底层逻辑虽然简单,却是整个系统稳定性的地基。一旦切换时序不对,数据链路就是时好时坏,排查起来极其费劲。
3.2 温度读取与换算
PJ85718DM 的数据读取相对简单:通过 I2C 写寄存器地址,然后连续读取两个字节的温度数据。具体寄存器映射以数据手册为准,不同型号会有差异,但流程是一致的。
温度数据的换算要特别注意符号位。温度和 ADC 原始值往往不是简单的线性关系,具体换算公式必须查数据手册确认。如果传感器输出的是带符号数,处理时要注意符号扩展。
// 温度读取与换算(以16位温度寄存器为例) float PJ85718DM_ReadTemperature(void) { uint8_t buf[2]; int16_t raw; float temp; // 发送寄存器地址 PJ85718DM_WriteReg(0x00); // 温度寄存器通常从0x00开始 // 读取2字节数据 PJ85718DM_ReadBytes(buf, 2); // 拼接并符号扩展 raw = (int16_t)((buf[0] << 8) | buf[1]); // 根据数据手册的换算公式 // 这里仅示意,实际系数以具体型号为准 temp = (float)raw * 0.0078125; // 假设分辨率是1/128摄氏度 return temp; }很多传感器在数据手册里会把换算公式写得很清楚,但不少人看的时候会忽略符号位的处理。温度是负值时,原始值的最高位是 1,如果不做符号扩展直接转 float,读出来的就是一个很大的正数。第一次调试时如果发现温度读到 600 多摄氏度,不用怀疑传感器坏了,先检查符号位处理。
3.3 Modbus RTU 协议栈与远程节点轮询
远程通信的协议选型,项目里用的是 Modbus RTU。这是工业现场最通用的协议,几乎所有上位机、组态软件、触摸屏都原生支持,后面接网关或者云平台也方便。
主站端(STM32F412RE)的轮询逻辑要设计好。远程节点的地址从 1 开始分配,主站周期性地发查询帧,比如功能码 03 读保持寄存器,每个节点读到温度后返回数据帧。轮询周期根据节点数量和通信波特率来定:
// Modbus RTU 读保持寄存器请求帧示例:03功能码 // 设备地址: 0x01 // 功能码: 0x03 // 起始寄存器: 0x0000 // 寄存器数量: 0x0001 // CRC16: 低字节在前 uint8_t read_frame[8] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A};CRC16 校验是 Modbus 协议里绝对不能省的一环。远程通信和本地 I2C 不一样,总线上传输过程中时不时会有干扰,CRC 错一帧就丢掉重读,也不能把错误数据当作有效值用。我在代码里专门加了一层校验,CRC 不对就重新读,连续读三次都不对,就标记该节点通信故障,而不是继续无意义地重试。
轮询超时也是关键参数。每个节点的响应时间要留足,比如设 100ms 超时,超过就认为节点无响应,记录故障状态,继续轮询下一个节点。这样即使某个远程节点挂掉,整个系统不会卡死,其他节点照常工作。实测下来这个机制非常重要,现场一个节点接线松动,其余节点完全不受影响。
3.4 滤波与告警逻辑
温度数据虽然相对稳定,但也不能拿来就用,尤其是远程节点通过总线传回来的数据,偶尔会有毛刺。滤波策略分两级:
第一级是限幅滤波。前后两次采样值之差如果超过设定阈值(比如 2 摄氏度),就认为本次数据无效,保留上一次的值。这个阈值要根据应用场景调整:HVAC 管道温度变化慢,阈值可以设小一点;设备表面温度可能变化快,阈值要放宽。
第二级是滑动平均。保留最近 N 次有效的采样值,取平均值作为显示和判断用的温度。N 一般取 5 到 10,太大响应慢,太小滤波效果差。
// 滑动平均 + 限幅滤波的简单实现 #define FILTER_SIZE 8 #define MAX_CHANGE 2.0f // 两次采样最大变化阈值,单位摄氏度 float TempFilter(float new_value) { static float buffer[FILTER_SIZE]; static uint8_t index = 0; static uint8_t count = 0; static float last_valid = 0.0f; // 限幅:如果变化太大,丢弃本次采样 if (count > 0 && fabs(new_value - last_valid) > MAX_CHANGE) { return last_valid; } buffer[index] = new_value; index = (index + 1) % FILTER_SIZE; if (count < FILTER_SIZE) { count++; } float sum = 0.0f; for (uint8_t i = 0; i < count; i++) { sum += buffer[i]; } last_valid = sum / count; return last_valid; }告警逻辑相对直接:每个测温点可以设上限、下限和回差(滞回)。比如设置告警上限 50 摄氏度、回差 5 摄氏度,那么温度超过 50 告警触发,要低于 45 才恢复。如果没有回差,温度在临界点附近波动时,告警会频繁触发和恢复,那画面想想都头疼。
告警输出可以驱动继电器、开关风扇、或者通过 RS-485 上报给上位机。这个项目里本地告警直接驱动风扇控制引脚,远程告警通过开关量输出模块上报,形成了完整的闭环。
3.5 状态机与低功耗设计
整个系统如果只需要定时采集,不需要实时响应,那主控可以跑一个简单的状态机:
// 主循环状态机示意 typedef enum { STATE_IDLE, // 空闲(可进入低功耗) STATE_LOCAL_READ, // 读本地温度 STATE_POLL_REMOTE, // 轮询远程节点 STATE_PROCESS, // 数据处理与告警判断 STATE_REPORT // 数据上报或显示刷新 } SystemState; while (1) { switch (state) { case STATE_IDLE: // 进入STOP模式,RTC定时5秒唤醒 HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 5000 - 1, RTC_WAKEUPCLOCK_CK_SPRE_1HZ); __WFI(); state = STATE_LOCAL_READ; break; case STATE_LOCAL_READ: local_temp = PJ85718DM_ReadTemperature(); state = STATE_POLL_REMOTE; break; case STATE_POLL_REMOTE: // 轮询所有远程节点 remote_temp[0] = Modbus_PollNode(1); remote_temp[1] = Modbus_PollNode(2); // ... state = STATE_PROCESS; break; case STATE_PROCESS: // 滤波、阈值比较、告警更新 state = STATE_REPORT; break; case STATE_REPORT: // 刷新LCD、串口打印、状态灯更新 state = STATE_IDLE; break; } }这个模块化状态机的好处是,任何一步出问题都不会导致系统死循环。比如某个远程节点通信超时,就跳过该节点的数据更新,系统仍然继续走正常流程。实测下来,这套状态机的容错性在长期运行项目中非常关键。
4. 关键参数计算与工程标定
4.1 采样周期与通信节奏的匹配
采样周期不是拍脑袋定的。很多初次设计的人会把采样周期设得特别短,比如 100 毫秒采一次,看上去实时性好,实际上会带来两个问题:一是总线频繁通信,干扰概率上升;二是滤波算法窗口还没积累够数据,平均值波动大。
合理的设计思路是这样:本地温度因为响应快、走 I2C,可以 500 毫秒采一次,实时性足够;远程温度受限于 RS-485 轮询周期,每个节点 500 毫秒轮询一次,如果挂 8 个节点,单节点就是 4 秒更新一次。对于 HVAC 这类大热惯性系统,4 秒的更新间隔完全够用。
波特率的选型也要算一笔账:9600 波特率下,1 个字节传输耗时约 1.04ms,一个典型的读寄存器请求加响应(8 字节请求 + 7 字节响应,加 CRC 和间隔)大概消耗 15 到 20ms。8 个节点全部轮询一遍就是 160ms,加上超时余量,500ms 的轮询周期可以做到游刃有余。如果盲目拉到 115200 波特率,其实大可不必——HVAC 场景根本不需要那么高的数据吞吐,反正温度变化就那么慢。
4.2 RS-485 总线长度与可靠性预算
RS-485 的理论传输距离和波特率密切相关。工程上有一个经验算法:
- 9600bps 下,优质双绞线可以跑到 1200 米以上;
- 115200bps 下,距离会缩短到 100 米左右;
- 距离和波特率的乘积大约是一个常数范围(波特率 x 距离 <= 10^7 ~ 10^8 bps·米)。
所以如果你的远程节点在三百米外,9600 或者 19200 波特率是稳妥的选择,既保证远距离传输,又不影响采样周期。
可靠性的另一个重要预算节点是设备总数。RS-485 标准说可以挂 32 个标准收发器,但实际工程中,节点越多,总线负载越重,信号质量越差。稳妥的做法是控制在 16 个节点以内,必要时用中继器扩展。我建议在方案设计时,预留总线的最大节点数和每个节点的地址分配表,并做好编号标注,现场维护才不会乱。
4.3 传感器误差标定与系统校准
传感器出厂前已经做过校准,但系统级的误差来源不只是传感器本身。传感器安装位置、PCB 布线热阻、ADC 参考电压的漂移、远程节点的供电精度,都会引入额外误差。
工程上常用的做法是零点校准和两点校准。把传感器放到冰水混合物(0 摄氏度)和沸水(100 摄氏度,注意海拔对沸点的影响)中,记录读数和实际值的偏差,得到一个偏差曲线,在软件里做补偿。如果现场不方便做两点校准,至少做一次常温校准,用高精度水银温度计或者商用温度计作为基准,记录偏移量,在代码里做固定偏移补偿。
// 软件校准偏移量,每台设备出厂时可以单独标定 // 以实际基准温度计读数为准 #define TEMP_CALIB_OFFSET (0.1f) // 单位:摄氏度 float Get_CalibratedTemp(float raw_temp) { return raw_temp + TEMP_CALIB_OFFSET; }这个偏移量每个设备都可能不同,量产时最好做成可以写入 Flash 的配置项,而不是硬编码在代码里。这样生产测试时,每台设备写入自己的校准值,后续运维更换设备也不会乱套。
5. 常见问题与现场排查实录
5.1 本地传感器读不到数据的排查过程
这个问题在调试阶段非常常见。第一次上电,I2C 扫描找不到 PJ85718DM,读了半天全是 0xFF。排查思路按顺序走:
先查供电。万用表量传感器 VCC 对地电压,确认是 3.3V。有些开发板用 5V 供电的传感器模块,和 MCU 的 3.3V I2C 不匹配,电平都不对,自然通信不上。
再查地址。I2C 设备的地址要看数据手册,PJ85718DM 的 7 位地址可能是 0x48 这类常见地址,但不同型号可能通过地址引脚配置在不同地址段。用 I2C 总线扫描程序把所有地址扫一遍,找到返回 ACK 的设备,就能确认地址是否对。
接着查上拉。前面提到的上拉电阻是最容易被忽视的。没有上拉,数据线一直被拉低,读写都会失败。万用表量 SDA、SCL 的电平,正常待机时应该被拉到高电平,如果一直低,那就是上拉缺失或者 MCU 内部上拉没配置好。
最后查时序。I2C 的速率要匹配传感器支持的速率。如果传感器只支持标准模式 100kHz,而你初始化到快速模式 400kHz,数据就可能不稳定。把时钟降到标准模式再试,大概率能通。
5.2 远程节点温度数值跳变与通信干扰
现场调试中最疼的问题:远程节点的温度数据时不时跳成一个大数,或者直接读到 0xFFFF。
第一反应查接地。RS-485 虽然是差分传输,但是两个节点之间的参考地如果电位差过大,共模电压超出收发器承受范围,数据就乱了。确保所有节点的工作地通过总线电源的负极连在一起,最好用星型接地,不要形成地环路。
第二反应查终端电阻。总线两端有没有 120 欧姆电阻?如果只有一端有或者两端都没有,长线反射会造成信号过零点的抖动,误码率会直接上升。示波器看 A、B 两线之间的波形,如果上升沿有明显的振铃,大概率就是终端电阻问题。
第三反应查屏蔽。双绞线最好选用带屏蔽层的型号,屏蔽层单端接地。如果现场布线走了强电桥架附近,干扰会大到逻辑电平翻转。
第四反应是软件层面的确认。Modbus 的 CRC 校验一定要启用,CRC 不对的帧直接丢弃。如果 CRC 错的很多,说明信道质量差,先查硬件;如果 CRC 对的但是数据明显不对,那可能是节点端传感器被干扰,在节点本地也要加滤波。
我调试时遇到过一种很隐蔽的情况:两个远程节点的地址设重了,主站轮询地址 1 时,两个节点同时响应,总线冲突,数据完全乱掉。这个必须靠设备管理来避免,每个节点出厂前必须烧录唯一地址,现场安装时也要用地址表核对。
5.3 常见问题速查表
| 现象 | 可能原因 | 处理方案 |
|---|---|---|
| 本地温度读不出来 | 上拉电阻缺失 | 检查 SDA/SCL 上拉电阻(4.7k-10k) |
| 温度读出来是 65535 | I2C 无响应或地址错误 | 扫描总线确认地址,检查供电 |
| 温度是负数但显示很大 | 符号位未扩展 | 将原始值转为 int16_t 再做换算 |
| 远程节点经常超时 | 波特率过高或总线过长 | 降低波特率到 9600/19200 |
| 远程数据乱跳 | 终端电阻缺失 | 总线两端加 120 欧姆电阻 |
| 某节点掉线不影响其他节点 | 轮询超时机制生效(正常) | 无需处理,检查故障节点接线即可 |
| 温度一直偏高/偏低 | 传感器安装位置或校准缺失 | 检查热源距离,做软件校准偏移 |
5.4 一个少有人提的软件坑:打印与轮询互相阻塞
写完主逻辑之后,我发现串口打印调试信息和 RS-485 轮询放在同一个循环里时,打印耗时太长,导致远程节点响应超时。第一次没注意,后来发现调高串口波特率到 115200 或者把打印任务放到 DMA 传输,问题就解决了。
这个坑给所有做类似项目的人一个提醒:调试代码别留在正式逻辑里。串口打印、OLED 刷新这类耗时操作,要么占用单独的 DMA 通道,要么降低刷新频率,不要让它们阻塞总线轮询的节奏。最终版固件里我把调试打印全部关掉,只在本地维护时通过调试串口重新打开,整个系统的轮询时序稳了很多。
6. 实测效果与应用扩展
6.1 长时间运行实测数据
系统搭完以后,我在模拟 HVAC 环境里做了 7 天不间断运行测试,部署了 1 个本地节点和 6 个远程节点,RS-485 总线长度约 150 米,波特率 9600。结果如下:
- 本地温度稳定在 25 度左右,波动小于正负 0.3 摄氏度;
- 远程节点温度与本地基准温度计偏差在正负 0.4 摄氏度以内;
- 总线误码率统计,CRC 错误帧占比低于 0.01%,全部被软件过滤,没有对有效数据产生污染;
- 告警功能测试中,把加热器打开让温度超过设定阈值,风扇继电器在 1 秒内响应,温度回落正常。
这个结果验证了整套方案的可行性。同时也说明,温度监测系统的瓶颈往往不在传感器精度,而在通信稳定性和软件滤波策略,把这两块做好,系统的实际表现会非常稳定。
6.2 可扩展方向
这套系统的边界不止于“读温度”。硬件和软件架构上都留了扩展空间:如果后续要接入更多类型的传感器(湿度、压力、风速),远程节点只用改传感器部分,总线协议不用动;如果要接入云平台或者 HMI 触摸屏,STM32F412RE 多出来的 UART 可以接 WiFi 模块或者有线以太网,Modbus 数据直接推送出去。
我自己下一步就打算把几个远程节点里的温度数据,通过一个协议转换模块接入现有的楼宇自控系统,让值班室的大屏上直接能看到各管道的实时温度曲线。整个系统的扩展路径很平滑,不需要推翻重来。
写在最后
这套 PJ85718DM + STM32F412RE 的温度监测方案,做下来最大的体会是:硬件选型只是开始,把通信链路、软件时序和滤波策略捋顺,才是系统真正能跑起来的核心。
如果你也要做类似的嵌入式温度监测,我建议先从最小系统开始:一块主控板、一个本地传感器、一个远程节点,跑通整条数据链路之后,再逐步加节点、加功能。别一开始就追求大而全的架构,先把最小闭环做稳定,后续扩展会顺畅得多。遇到问题时,优先按“供电 -> 通信 -> 校验 -> 滤波”的顺序排查,能少走不少弯路。