測方案)
做嵌入式溫度監(jiān)測我最近一直在用 PJ85718DM 這顆傳感器加上 STM32F042C6 這顆 M0 主控做本地和遠程溫度采集。剛開始以為這就是“上拉電阻讀寄存器”的小活真正深入進去才發(fā)現(xiàn)本地溫度、遠程二極管測溫、HVAC 環(huán)境里的干擾和安裝方式每一環(huán)都有講究。這篇文章就把這套組合從選型、硬件、固件到現(xiàn)場調(diào)試的完整過程寫出來適合正在做溫控、低壓變頻器、HVAC控制器或者電池管理系統(tǒng)里溫度保護的朋友參考。PJ85718DM 是一顆帶 I2C 接口的數(shù)字溫度傳感器和普通單點溫度芯片最大的區(qū)別是它同時支持本地溫度采樣和遠程二極管溫度采樣。STM32F042C6 則是 Cortex-M0 內(nèi)核的 MCU主頻 48MHz內(nèi)置 CAN、USB、多路 USART 和硬件 I2C做傳感器數(shù)據(jù)讀取、PID 調(diào)節(jié)、Modbus 上報都足夠用。這個組合解決的核心問題只有一個設備既要知道“自己身邊有多熱”也要知道“遠處一個溫度敏感點有多熱”而且兩邊數(shù)據(jù)要在同一套采集鏈路里完成成本還不能高。1. 方案拆解為什么是“本地溫度傳感器 遠程測溫通道”的組合1.1 PJ85718DM 到底解決了什么問題很多場景需要一個傳感器同時照顧兩個測溫點。舉幾個我實際接觸過的例子嵌入式控制器里要監(jiān)控 PCB 環(huán)境溫度同時還要監(jiān)控功率器件或者主芯片的結(jié)溫。變頻器或者電機驅(qū)動器里IGBT 模塊附近需要溫度保護但控制板上的 MCU 也想拿到散熱器溫度。HVAC 空調(diào)內(nèi)機控制板需要知道板載溫度來做防凝露判斷而蒸發(fā)器管路、回風風道的溫度又得靠一個伸出去的探頭采集。如果只用普通 NTC每個測溫點都要一路信號調(diào)理、一個 ADC 通道、一套校準系數(shù)硬件復雜校準更是麻煩。PJ85718DM 這種帶遠程通道的芯片本地通道直接讀芯片內(nèi)部結(jié)溫遠程通道則通過一對 D、D- 引腳接一顆二極管連接的三極管就能把遠處的溫度信號拉回到同一顆芯片上處理輸出統(tǒng)一走 I2C 總線上報。遠程測溫的核心原理并不難理解。二極管的 PN 結(jié)正向壓降 Vbe 會隨溫度變化大約每升高 1°C 降低 2mV 左右。但直接用 Vbe 絕對值算溫度會受到器件批次、串聯(lián)電阻、焊接工藝帶來的誤差影響。PJ85718DM 這類芯片更常用的做法是“不同激勵電流下的 ΔVbe 測量”分別用兩種電流去驅(qū)動外部二極管測量兩個 Vbe 的差值。因為 Vbe 絕對值里的固定項會被差分運算抵消剩下的 ΔVbe 就和絕對溫度近似成正比再經(jīng)過片上 ADC 轉(zhuǎn)換就能得到數(shù)字溫度。這也是遠程通道在較長距離走線時仍然能維持精度的原因。本地通道則簡單很多芯片內(nèi)部有一個寄生的測溫二極管和同一個 ADC 采樣鏈路。因為本地傳感器和 ADC 在同一顆芯片里距離短、溫度梯度小所以本地精度通常能做到比遠程更好。手冊里給的典型規(guī)格大約是本地 ±0.5°C遠程 ±1°C 上下這在 HVAC 和一般嵌入式熱保護里已經(jīng)夠用。如果你只需要“大概準”而不是“實驗室級別準”這套方案比外面掛三四個 NTC 省事得多。1.2 為什么選 STM32F042C6 當主控STM32F042C6 不算新器件但在這個項目里非常合適。它的技術(shù)參數(shù)并不華麗而是勝在接口全、功耗低、價格穩(wěn)定。Cortex-M0 內(nèi)核48MHz 主頻。跑 I2C 采樣、濾波算法、PID 或者簡單的 Modbus 協(xié)議棧完全夠用不需要上高成本 M4。內(nèi)置 CAN 2.0B 和 USB FS。嵌入式場景里如果要和車輛總線、運動控制器通訊CAN 是現(xiàn)成的如果要做本地調(diào)試USB 虛擬串口插上就能看數(shù)據(jù)流。I2C 接口是硬件外設不需要軟件模擬時序。配合 DMA 和中斷讀溫度寄存器只需要幾個周期CPU 時間可以留給控制邏輯。工作電壓只有 3.3V邏輯電平、功耗模型都很好規(guī)劃。整個測溫節(jié)點如果控制得夠精細運行電流可以做到很低。OFQFN 或者 LQFP 封裝體積小適合塞進 HVAC 控制板這種空間不寬裕的場合。有人會問既然只是讀溫度為什么不用一顆 8 腳的小單片機因為這類項目通常不是“只測溫”這一個功能。STM32F042C6 還要負責繼電器控制、風扇調(diào)速、狀態(tài)指示、與上位機通訊甚至跑本地保護邏輯。留出一路 I2C 接溫度傳感器只是它的本職工作之一。1.3 這套組合在什么項目里最劃算我做這套的時候總結(jié)過一個判斷標準如果你只需要測一個點的溫度用一顆單通道數(shù)字傳感器或者 NTC 加運放就解決了完全沒必要上雙通道遠程方案但如果系統(tǒng)里“板內(nèi)溫度”和“遠端溫度”都必須要而且兩者距離可能超過 20cm、甚至分屬不同 PCB 或者不同結(jié)構(gòu)件那 PJ85718DM 這種方案就開始變得合適。典型的嵌入式場景包括充電器 / 電源適配器本地測內(nèi)部環(huán)境溫度遠程測充電接口或者電池包表面溫度超過閾值直接降功率。無刷電機驅(qū)動板本地測 PCB 溫度遠程通過一顆貼在三相橋散熱片上的二極管三極管測散熱器溫度。智能照明電源LED 金屬基板上的溫度點通過遠程探頭采集實現(xiàn)過溫降額延長 LED 壽命。HVAC 場景則更直接空調(diào)外機控制器本地測電控盒溫度遠程探頭固定到壓縮機排氣管或者冷凝器管壁配合制冷邏輯做防過載。新風系統(tǒng)控制板測電路溫度遠程探頭伸進風道測進風溫度用來判斷是否結(jié)露。恒溫恒濕設備本地是控制板溫度遠程測量水箱或者出風口溫度。這些場景的共同點是遠端溫度點本身不方便放一整塊帶 MCU 和通信芯片的電路板只放一顆小二極管非常靈活。把二極管用導熱膠貼在目標物體表面引線長度控制在幾十厘米內(nèi)溫度信號就能回到主控板上的 PJ85718DM再由同一顆芯片轉(zhuǎn)成 I2C 數(shù)據(jù)給 STM32F042C6。這種一主一從的架構(gòu)比在每個測溫點單獨放傳感器、再通過長線通訊回傳可靠性和成本都更優(yōu)。2. 硬件設計PJ85718DM 與 STM32F042C6 的完整連接鏈路2.1 傳感器最小電路別只拉兩線上拉電阻PJ85718DM 的引腳不多一般可以歸納為電源 VDD、地 GND、I2C 時鐘 SCL、數(shù)據(jù) SDA、遠程測溫正負端 D、D-還有地址選擇 ADD0/ADD1、報警輸出 OS/ALERT。不同批次可能引腳定義順序有變化但功能類別是穩(wěn)定的。在設計最小電路時下面這幾個要點是我自己的習慣VDD 對 GND 必須放 0.1μF 陶瓷電容并且靠近引腳放。如果系統(tǒng)電源紋波較大再并聯(lián)一個 1μF 到 10μF 的電容實測對溫度讀數(shù)穩(wěn)定性很有幫助。SDA、SCL 都需要上拉電阻。電阻值要按總線上掛的設備數(shù)量、走線長度和通信速率來定??偩€上只有這顆傳感器工作頻率在 400kHz 以內(nèi)上拉 4.7kΩ 通常沒問題如果線長超過 10cm 或者總線電容偏大就換 2.2kΩ。ADD0/ADD1 決定 I2C 地址。做多路采集時可以用同一個寄存器地址通過不同地址段的芯片接在同一條 I2C 總線上每路能區(qū)分開。OS/ALERT 是漏極開路輸出也要接上拉電阻并且可以接到 STM32F042C6 的外部中斷引腳。這樣溫度超過閾值時MCU 不需要輪詢直接被中斷喚醒處理。我通常把傳感器放在控制板邊緣靠近遠程探頭接線端子那一側(cè)避免 D、D- 的長走線穿過板子中間的電源區(qū)域。一個需要注意的坑是遠程測溫腳 D、D- 的極性。大多數(shù)傳感器要求把二極管三極管的集電極和基極短接后接 D發(fā)射極接 D-接反了讀數(shù)會明顯不對。有的芯片手冊里說“支持反接檢測”但為了省調(diào)試時間我建議直接按標準接法設計不要賭。下面是一張參考連接示意表信號PJ85718DM 引腳連接目標關(guān)鍵參數(shù)供電VDD3.3V0.1μF 去耦電容地GNDGND單點接地時鐘SCLSTM32F042C6 PB6上拉 4.7kΩ 到 3.3V數(shù)據(jù)SDASTM32F042C6 PB7上拉 4.7kΩ 到 3.3V地址ADD0/ADD1高/低電平組合決定 I2C 地址報警OS/ALERTSTM32F042C6 PA0 EXTI漏極開路需上拉遠程D二極管三極管 BC 短接端走線盡量短遠程-D-二極管三極管發(fā)射極走線盡量短STM32F042C6 這邊VDD 就近加 0.1μF 和 4.7μF 電容NRST 默認上拉BOOT0 下拉到地。如果系統(tǒng)里要跑 USB 或者 CAN還要注意晶振和終端電阻這些和普通 STM32 設計沒有區(qū)別不展開細說。2.2 遠程測溫為什么非得用“三極管接成二極管”很多人第一次看到遠程溫度探頭會下意識覺得“直接拿一個普通整流二極管不就行了嗎”。我試過能工作但精度差不少。PJ85718DM 這類芯片測量遠程溫度依賴的是二極管的 Vbe 溫度特性而我們實際希望測量的是一個理想二極管模型的結(jié)溫。普通整流二極管比如 1N4007正向特性不一致生產(chǎn)批次差異大而且封裝管殼熱阻高感應到的往往是引腳周圍空氣溫度而不是目標物體溫度。更合適的做法是用小信號三極管比如常見的 MMBT3906把基極和集電極短接讓集電結(jié)變成零偏置只讓發(fā)射結(jié)發(fā)揮二極管作用。這樣發(fā)射結(jié)面積小、熱阻低能更準確地感應粘貼位置的溫度。三極管的工藝一致性比普通二極管好批次離散性小。不同型號三極管的 ideality factor 值非理想因子相對接近芯片內(nèi)置的校正算法能更好匹配。更進一步的場景是直接測量 MCU、CPU、GPU 芯片內(nèi)部的結(jié)溫。很多處理器會把片上測溫二極管引到外部引腳使用前要查清楚是 PNP 對管還是 NPN 對管結(jié)構(gòu)、電流激勵大小、是否需要設置 ideality factor 寄存器。PJ85718DM 如果提供 n-factor 校正配置就要按目標芯片手冊里的參數(shù)寫進去。如果忽略這一步遠程讀數(shù)可能會有 1°C 到 2°C 的誤差在某些應用里這就足以觸發(fā)保護動作了。2.3 HVAC 環(huán)境下的 PCB 布局和抗干擾經(jīng)驗HVAC 設備里的電磁環(huán)境說不上惡劣但比實驗室惡劣得多。我踩過的坑里印象最深的是風機繼電器吸合的瞬間溫度讀數(shù)跳一下然后恢復正常。用示波器看 D 引腳發(fā)現(xiàn)上面疊加了不小的高頻毛刺。溫度傳感器內(nèi)部 ADC 采樣雖然會做濾波但遠程模擬輸入端口是高阻抗處理不好就容易吸收噪聲。我的處理經(jīng)驗有這么幾條D、D- 差分走線盡量貼近中間不要穿插其他信號線避免形成大的環(huán)路面積。在傳感器 D、D- 引腳附近加一個幾十 pF 到幾百 pF 的對地電容。注意不能加太大電容過大會影響電流建立時間導致轉(zhuǎn)換結(jié)果偏低。通常 100pF 起步實測可用性最高。如果遠程探頭線必須過長超過 30cm就在探頭端做一個 RC 低通濾波而不是在主板上硬扛。傳感器和 MCU 的地、電源地之間做單點連接避免繼電器驅(qū)動的地電流串進傳感器地。報警輸出漏極開路引腳上拉電阻不要選太大否則邊沿過慢在電磁噪聲里容易被誤觸發(fā)中斷我一般用 4.7kΩ。另外不管板內(nèi)空間多緊張我都建議給遠程溫度探頭留一個獨立的連接器不要直接把裸線焊在主板上?,F(xiàn)場接線時HVAC 設備往往需要拆裝多次可插拔連接器能減少線纜折斷的概率后續(xù)維護更換探頭也方便。接線端子盡量選帶鎖定結(jié)構(gòu)的防止震動松脫。3. 固件設計把溫度讀數(shù)變成可控可用的數(shù)據(jù)3.1 I2C 底層讀取與寄存器讀寫STM32F042C6 使用硬件 I2C我在項目里優(yōu)先用 HAL 庫因為它對超時、錯誤標志的處理比較完整。調(diào)用方式并不復雜以讀取本地溫度寄存器為例uint8_t data[2]; HAL_StatusTypeDef status; status HAL_I2C_Mem_Read( hi2c1, (uint16_t)(PJ85718_ADDR 1), PJ85718_REG_LOCAL_TEMP, I2C_MEMADD_SIZE_8BIT, data, 2, 100 ); if (status ! HAL_OK) { // 記錄一次總線錯誤連續(xù)失敗則嘗試恢復 I2C 總線 }PJ85718_ADDR 要根據(jù) ADD0、ADD1 的跳線來定義不能寫死成 0x90。寄存器地址按照手冊填寫讀取順序要一次性讀完 2 字節(jié)不要拆成兩次字節(jié)讀取否則在兩次讀取之間數(shù)據(jù)更新高低字節(jié)會錯位溫度值可能出現(xiàn)異常跳變。為了屏蔽總線上其他干擾我給每次讀取加了超時。HAL 里面最后一個參數(shù)就是超時時間毫秒在溫控邏輯中我習慣設為 20ms。超過 20ms 還沒讀回來就判定總線掛死走 5.2 小節(jié)的恢復流程。3.2 溫度轉(zhuǎn)換計算從寄存器原始值到“讓人看得懂”的攝氏度PJ85718DM 的溫度數(shù)據(jù)寄存器一般是 16 位高 12 位是有效溫度低 4 位作為擴展精度或者為 0。典型分辨率是 0.0625°C也就是把最高有效位當作符號位。轉(zhuǎn)換時先將兩個字節(jié)拼成 int16_t再右移 4 位得到真正的 12 位有符號數(shù)最后乘 0.0625。int16_t raw (int16_t)((data[0] 8) | data[1]); raw 4; // 保留 12 位有符號溫度 float temp_c (float)raw * 0.0625f;舉個例子如果 data[0]0x0Ddata[1]0xA0拼起來是 0x0DA0右移 4 位得到 0x0DA 即 218218 × 0.0625 13.625°C。如果寄存器值是負溫度右移后符號擴展依然成立這個公式不用額外處理。遠程溫度寄存器采用同樣的轉(zhuǎn)換方式。在把原始值轉(zhuǎn)成 float 之前我還建議保留一份原始寄存器值用于后期排查?,F(xiàn)場設備一旦出現(xiàn)溫度異常先用 I2C 調(diào)試器讀寄存器確認是“傳感器本身讀數(shù)就不對”還是“固件轉(zhuǎn)換或上層處理引入了錯誤”。這一步在 HVAC 設備遠程維修時特別管用能省下大量來回跑現(xiàn)場的功夫。3.3 閾值報警讓 MCU 靠中斷而不是阻塞輪詢?nèi)绻?100ms 讀一次溫度輪詢也不會占用很多 CPU但優(yōu)勢在于報警能力。PJ85718DM 一般有本地和遠程高低溫限值寄存器還會有一個 OS/ALERT 輸出腳。把高低溫限值寫進去之后芯片自身會持續(xù)監(jiān)控兩個通道溫度一旦超限就把 OS/ALERT 引腳拉低。我在項目里是這樣安排的初始化階段寫入本地通道高溫限值、遠程通道高溫限值和恢復回差。OS/ALERT 配置成“比較器模式”溫度低于限值時自動恢復不鎖存。STM32F042C6 的 PA0 配置為外部中斷下降沿觸發(fā)。中斷服務函數(shù)里只置一個標志位具體的風扇調(diào)速、降功率、報警動作放在主循環(huán)處理避免在中斷里做耗時的 I2C 操作。有一點值得注意報警限值寄存器用的是和溫度寄存器一樣的分辨率寫入時要把目標溫度值除以 0.0625 再換算成整型。比如遠程最高溫度要設成 85°C寄存器值就是 85 / 0.0625 1360也就是 0x0550。如果用浮點算完以后不處理對齊問題可能寫入一個略高于目標值的數(shù)導致保護動作偏差。3.4 低功耗輪詢策略這個方案里傳感器本體功耗很低真正的功耗大頭是 MCU。STM32F042C6 常用的運行模式電流有個幾十毫安但對電池供電的設備來說還不夠。我的低功耗策略是“傳感器 asleepMCU stop定時醒來一下”。具體時序是將 PJ85718DM 寫 shutdown 配置進入低功耗待機。STM32F042C6 進入 STOP 模式使用 RTC 或低功耗定時器設置喚醒周期。喚醒后給傳感器發(fā)起一次 one-shot 轉(zhuǎn)換等待轉(zhuǎn)換完成讀取溫度寄存器。判斷溫度是否超限然后迅速重新進入 STOP。這樣的設計能把平均電流壓到微安級別適合溫度采集節(jié)點。HVAC 控制板通常不要求這么省電但嵌入式電池設備比如無線傳感器、冷鏈標簽就非常有幫助。需要注意的是one-shot 轉(zhuǎn)換不是馬上完成的啟動后必須讓傳感器內(nèi)部 ADC 完成采樣再讀寄存器。有的芯片會提供數(shù)據(jù)更新標志沒有標志的話就按手冊里的轉(zhuǎn)換時間延時。延時太短讀到的還是上一次數(shù)據(jù)太長又浪費電流所以這個時間要按手冊算準。不同分辨率模式對應不同的轉(zhuǎn)換時間一般從幾十毫秒到一兩百毫秒不等。4. 數(shù)據(jù)從量測到應用嵌入式保護邏輯與 HVAC 監(jiān)控平臺4.1 嵌入式場景里的環(huán)形緩沖、濾波與 ODT 保護嵌入式中控板需要的不僅僅是“當前溫度值”而是“趨勢”和“變化率”。我常用的做法是在內(nèi)存里維護一個環(huán)形緩沖保存最近 16 到 32 次溫度采樣然后計算移動平均。#define TEMP_BUF_LEN 16 static float temp_buf[TEMP_BUF_LEN]; static uint8_t idx 0; static float temp_sum 0.0f; float update_moving_average(float new_value) { temp_sum - temp_buf[idx]; temp_buf[idx] new_value; temp_sum new_value; idx (idx 1) % TEMP_BUF_LEN; return temp_sum / TEMP_BUF_LEN; }這個寫法占用資源極小但能明顯抑制偶發(fā)毛刺。配合變化率檢測還能做 ODT過溫降額或者熱保護當遠程溫度每秒鐘上升超過某個斜率比如 5°C/s就提前降低 PWM 占空比而不是等溫度沖到閾值才動。在電機驅(qū)動和電源適配器里提前一點降額往往比事后切斷更實用因為負載可以繼續(xù)工作只是性能稍微下降。HVAC 里的風機調(diào)速邏輯也類似。遠程冷凝器溫度高時提高風機轉(zhuǎn)速溫度降下來后再逐步降速中間加滯回區(qū)間避免風機頻繁變速。PJ85718DM 雙通道的優(yōu)勢在這里體現(xiàn)得很充分本地溫度負責控制板自身熱保護遠程溫度負責制冷循環(huán)熱負荷判斷兩路各自有獨立的報警限值互不干擾。4.2 HVAC 場景通過 Modbus 把溫度上報到監(jiān)控平臺設備端的溫度數(shù)據(jù)要送到人機界面或者樓宇控制系統(tǒng)在 HVAC 行業(yè)最通用的還是 RS485 加 Modbus RTU。STM32F042C6 的 USART 加上一個收發(fā)器配合中斷發(fā)送和接收就能實現(xiàn)簡潔的從機棧。我習慣把溫度值按 0.1°C 為單位存到保持寄存器里這樣整數(shù)運算足夠精度也比 0.0625°C 低不了多少還能避開浮點和 Modbus 協(xié)議編碼的麻煩。一張典型的寄存器映射表如下Modbus 地址內(nèi)容說明40001本地溫度單位 0.1°C有符號整型40002遠程溫度單位 0.1°C有符號整型40003報警狀態(tài)字bit0本地高溫bit1本地低溫bit2遠程高溫bit3遠程低溫40004設備狀態(tài)bit0傳感器通信正常bit1正在除霜等協(xié)議棧不需要做全套復雜邏輯只需要支持 03 讀保持寄存器、06 寫單個寄存器、16 寫多個寄存器就能滿足大多數(shù)現(xiàn)場需求。寫入功能多用于遠程設置溫度閾值這里要留意整數(shù)單位換算比如上位機寫入 850 表示 85.0°C固件里要除以 10 再存到浮點變量寫回傳感器時再乘回 16 倍換算成寄存器的 0.0625°C 單位。單位不統(tǒng)一是現(xiàn)場參數(shù)錯亂的高頻原因我建議在代碼里把所有溫度值統(tǒng)一成“0.1°C 有符號整型”到了傳感器驅(qū)動層再單獨換算。嵌入式設備內(nèi)部通訊如果走 CAN則更簡單每 100ms 發(fā)送一幀 CAN 標準幀ID 前 8 位是設備類型后面數(shù)據(jù)字節(jié)放本地溫度、遠程溫度、報警標志??偩€節(jié)點少的話不需要復雜的網(wǎng)絡管理只要約定好數(shù)據(jù)格式即可。4.3 多點校準與一致性傳感器出廠雖然做過校準但遠程通道的探頭安裝位置、導熱介質(zhì)、線路電阻都會影響最終讀數(shù)。在 HVAC 和嵌入式現(xiàn)場我強烈建議做一次“系統(tǒng)級校準”而不僅僅是芯片級校準。校準流程我一般這樣做把遠程探頭的感溫端和一只標準溫度探頭綁在一起放在同一個恒溫環(huán)境里。分別在 0°C、25°C、50°C或者項目關(guān)心的下限、中間、上限三點讀取 PJ85718DM 遠程溫度值。用最小二乘法擬合出實際溫度 測量溫度 × k b 的系數(shù)把 k 和 b 存在 STM32F042C6 的 Flash 里。固件每次上報前調(diào)用這段校正公式而不是直接上報原始轉(zhuǎn)換值。如果應用場景溫度范圍不大也可以只做單點偏移校正。但要注意只調(diào)整偏移不調(diào)整增益在距離中心溫度較遠的位置可能依然有偏差。比如 HVAC 設備冬季遠程溫度在零下夏季在 60°C跨度大就必須兩到三點校正。導熱介質(zhì)也是容易忽略的誤差來源。遠程探頭感溫部分要用導熱硅脂和被測物體充分接觸不能留空氣間隙。空氣的導熱系數(shù)很低會造成明顯滯后和偏低讀數(shù)?,F(xiàn)場如果是測水管外壁還要先清除表面的銹漬和水垢否則測量的是“銹層溫度”而非“管壁溫度”。5. 實測中的坑與排查辦法5.1 溫度讀數(shù)跳變幾十度過一會兒又恢復這個現(xiàn)象我在第一次做遠程測溫時碰到過。表面看是數(shù)字亂跳用示波器看發(fā)現(xiàn)遠程通道波形上疊加了尖峰。排查順序如下確認遠程三極管基極和集電極確實短接。如果只是用一個普通二極管接法不對就可能出現(xiàn)異常。檢查 D、D- 走線是否和繼電器驅(qū)動線、電源線平行。如果平行長度長嘗試換層、加寬間距。在 D、D- 對地加 100pF 到 220pF 電容看跳變是否減小。如果數(shù)據(jù)還是亂跳把遠程探頭線斷開用短跳線直接在板載焊盤上接入測溫管排除長線問題。這個問題的本質(zhì)是遠程模擬信號太容易被干擾。和普通數(shù)字 I2C 不一樣遠程二極管測量是一個微弱的模擬量你沒法靠“重發(fā)一次數(shù)據(jù)”來補救必須在硬件端就把噪聲抑制住。5.2 I2C 總線掛死傳感器不回 ACK現(xiàn)象是主控讀取超時SCL 正常SDA 一直是低電平。這種情況多數(shù)是系統(tǒng)剛上電、總線上有其他設備搶占了通信或者 SDA 在通信過程中被干擾拉低。我用的恢復方法是“總線時鐘脈沖恢復法”void recover_i2c_bus(void) { GPIO_InitTypeDef gpio {0}; gpio.Mode GPIO_MODE_OUTPUT_OD; gpio.Pull GPIO_PULLUP; gpio.Speed GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(SDA_GPIO_Port, gpio); for (int i 0; i 10; i) { HAL_GPIO_WritePin(SCL_Pin, GPIO_PIN_RESET); delay_us(5); HAL_GPIO_WritePin(SCL_Pin, GPIO_PIN_SET); delay_us(5); } HAL_GPIO_WritePin(SDA_Pin, GPIO_PIN_SET); MX_I2C1_Init(); // 重新初始化硬件外設 }這個辦法利用 SCL 時鐘沿讓掛死的從機釋放 SDA成功率比較高。但如果傳感器徹底死機脈沖不起作用就需要掉電重啟傳感器。所以我在硬件設計上給 PJ85718DM 的電源加了一個由 GPIO 控制的負載開關(guān)。真到需要復位傳感器的時候只需要把 GPIO 拉低再拉高不用整個系統(tǒng)斷電。這一點在 HVAC 現(xiàn)場特別重要因為設備一旦運行斷電重啟需要停機會造成很大的麻煩。能單獨復位傳感器比復位整個控制器好太多。5.3 低溫環(huán)境下讀數(shù)偏高的“假高溫”有次在冷庫設備里傳感器裝在控制柜內(nèi)控制柜在冷庫內(nèi)部遠程探頭貼在蒸發(fā)器盤管上。調(diào)試時發(fā)現(xiàn)遠程溫度始終比現(xiàn)場溫度高 3°C 左右而且很穩(wěn)定。后來發(fā)現(xiàn)是冷庫環(huán)境里空氣相對濕度很大遠程探頭感溫部分和導熱硅脂暴露在潮濕空氣中表面結(jié)了一層冰水混合物等效熱阻變大導致傳感器感知的不是盤管壁溫而是冰層外面的溫度。解決辦法并不神秘把探頭感溫部分用高強度導熱膠密封起來再壓緊在管壁上接線端子涂抹防凝露硅膠控制柜內(nèi)加一點小功率加熱防止 PCB 直接結(jié)露。之后讀數(shù)就和參考溫度一致了。HVAC 設備做溫度監(jiān)測安裝工藝常常比電路設計影響更大。5.4 遠程二極管選型導致的精度偏移我這里補充一個容易踩的坑PJ85718DM 的手冊通常會建議用 2N3904/2N3906 這類小信號三極管做遠程測溫探頭但現(xiàn)場如果采購替代料很可能買到貼片封裝、die 材料或者工藝參數(shù)差異較大的管子。替代料的 ideality factor 和手冊校正參數(shù)不匹配采集到的溫度會穩(wěn)定偏移有的甚至會偏移 2°C 以上。處理方式有兩種嚴格按推薦型號采購不隨意替代。遠程溫度探頭是整個系統(tǒng)里的極小成本項沒必要在這里省幾毛錢。如果必須替代就在固件里開放一個遠程通道增益校正參數(shù)通過遠程補償寄存器把誤差拉回來。前提是芯片支持 ideality factor 或 offset 補償PJ85718DM 這類芯片一般會有對應寄存器。我把常見現(xiàn)象和排查方法整理成了表格方便現(xiàn)場用現(xiàn)象可能原因處理辦法遠程溫度讀數(shù)明顯偏高/偏低且穩(wěn)定遠程三極管型號不匹配、導熱不良按推薦型號更換重新涂導熱膠本地溫度正常遠程溫度跳變D/D- 受干擾加濾波電容調(diào)整布線溫度讀數(shù)為 0 或全 1傳感器未初始化、I2C 地址錯檢查地址引腳讀回寄存器驗證I2C 通信超時總線掛死用 SCL 脈沖恢復必要時重啟傳感器現(xiàn)場溫度正常上報溫度滯后探頭熱阻大、安裝位置不當改善接觸減小熱阻最后再分享一個小技巧這套方案真正穩(wěn)定運行之后我反而舍不得刪掉調(diào)試階段留下的一組“原始值日志”。就是每次把 PJ85718DM 的本地溫度高字節(jié)、遠程溫度高字節(jié)、報警狀態(tài)原樣打進日志和經(jīng)過程序轉(zhuǎn)換后的溫度值放在一起。線上設備一旦出現(xiàn)保護動作先看原始寄存器就知道是傳感器數(shù)據(jù)本身出錯還是后端的濾波、轉(zhuǎn)換、閾值比較環(huán)節(jié)出了問題。另一個小經(jīng)驗是給遠程探頭預留一個“開路自檢”流程。當遠程 D、D- 懸空時芯片一般能返回一個明顯異常的溫度值比如 -64°C 或者 127°C。固件里判斷到這種情況直接把對應通道標記為故障而不是把異常溫度送進控制邏輯。否則 HVAC 設備在運行中探頭線斷掉控制邏輯可能會誤以為溫度過低持續(xù)加熱釀成事故。溫度監(jiān)測系統(tǒng)最重要的不是把數(shù)據(jù)算得多么精確而是在傳感器異常時能“知道自己是異常的”。這一點做嵌入式的人越早明白越好。