多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

基于PIC18F56K42与PJ85718DM的HVAC本地/远程双路温度监测实战

基于PIC18F56K42与PJ85718DM的HVAC本地/远程双路温度监测实战 1. 从一颗温度传感器说起为什么本地与远程双路监测值得单独做嵌入式温度监测这件事看起来简单做起来坑不少。很多人第一反应是挂个传感器读一下不就完了但真正落到 HVAC暖通空调这类场景里你会发现需求远比想象中复杂你既要盯着设备本体的温度又要盯着远端某个房间、某段风管、某个回风口的温度而且这两路数据的采样节奏、精度要求、异常处理逻辑往往完全不同。我这次做的项目核心就是用PJ85718DM这颗温度传感芯片配合PIC18F56K42这颗 8 位单片机搭一套能同时监测本地温度和远程温度的小系统。选这两个器件的组合不是随便拍的——PJ85718DM 负责把温度转成数字量PIC18F56K42 负责采集、处理、判断、上报。一个管感知一个管决策分工很清晰。先说清楚这套东西能干什么、适合谁看。它能干的事包括本地板载温度实时采集、通过外接探头实现远程温度采集、双路数据对比与差值判断、超阈值告警、以及把数据通过串口或显示模块输出。适合的读者是正在做 HVAC 控制板、嵌入式环境监测、工业设备温控的工程师也适合刚接触 PIC 系列单片机、想找一个完整小项目练手的朋友。为什么我要把本地和远程分开讲因为这两路的物理实现方式、信号链路、误差来源都不一样。本地温度基本就是芯片贴着自己测走的是芯片内部或板级的热传导远程温度得靠外部传感器或者延长线把信号引过来中间会引入线阻、噪声、接触热阻等一堆问题。把这两件事混在一起谈最后一定是笔糊涂账。所以这篇内容我会把两条链路拆开从器件选型、硬件连接、寄存器配置、采样逻辑、误差处理到实测踩坑一层层讲透。关键词方面围绕这个项目最核心的几个词是温度监测、PIC18F56K42、PJ85718DM、HVAC、本地温度、远程温度、嵌入式采集、I2C 通信、阈值告警。这些词会在下文自然展开不会硬塞。2. 两颗核心器件到底怎么分工PJ85718DM 与 PIC18F56K42 的角色拆解2.1 PJ85718DM 在温度链路里承担什么PJ85718DM 是一颗数字温度传感器类的器件它的价值在于把模拟的温度物理量直接转成可读的数字量省掉了外部运放、ADC 调理、冷端补偿这一整套模拟前端。对嵌入式工程师来说这意味着你的板子上少了一堆电阻电容少了一堆需要校准的模拟节点BOM 更干净调试更省心。从使用角度看这类数字温度传感器通常具备几个关键特性一定的测温范围、固定的分辨率比如 0.0625°C 或 0.125°C 这类档位、通过标准串行总线I2C 或类似两线制接口与主控通信、支持寄存器配置采样精度和告警阈值。我在项目里最看重的两点一是它的分辨率够不够支撑 HVAC 场景的判断二是它的接口时序好不好伺候。HVAC 场景对温度精度的要求其实分档如果是做室温舒适度控制±0.5°C 已经够用如果是做设备过温保护那更看重响应速度和阈值一致性绝对精度反而次要。PJ85718DM 这类器件在常温段的线性度通常不错真正需要留意的是它在极端温度区间的表现以及自发热带来的偏移。提示数字温度传感器自身的功耗会带来轻微自发热如果芯片紧贴被测面且周围散热差读数可能比真实值高零点几度。做高精度场合时这一点必须纳入误差预算。2.2 PIC18F56K42 为什么适合当这个主控PIC18F56K42 属于 PIC18 系列里外设比较丰富的一档它有几个特性特别契合这个项目。第一它带有多路串行通信外设可以灵活配置成 I2C 主机去读传感器也能配成 UART 去上报数据。第二它的 GPIO 和定时器资源足够能同时处理本地采样、远程采样、按键输入、显示刷新这些任务而不打架。第三PIC18 系列的开发工具链成熟寄存器手册写得清楚出问题好查。我选它而不是选更小的 8 位型号核心原因是双路 告警 上报这套逻辑需要一定的 RAM 和定时器资源。如果你只用一颗传感器、只做单点读取那确实用更便宜的型号就行但一旦要同时管两路温度、做滑动平均、维护阈值状态机资源就开始紧张了。PIC18F56K42 在这中间是个比较舒服的平衡点。另外一个实际考量是它的工作电压范围和抗干扰能力。HVAC 控制板往往和继电器、风机、压缩机这些大功率负载共处一板电磁环境不干净。PIC18 系列在这类环境里被大量使用外围电路设计资料多遇到复位、跑飞、通信丢包这些问题时能找到的参考经验也多。2.3 两路温度的信号链路差异把本地和远程分开看链路是这样的维度本地温度远程温度传感器位置与主控同板靠近被测点通过探头/延长线引至远端信号形式板级数字总线路径短长线传输易受干扰主要误差源自发热、板级热耦合线阻、噪声、接触热阻采样节奏可高频响应快通常降频配合滤波校准方式单点校准即可需考虑线缆补偿这张表是我在实际调试中总结出来的不是抄手册。你会发现远程那一路的麻烦程度明显更高后面我会专门用一节讲远程链路的处理。3. 硬件连接与总线配置把两颗芯片真正连起来3.1 供电与去耦的细节先说供电。PIC18F56K42 和 PJ85718DM 通常都工作在 3.3V 或 5V 域具体看型号后缀和你的系统设计。我建议两者共用同一路 LDO 输出避免不同电源域之间产生地电位差这个差值在 I2C 总线上会直接表现为电平判读错误。去耦电容这块很多人图省事只在电源入口放一颗 10uF这是不够的。正确做法是每颗芯片的电源引脚旁边都放一颗 0.1uF 的陶瓷电容尽量靠近引脚走线短而粗。PJ85718DM 这种传感器对电源纹波比较敏感纹波大了读数会跳。我在第一版板子上就吃过这个亏读数每隔几秒抖一下后来加了去耦电容并缩短走线抖动明显收敛。注意去耦电容的地要就近打到芯片的地引脚不要绕远路回到电源入口的地。地回路越长高频噪声抑制效果越差。3.2 I2C 总线的上拉与速率选择PJ85718DM 通过 I2C 与 PIC18F56K42 通信总线需要上拉电阻。上拉阻值的选择是个经典问题阻值太小功耗大、灌电流大阻值太大上升沿变缓、高速通信时波形塌陷。常见取值在 2.2k 到 10k 之间。我的经验是如果总线走线短几厘米、速率 100kHz用 4.7k 很稳如果走线长或者速率上到 400kHz降到 2.2k 到 3.3k 更保险。判断方法很简单用示波器看 SCL 和 SDA 的上升沿如果上升时间超过通信周期的十分之一就该减小上拉阻值了。PIC18F56K42 的 I2C 外设配置需要注意几个寄存器波特率寄存器决定 SCL 频率控制寄存器决定主机模式和使能位。配置顺序我习惯先设波特率再设模式最后使能避免使能后立刻产生异常波形。// 以常见 PIC18 I2C 主机初始化为例示意具体寄存器名以手册为准 // 设置 I2C 时钟为 100kHz假设系统时钟 16MHz I2C1BRG 0x27; // 波特率分频值需按实际时钟计算 I2C1CONbits.I2CEN 0; // 先关闭外设再配置 I2C1CONbits.I2CSIDL 0; I2C1CONbits.I2CEN 1; // 配置完成后使能波特率分频值的计算不能拍脑袋。公式大致是分频值 (系统时钟 / (2 × 目标速率)) - 1 这类形式具体以手册给的公式为准。算错了通信直接不通而且现象是完全没响应很容易误判成硬件坏。3.3 远程探头的接入方式远程温度这一路物理上有两种常见做法。一种是把数字传感器直接放到远端用延长线把 I2C 引过去另一种是远端放模拟探头信号回到主板再做数字化。两种各有取舍。数字传感器放远端的好处是抗干扰相对好因为线上传的是数字信号只要电平判读正确噪声不会直接污染温度值。坏处是 I2C 是短距离总线延长线一长电容增大上升沿变缓通信容易失败。我实测下来普通杜邦线超过半米就开始不稳超过一米基本要靠降低速率和减小上拉阻值硬撑。模拟探头放远端的好处是线缆要求低坏处是模拟小信号在长线上极易被干扰而且需要主板上有 ADC 和调理电路。对 HVAC 这种电磁环境复杂的场景我更倾向数字方案但必须把总线驱动做好。提示如果远程距离确实较远可以考虑在远端加一级总线缓冲或改用差分传输方案但这会显著增加复杂度需要权衡。4. 固件逻辑采样、滤波、阈值判断怎么写才靠谱4.1 采样节奏的设计温度是个慢变量没必要像采高速信号那样疯狂读。我的做法是本地温度每 500ms 采一次远程温度每 1s 采一次。为什么远程更慢因为远程链路更容易受瞬时干扰采样太密反而把噪声都采进来了而且远程探头本身的热响应也慢采太快没有意义。采样节奏靠定时器中断来驱动。PIC18F56K42 的定时器配置成固定周期溢出在中断里置标志位主循环检测到标志位再去读传感器。这种中断置标志、主循环处理的结构比在中断里直接做 I2C 通信要稳因为 I2C 通信耗时且可能阻塞放在中断里容易影响其他中断的响应。volatile uint8_t flag_local_sample 0; volatile uint8_t flag_remote_sample 0; void __interrupt() timer_isr(void) { if (TMR0IF) { TMR0IF 0; static uint16_t cnt 0; cnt; if (cnt % 1 0) flag_local_sample 1; // 每 500ms if (cnt % 2 0) flag_remote_sample 1; // 每 1s } }4.2 滑动平均与中值滤波的组合原始读数一定带噪声直接拿去判断阈值会误报。我一般用中值滤波 滑动平均两级处理。中值滤波负责干掉偶发的野值比如通信误码导致的离谱读数滑动平均负责平滑正常范围内的抖动。具体做法维护一个长度为 5 的原始值数组每次新读数进来先排序取中值把中值塞进长度为 8 的滑动窗口求平均。这样即使某一两次读数异常也不会污染最终输出。窗口长度不是越大越好太大响应会变迟钝HVAC 场景里温度突变比如风机启动需要及时反映窗口太长会掩盖真实变化。滤波方式作用典型窗口副作用中值滤波剔除野值3~5计算量略增滑动平均平滑抖动8~16响应变慢一阶低通平滑且省资源系数 0.1~0.3参数需调4.3 阈值判断与状态机阈值判断不能只写一个if (temp threshold)那样会在阈值附近疯狂抖动告警。正确做法是加迟滞hysteresis比如超过 60°C 触发告警但要降到 55°C 以下才解除。这 5°C 的差值就是迟滞带能有效防止边界抖动。再进一步我会用一个简单的状态机来管理正常态、预警态、告警态。预警态是接近阈值但还没超用来提前提示告警态是确实超了。状态之间的迁移条件都带迟滞这样输出稳定不会让上位机收到一堆重复告警。typedef enum { STATE_NORMAL, STATE_WARN, STATE_ALARM } temp_state_t; temp_state_t update_state(float t, temp_state_t cur) { switch (cur) { case STATE_NORMAL: if (t 55.0f) return STATE_WARN; break; case STATE_WARN: if (t 60.0f) return STATE_ALARM; if (t 50.0f) return STATE_NORMAL; break; case STATE_ALARM: if (t 55.0f) return STATE_WARN; break; } return cur; }这段逻辑看着简单但实际跑起来比裸判断稳太多。我在一个风机控制项目里就是因为没加迟滞告警日志被刷爆后来补上迟滞才清净。5. 远程温度那一路的坑线缆、噪声与校准5.1 线缆带来的误差到底有多大远程温度最容易翻车的地方就是线缆。数字传感器延长线主要问题是总线电容和反射模拟探头延长线主要问题是线阻和干扰。我做过一个粗略测试用一米普通排线接数字传感器通信成功率在常温下还行但一旦旁边有继电器动作误码率立刻上升。线阻对模拟方案的影响更直接。假设探头是热敏电阻线阻几欧姆看起来不大但如果分压电阻也是几百欧姆量级线阻就会带来可观的读数偏移。而且线阻随温度变化等于给系统引入了一个漂移源。注意远程方案一定要做线缆补偿或至少做一次现场校准不能拿实验室短线的读数直接用到现场长线上。5.2 抗干扰的几招实用手段第一招是双绞。把信号线和地线绞在一起能显著降低共模干扰。第二招是屏蔽屏蔽层单端接地不要两端都接否则形成地环路反而更糟。第三招是降低总线速率100kHz 不行就降到 50kHz 甚至更低牺牲速度换稳定。第四招是在远端加小电容滤波但电容不能太大否则会拖慢上升沿。这几招我通常是组合使用。实测下来双绞加降速能解决大部分普通干扰问题屏蔽则用在干扰特别强的场合。5.3 现场校准的具体做法校准我一般分两步。第一步是零点校准把本地和远程探头放在同一环境里等热平衡后记录两者差值把这个差值作为固定偏移量存起来。第二步是跨度校准如果有条件用标准温度源在两个温度点比如 10°C 和 40°C分别比对拟合出斜率和截距。没有标准温度源怎么办可以用冰水混合物约 0°C和沸水约 100°C注意海拔修正做粗略两点校准。虽然精度有限但对 HVAC 这种不需要实验室级精度的场景已经够用。// 简单的两点校准根据两个参考点计算斜率和截距 float cal_slope (ref_high - ref_low) / (raw_high - raw_low); float cal_offset ref_low - cal_slope * raw_low; float calibrated cal_slope * raw cal_offset;6. 实测中遇到的几个典型问题与排查过程6.1 读数偶尔跳到 85°C 的诡异现象调试初期遇到一个怪事本地温度偶尔会跳到一个固定值看起来像 85°C 这种典型的上电默认值。排查过程是这样的先怀疑传感器坏换了一颗还是跳再怀疑电源示波器看电源纹波正常最后抓 I2C 波形发现跳变时通信时序里少了一个 ACK。根因是总线在特定时刻被干扰导致一次读事务不完整传感器返回了默认寄存器值。解决办法是在读事务后加校验如果读到的值等于已知的默认值或超出合理范围就丢弃这次读数并重读。加了这层保护后跳变再没出现过。这个坑的教训是不要无条件相信一次读数尤其是走外部总线的传感器。加一层合理性校验的成本极低收益极大。6.2 远程温度比本地低好几度的原因另一个问题是远程读数系统性地比本地低 3 到 4°C。一开始以为是校准没做重新校准后还是偏低。后来把远程探头和本地探头贴在一起发现差值依然存在说明不是环境差异。继续查发现是延长线的线阻加上探头接触热阻共同造成的。探头没有紧贴被测面中间隔了一层空气热传导不畅读数自然偏低。把探头用导热硅脂贴紧后差值缩小到 1°C 以内再做一次偏移校准就基本一致了。提示远程探头的安装方式对读数影响巨大导热硅脂、金属压片、贴合面积这些细节都要认真对待不能随便一贴了事。6.3 通信偶发失败但复位就好还有一个偶发问题系统跑几天后 I2C 通信失败断电重启就恢复。这种跑久了才出问题的现象通常和状态机卡死或总线锁死有关。I2C 总线有个经典问题如果主机在从机拉低 SDA 时复位从机会一直拉着 SDA 不放导致总线锁死。解决办法是在初始化时加总线恢复逻辑检测到 SDA 被拉低且 SCL 空闲时手动发送 9 个时钟脉冲让从机释放总线。PIC18F56K42 可以通过把 SCL 引脚临时配成 GPIO 来手动翻转时钟。加了这段恢复逻辑后长时间运行再没出现锁死。// I2C 总线恢复示意手动发时钟脉冲释放被拉低的 SDA void i2c_bus_recover(void) { // 将 SCL/SDA 配为 GPIO 输入 // 若 SDA 为低则翻转 SCL 最多 9 次 for (int i 0; i 9; i) { // SCL 拉低、拉高各一次 // 每次检查 SDA 是否释放 } // 恢复 I2C 外设配置 }7. 把数据用起来上报、显示与后续扩展7.1 串口上报的格式设计数据采出来得让人看见。我用 UART 把本地温度、远程温度、状态、时间戳打包上报。格式上我倾向用简单的文本行比如L:25.3,R:24.8,S:0好处是人眼可读、调试方便、上位机解析也简单。二进制协议虽然省带宽但调试时得对着解析工具看效率低。上报频率不用太高和采样节奏对齐即可本地 500ms、远程 1s打包后每秒发一到两帧。波特率 9600 或 115200 都行看你的上位机支持情况。7.2 本地显示的取舍如果设备需要现场查看加一个小段码屏或 OLED 是常见做法。段码屏便宜、抗干扰好、功耗低但只能显示数字OLED 信息量大但怕低温、寿命有限。HVAC 设备很多装在室外或机房温度范围宽我更倾向段码屏或者带背光的字符屏。显示刷新不要和采样同频否则屏幕闪。我一般 1s 刷一次只刷变化的部分减少总线占用。7.3 后续可以怎么扩展这套框架搭好之后扩展空间不小。可以加多路远程探头做多点平均可以接入无线模块做远程上报可以把阈值配置做成可下发参数还可以加历史数据存储做趋势分析。核心的采样、滤波、状态机逻辑都是复用的换的只是外围。我个人在实际操作中的体会是温度监测这类项目难点从来不在读一个数而在读得准、读得稳、异常能兜住。把滤波、校验、迟滞、总线恢复这几层防护做扎实系统才能长期可靠运行。很多新手项目跑一天没问题跑一周就出各种幺蛾子差别就在这些防护细节上。最后再分享一个小技巧调试阶段一定要把原始读数和滤波后的值都打印出来对比不要只看最终结果。原始值能告诉你噪声有多大、野值多不多这些信息决定了你的滤波参数该怎么调。只看平滑后的值等于把问题藏起来了。
返回列表