最近我调了一套设备,核心思路很简单:用PJ85718DM数字温度传感器采集本地和远程温度,用PIC18F55K42这颗8位MCU统一处理数据并通过串口/RS485上报。这套组合覆盖了两个我很常见的场景——嵌入式机柜里的板卡测温,以及HVAC风管里的远端温度回传。
以前我习惯用NTC热敏电阻加长线,把模拟信号直接拉回主控板,结果一到现场就被干扰、压降和校准问题搞得头疼。换用数字单总线传感器之后,远端只传数字信号,温度值在传感器内部就转换好了,主控这边只管读数,抗干扰能力和调试效率完全不是一个级别。这篇文章会从选型思路、系统拓扑、硬件细节、固件状态机、滤波标定和现场坑点几个方面,把这套方案的完整实现过程写清楚,适合正在做温控采集、嵌入式环境监测或者HVAC控制项目的朋友参考。
1. 选型思路:单总线数字温度传感器搭配8位MCU解决了什么
1.1 为什么不想再用NTC加长线方案
先说说我为什么从NTC换到数字传感器。NTC本身不贵,精度也能做到差不多,但它的输出是电阻变化,要经过分压电路、ADC采样、查表转换好几道工序。本地短距离还好说,一旦传感器放到几米甚至十几米外的风管里,问题就来了:
- 长线电阻会直接叠进分压电路,引入不可忽略的测量偏差;
- 模拟信号在长线上容易耦合电机启停、变频器产生的干扰;
- 每路传感器都要单独占用一路ADC通道,还要做线性校准和温度补偿。
这些问题的根源在于:模拟信号没能在测量点本地转换成数字量。所以这次我直接选带数字输出的温度传感器,把A/D转换放在传感器内部完成,远端传回来的就是已经量化好的数值,线路噪声对信号的影响会小很多。
1.2 关于PJ85718DM这颗传感器
PJ85718DM属于单总线接口的数字温度传感器,和我之前用过的很多单总线芯片使用方法类似,但指标更贴近工业测量需求。按数据手册上的参数看,测温范围覆盖了-55℃到+125℃,常规工作区间内精度能做到±0.5℃以内,分辨率可以通过配置寄存器调整到12位,也就是0.0625℃的步进。这样的指标对嵌入式机柜散热监测和HVAC风管温度监测来说都够用,留出的余量也不小。
单总线协议最大的好处是省引脚,一条数据线就可以挂多个传感器,每个传感器有独立的序列号,主控能够按地址逐个访问。在只做本地测温的场景里,一颗MCU的普通GPIO就能搞定;要做多点测温时,也不需要扩展IO口。
它支持外部供电和寄生供电两种模式。我在HVAC现场基本都用外部供电,原因后面会详细说——寄生供电在长线和强干扰环境下容易出各种奇怪问题。
1.3 关于PIC18F55K42这颗MCU的选择
PIC18F55K42是一颗8位MCU,定位就是做中小型工控和家电类控制。我选它不是因为它的性能有多强,而是因为它的外设组合恰好覆盖了这套温度监测方案的几乎所有需求:
- 引脚足够多,除了单总线数据线,还能留出UART、I2C、GPIO和状态指示灯;
- 自带内部振荡器,精度对于单总线时序来说够用,不需要外挂晶振;
- 低功耗模式相对完善,在嵌入式电池供电场景下可以把功耗压得很低;
- 工具链成熟,调试方便,小批量打样后可以直接进中批量生产。
另外它内部还有可配置逻辑单元这类外设,不过我在这个项目里没有用到,只用了最基础的数字IO和串口。如果你手头有其他8位MCU,只要时序精度能满足单总线要求,这套方案也可以平移过去。
1.4 两种方案的成本和体验对比
用一个表格来概括我这次的选型对比:
| 维度 | NTC模拟长线方案 | PJ85718DM单总线数字方案 |
|---|---|---|
| 每路传感器IO占用 | 1路ADC | 1路普通IO,可挂多路 |
| 远端抗干扰能力 | 弱,模拟信号易受干扰 | 强,信号已数字化 |
| 校准复杂度 | 需要电阻分压校准、查表 | 传感器内部完成,只做必要的偏移校准 |
| 线缆节省程度 | 每传感器至少2-3根线 | 数据线可共用一根总线 |
| 排查问题难度 | 需要示波器逐段查信号 | 通过CRC和存在检测定位问题 |
这个对比并不说明NTC一无是处,在一些单点近距离、成本极敏感的场合它仍然有优势。但如果你的项目要覆盖本地和远程多点测温,又要面对现场复杂的电磁环境,数字单总线方案明显更稳妥。
2. 本地与远程测温的系统拓扑:先从接线图开始定方案
2.1 一个现场常见的测温需求拆解
我这次接的项目可以拆成两块需求。嵌入式机柜里,需要测主控板附近的空气温度,用于风扇调速和过温告警,这个属于本地测温。HVAC系统里,需要在风管末端、回风口或送风口测温度,用来做空调联动控制,传感器离主控板可能有几米到几十米的距离,这个属于远程测温。
如果把所有传感器都用同一根单总线并联,理论上可行,但现场布线一旦出现分支、接头和长距离裸露,总线电容和噪声就会上升。所以我做了一个更稳妥的拓扑设计:
- 本地温度传感器:直接焊在主控板上或走很短引线,连接MCU的普通GPIO,走线距离不超过20cm;
- 远程温度传感器:用屏蔽双绞线接到MCU的总线IO,中间经过可插拔端子,方便现场更换;
- 主控板再通过RS485或UART把温度数据上报给上位机或PLC。
2.2 为什么远程传输用数字总线而不是放大模拟信号
早期有工程师想在远端放一个运放,把NTC信号放大后再拉回来,我试过这种方案,效果并不好。原因很简单:运放会把有用的温度信号和干扰一起放大,地电位差也会直接叠加进去。哪怕用了差分架构,现场的电机、压缩机启停还是能在长线上感应出不小的毛刺。
PJ85718DM这类数字传感器相当于把测量端和传输端隔离开,传感器本地完成温度到数字量的转换,之后整条总线上传递的是电平状态,不是连续变化的模拟电压。即使线缆上耦合了一些干扰,只要电压电平没有严重变形,接收端依然能准确读出0和1。再加上单总线协议里带CRC校验,偶发的位错误也能被识别出来,不会直接污染温度值。
2.3 两级数据链路的划分
我在这个项目里把数据链路分成两级:
第一级是采集链路,也就是PJ85718DM到PIC18F55K42之间的单总线通信。这一级解决的是“传感器怎么把温度可靠传给MCU”的问题,距离一般在几十米以内。第二级是上报链路,也就是PIC18F55K42通过RS485或UART把整理好的温度值和状态信息传给上位机、PLC或触摸屏。这一级解决的是“MCU怎么把处理好的数据交给系统其他部分”的问题。
区分这两级非常重要。很多初学者会把传感器直接挂到上位机的通信线上,于是整个系统的可靠性都压在传感器那一根总线上,出问题后排查范围很大。我习惯让MCU作为中间节点,传感器只管采集,通信模块只管上报,MCU在中间做数据处理、缓存和诊断,这样每一级的边界都清晰,调起来快得多。
2.4 电源拓扑也要提前规划
单总线传感器虽然电流不大,但在远程供电场景里不能随便接线。我见过有人直接把传感器电源和MCU电源用一根细长线拉到远端,结果远端设备一启动,线上压降就能让传感器复位。计算很简单,假设传感器平均工作电流1mA,供电线20米,线阻大约1Ω/m,那么20米来回就是40Ω,压降就有40mV。听起来不大,但传感器内部有时会有一个较大的瞬态电流,峰值可能到mA级别,再加上线上其他设备,压降就会明显抬高。
所以我在项目里给了远程传感器独立的供电线路,用的线径比信号线粗一档,并且在传感器端加了100nF和10μF两级去耦电容。如果距离更远,可以考虑在远端做一个小的稳压电路,把电压稳定后再供给传感器。这条经验在长距离单总线测温中特别重要。
3. 单总线长距离部署的硬件细节:上拉、线缆、保护一个都不能少
3.1 上拉电阻到底选多大
单总线数据线在空闲状态需要外部上拉到高电平,上拉电阻的选择直接影响到通信可靠性和功耗。常见做法是4.7kΩ,但那是针对短距离、单设备的情况。我这套系统里有本地和远程传感器并联,总线电容明显变大,再用4.7kΩ就会出现上升沿变缓、时序不满足要求的问题。
可以做一个粗略估算。假设总线等效电容为2nF,上拉电阻为4.7kΩ,那么RC时间常数就是4.7kΩ×2nF=9.4μs。而单总线协议中,某些读时隙对电平建立时间的要求很严格,通常在几微秒级别,9.4μs的上升沿明显太慢了。
我在项目里把上拉电阻调整为1.5kΩ到2.2kΩ,实测波形明显改善。这里有个权衡,电阻越小,上升沿越快,但总线空闲时的灌电流会增大,功耗和信号反射也会上升。所以最好用示波器实测总线波形,以看到干净的方波且过冲可接受为准。我自己的经验是,短距离优先用4.7kΩ,长线或多设备时从2.2kΩ开始往下调,调完一定要测上升沿和过冲。
3.2 线缆不是随便拉一根网线就行
远程传感器到主控板之间,我要求用屏蔽双绞线,屏蔽层在主控板侧单端接地。双绞线可以让正反信号受到的干扰相近,屏蔽层则把外部电磁场挡在外面。不要用普通平行电线代替,尤其在HVAC场景里,风机、压缩机和变频器的干扰非常大。
线缆长度也要控制。虽然单总线允许一定长度的总线,但过长会让信号完整性和时序都变差。我实测下来,在没有中继的情况下,稳定的传输距离能做到几十米。如果你要拉上百米,就不建议硬撑了,更可靠的做法是加总线中继器,或者干脆把PIC18F55K42做成分布式采集节点放在现场,再通过RS485把数据传回主控。
3.3 现场干扰的防护措施
HVAC现场最麻烦的是变频器和电机启停。即使在数字总线上,如果干扰脉冲幅度足够大,还是会打乱电平状态,导致复位信号误判、时序错乱或CRC错误。我在这套板子上加了以下保护措施:
- 总线IO口串联一个100Ω到220Ω的电阻,限制外部浪涌电流;
- 在总线和地之间加TVS管,把过压钳位在安全范围;
- 靠近传感器端再加一个小电容到地,进一步滤除高频噪声,但要注意电容不能太大,否则会拖慢上升沿;
- 屏蔽层单端接地,不要两端都接地,以免形成地环路。
这些措施看起来简单,但在现场稳定运行中的价值非常大。我遇到过不加TVS时偶尔读到异常温度、加了之后连续跑几天都正常的情况,说明保护电路不是摆设。
3.4 地电位差问题
本地传感器和MCU共地自然没问题,远程传感器容易出问题的地方就是“地”。如果MCU的地和远端的传感器地不在同一个电位,总线上的逻辑电平判断就会出问题。我见过最典型的故障是:远程传感器明明供电正常,但读回来的数据偶尔变成全1,也就是传感器似乎不在线,其实是因为地电位差让总线的高电平判断产生了偏移。
解决地电位差有两个方向:一是把地线做得足够粗,尽量降低地线阻抗;二是在总线上做一些隔离或电平整形。项目里我比较实用的做法是保证远端供电地和信号地共用一根粗地线,并在传感器端做好接地,实测下来基本能解决大多数间歇性通信问题。
4. 固件状态机:单总线驱动、多传感器轮询与数据上送
4.1 主状态机的整体结构
固件部分我一开始就想用一个简单清晰的状态机来组织,避免所有逻辑都挤在while循环里。这套程序分以下几个状态:
- 初始化:配置IO口、串口、定时器和传感器参数;
- 总线扫描:检测总线上有多少个传感器,获取每个传感器的序列号;
- 温度转换:向所有传感器广播启动温度转换命令;
- 温度读取:逐个传感器读取温度值并校验CRC;
- 数据处理:滤波、格式化和异常判断;
- 数据上报:通过UART/RS485把结果发出去;
- 掉线重试:当某个传感器连续多次读取失败,进入重试和告警流程。
这个状态机的好处是每个阶段职责单一,出现问题很容易定位。比如读温度一直失败,直接检查总线扫描阶段是否能看到设备即可,不需要从头排查。
4.2 单总线驱动时序要点
单总线时序是整个固件的基础,我按手册和实际调试经验整理了下面这些要点。需要注意,不同批次的传感器时序参数可能略有差异,最好以实际数据手册为准,我只给出工程上常用的参考值:
- 复位脉冲:主机拉低总线至少480μs,然后释放,等待传感器存在脉冲;
- 存在检测:传感器在主机释放总线后60μs内拉低约60μs,表示设备在线;
- 写0时隙:主机拉低总线,持续时间至少60μs;
- 写1时隙:主机拉低总线一小段时间后释放,持续时间至少60μs;
- 读时隙:主机发起一个短的低电平脉冲,然后在15μs内采样总线电平;
- 两次总线操作之间,需要留出足够的恢复时间。
代码上,我习惯把每个时序写成独立的函数,并且用内联汇编或定时器来保证延时精度。延时时间不要用无符号整数递增的方式去凑,建议把代码放到中断尽量少的上下文里执行。
下面是一段我常用的复位和读温度流程示意代码:
uint8_t ow_reset(void) { uint8_t present; OW_PIN_LOW(); delay_us(500); OW_PIN_RELEASE(); delay_us(60); present = OW_PIN_READ(); delay_us(240); return present; } void ow_write_byte(uint8_t data) { for (uint8_t i = 0; i < 8; i++) { if (data & 0x01) { OW_PIN_LOW(); delay_us(6); OW_PIN_RELEASE(); delay_us(60); } else { OW_PIN_LOW(); delay_us(60); OW_PIN_RELEASE(); delay_us(6); } data >>= 1; } }这段代码的意图很清楚:严格按照时序拉低和释放总线。这里要注意的是,delay_us的精度非常关键,我使用的是PIC18F55K42内部定时器配合延时函数,实测满足要求。如果MCU主频偏低,需要重新校准延时参数。
4.3 多传感器轮询与地址管理
多个PJ85718DM挂在同一根总线上时,每个传感器都有唯一的序列号。固件启动后先执行总线扫描,把每个传感器的序列号保存在数组中,之后轮询时挨个发送匹配命令并读取温度。
轮询过程中要注意转换时间。传感器开始温度转换后,需要等待一段时间才能读取结果。转换时间跟分辨率有关,分辨率越高,转换时间越长。我的做法是广播启动转换后,等待一个覆盖所有传感器转换时间的固定延迟,然后再逐设备读取。这样比逐个启动逐个读取更高效,也让总线上的时序更规整。
4.4 如何用Modbus RTU上报温度数据
温度采集完之后,数据要通过RS485上报给上位机或PLC。Modbus RTU是工控和HVAC领域最常见的协议,我用PIC18F55K42的UART外设直接实现了一个简化的从站,只支持03功能码,用来读取寄存器。
寄存器映射如下:
| 寄存器地址 | 内容 | 数据格式 |
|---|---|---|
| 0x0000 | 本地温度 | 有符号整数,单位0.1℃ |
| 0x0001 | 远程温度1 | 有符号整数,单位0.1℃ |
| 0x0002 | 远程温度2 | 有符号整数,单位0.1℃ |
| 0x0100 | 在线状态字 | Bit0-7对应各传感器在线状态 |
| 0x0101 | 最近一次CRC错误计数 | 只读 |
收到上位机的03功能码请求后,MCU按地址组织数据,计算CRC16并回帧。这个实现不复杂,但可以避免上位机直接和传感器裸通信,维护起来也方便。你在自己的项目里如果已经有上位机中间件,也可以直接通过简单自定义帧上报,关键是数据和状态字段要定义清楚。
5. 滤波与标定:把传感器精度转化成系统测量精度
5.1 误差来源分析
PJ85718DM的固有精度虽然不错,但系统级的测量误差不等于传感器标称精度。我总结下来,误差主要来自以下几个方面:
- 传感器自热:传感器本身工作时会有微小电流,长时间通电会让读数略高于真实环境温度;
- 导热路径:传感器贴在高功耗器件旁边时,会直接感受到热量辐射;
- 电气噪声:总线干扰可能导致偶发的数据跳动;
- 安装位置:探头放在风管壁附近和放在气流中心,读数差距可能达到几度。
理解这些来源之后,才能设计合理的滤波和标定方案。否则就算传感器精度再高,系统层面的误差依然可能很大。
5.2 滑动平均与中值滤波结合
HVAC和嵌入式环境温度变化通常比较缓慢,温度信号的带宽很低,高频噪声可以放心滤除。我在固件里做了两级处理:
- 中值滤波:取最近5次读数,排序后取中间值,用来剔除明显的野值和偶发干扰;
- 滑动平均:经过中值滤波后的数据再做一次8次滑动平均,让输出曲线更平滑。
这里要注意,滤波强度不宜过大。如果滑动平均窗口太长,系统对温度变化的响应会变得迟钝,在需要快速联动风机或压缩机的场合会不合适。我最终用的是5次中值加8次滑动平均,实测在风管突然通入冷气时,温度响应时间仍然可以接受。
5.3 两点校准的思路
如果现场对绝对温度要求很高,比如HVAC系统需要和标准温度计对比,那就需要做校准。我的做法是两点校准法,选择两个有代表性的温度点,比如0℃附近和50℃附近,分别记录传感器读数和标准温度计读数,然后计算出偏移量bias和增益系数gain。
校准后的温度值 = 原始读数 × gain + bias
这个gain和bias可以存在MCU的EEPROM或Flash里,烧录后可以通过串口命令重新校准,不需要重新编译固件。考虑到PJ85718DM本身的线性度不错,两点校准一般就能把系统误差压到很低的水平。
5.4 在线自检与健康状态上报
我在这套系统的寄存器里专门留了一块状态区,用于上报传感器在线状态和CRC错误计数。每次轮询完成后,MCU会检查是否存在检测失败和CRC错误,并在连续多次失败后把对应通道标记为离线。
这样做的好处是,远程维护人员不用到现场就知道哪个传感器接触不良、哪根线缆可能被老鼠咬了。我在HVAC项目里遇到过传感器间歇性掉线的问题,正是通过CRC错误计数才发现某段线缆的屏蔽层破损,提前处理避免了更严重的故障。
6. 现场问题记录:长线、干扰和多传感器地址的那些坑
6.1 坑一:上拉电阻太大导致长线时序漂移
第一次去现场调试时,远程传感器长度大约15米,我用了4.7kΩ上拉,结果频繁读取失败,示波器一测,总线上升沿果然慢得像电容充电。把上拉改成2.2kΩ后,波形明显变好,通信恢复稳定。这个问题的排查思路值得记下来:温度读数异常、CRC错误频繁,先看波形,再看时序,不要一上来就怀疑代码。
6.2 坑二:传感器的存在检测时好时坏
有一路远程传感器经常出现存在检测失败,但测量总线对地阻值又正常。最后发现是传感器供电引脚松动,传感器在供电电压临界点附近工作,偶尔上电不完全导致存在脉冲幅度不够。处理方式是重新压接端子,并给传感器端加了一个较大的储能电容,问题彻底解决。
这给我一个教训:单总线传感器的工作电流不大,但供电质量直接影响通信。所有疑似通信问题,都要先确认供电电压和纹波,不要只盯着数据线。
6.3 坑三:多传感器地址一样
项目里有一次采购了一批传感器,发现有两颗序列号完全一样,挂在总线上后只能读到其中一个。排查后确认是采购时买到了地址重复的特殊批次。解决方法是换用序列号唯一的原厂正规渠道芯片,或者把重复的设备单独接一路IO。这里建议所有从正规渠道采购传感器,并保留标称序列号信息。
6.4 坑四:HVAC现场的电机启停干扰
还有一个现场问题是,空调压缩机一启动,温度读取偶尔会跳变几度。通过增大总线IO串联电阻和加TVS管,把干扰抑制在安全范围内之后,跳变基本消失。说实在的,这种干扰问题非常依赖于实际安装环境,最好的验证方式是在现场多跑几天,看CRC错误计数是否持续增长。
最后说一点我的体会
这套本地与远程温度监测方案跑到现在,我最想分享的一点是:硬件保护上的钱和精力不要省。数字传感器确实比模拟方案抗干扰能力强,但长距离、强干扰的HVAC现场依然会暴露很多问题。上拉电阻、屏蔽双绞线、TVS和供电去耦,这些细节都做到位之后,固件工作会很轻松,很多“软件问题”其实也就不存在了。如果你也在做类似的嵌入式温度采集项目,建议先从硬件抓稳,再优化算法和状态机,这样整套系统的稳定性会比只盯代码想来得可靠很多。