設計)
做嵌入式和 HVAC 項目的朋友幾乎都會遇到溫度采集這件事。一類是設備本地的溫度比如控制板安裝環(huán)境溫度、壓縮機表面溫度另一類是遠程的溫度比如風道末端、送回風口、房間內部這些布線距離比較遠的位置。前陣子我配合某設備廠商做溫控節(jié)點核心就是標題里的兩個器件PJ85718DM 數(shù)字溫度傳感器加一顆 STM32F205RB 控制芯片把本地溫度直接讀出來遠程溫度再通過 RS485/Modbus 匯總上報。這套方案不算復雜但把采集、濾波、通信、校準整個鏈路走通里面值得記錄的細節(jié)非常多。這篇文章會把整個項目從頭到尾拆開講。不管你是在做 HVAC 溫控器、嵌入式數(shù)據(jù)采集終端還是想學怎么用 I2C 溫度傳感器加 Modbus 做多點測溫都能直接照著搭。我會把選型原因、硬件接線、驅動代碼、濾波處理、遠程通信、實測數(shù)據(jù)、坑點排查全部寫出來盡量讓沒做過的人也能一次落地。1. 先從需求說起嵌入式和 HVAC 到底要測哪里的溫度1.1 本地溫度和遠程溫度分別解決什么問題很多剛接觸 HVAC 項目的人會有個誤區(qū)溫度采集不就是把傳感器插到設備里讀個數(shù)值嗎實際上本地溫度和遠程溫度是兩類完全不同的問題。本地溫度通常指控制器自身周圍、壓縮機殼體、換熱器管壁、配電柜內部這些位置。它距離 MCU 很近導線長度通常不超過幾十厘米用 I2C 接口的數(shù)字傳感器非常合適。好處是傳感器直接輸出數(shù)字量不需要額外搭放大電路或做冷端補償抗干擾能力也強。這類溫度主要用來做設備保護比如壓縮機排氣溫度超過設定值就降載甚至停機或者根據(jù)管壁溫度判斷除霜時機。遠程溫度則是安裝在風道、回風口、房間溫控面板、室外補償溫度探頭這些需要長距離布線的位置。這些地方離主控板可能隔著十幾米甚至上百米I2C 在這種距離下根本跑不起來信號完整性會非常差。所以遠程測溫的常規(guī)做法是在每個遠端位置放一個小節(jié)點板節(jié)點板上有 MCU 和傳感器采集到溫度后通過 RS485 總線傳回主控。RS485 是差分信號抗干擾能力強標準應用下能到 1200 米這正好覆蓋 HVAC 項目的典型布線距離。所以標題里“本地與遠程溫度”不是一句廢話它代表了兩條完全不同的信號鏈路。一個項目里同時處理好這兩條鏈路才能做出真正能用的溫控系統(tǒng)。1.2 這個項目適合誰參考我建議下面幾類人重點看這篇文章做 HVAC 控制器、樓宇自控、工業(yè)溫控箱的嵌入式工程師這套方案可以直接落地。正在學習 STM32 和 I2C 傳感器驅動的開發(fā)者可以拿這個項目當完整練手案例。想了解 Modbus RTU 從機怎么實現(xiàn)、怎么和觸摸屏或組態(tài)軟件對接的人第 4 章有代碼拆解。經(jīng)常被溫度數(shù)據(jù)跳變、通信不穩(wěn)定折磨的現(xiàn)場調試人員第 5 章和第 6 章的實測與排查記錄應該能幫上忙。我自己當年做類似項目時最頭疼的不是讀溫度而是讀出來的溫度不可信、傳不出去、或者現(xiàn)場跑幾天就漂了。這些問題大多不是芯片本身的問題而是電路細節(jié)、濾波策略和通信時序沒處理好。下面這些內容就是我踩過坑之后總結出來的。2. 選型與整體方案為什么是 PJ85718DM STM32F205RB2.1 傳感器選型對比為什么不用 NTC 和 PT100溫度傳感器這塊市面上最常見的是 NTC 熱敏電阻、PT100 鉑電阻、以及各類數(shù)字溫度傳感器。我?guī)涂蛻糇龇桨笗r通常先問三個問題測量范圍多少、精度要求多少、現(xiàn)場有沒有強干擾。回答完這三個問題再決定用哪種。NTC 成本最低很多家電溫控器都在用。但 NTC 是非線性的而且同一批次之間的阻值離散性也不小。要做好更換不標定的產品基本必須用電橋加編程校準表B 值一變整個曲線就偏了。我并不是否定 NTC在溫度范圍窄、精度要求不高、單點定標能接受的產品里它仍然是最經(jīng)濟的選擇。但如果我們做的是對精度和一致性有要求的 HVAC 節(jié)點我不想把大量生產校準成本轉移到溫控邏輯里。PT100 精度高能到 ±0.1℃ 甚至更高但需要恒流源或電橋電路、儀表放大器、ADC還要考慮導線電阻補償硬件成本一點都不低。PT100 適合做實驗室級或者工業(yè)級標準溫度計用在分布式測溫節(jié)點上每個節(jié)點的物料成本和 PCB 面積都會失控。PJ85718DM 這種數(shù)字溫度傳感器就適合在這兩者之間找到一個平衡點。它本身集成了溫度敏感元件和 ADC直接通過 I2C 輸出數(shù)字量。單芯片方案不需要外圍放大精度一般能做到 ±0.5℃ 以內分辨率可以達到 0.0078125℃。對 HVAC 環(huán)境監(jiān)測來說這個精度綽綽有余風道和房間溫度的控制精度通常在 ±1℃ 到 ±2℃?zhèn)鞲衅鞅旧淼恼`差遠小于控制回路的動作閾值。另外要說明的是PJ85718DM 這個型號可能不像 NTC 那樣人人熟悉我拿到實物后的理解是它是一顆 I2C 接口、16 位溫度寄存器輸出的數(shù)字傳感器工作電壓 3.3V 或 5V 都能兼容默認 7 位地址是 0x48 那一檔實際以你手里的數(shù)據(jù)手冊為準。如果你拿到的批次寄存器映射稍有差異不影響整體架構只需要把驅動里讀寄存器的地址改一下就行。2.2 STM32F205RB 扮演什么角色STM32F205RB 是 Cortex-M3 內核主頻最高 120MHzFlash 是 1MBRAM 是 128KB。對于溫度采集這種任務來說這個配置其實是富余的。那為什么還要選它因為我在這個項目里不只是讀一個溫度還要同時管理 RS485 通信、看門狗、狀態(tài)指示燈、本地存儲甚至以后可能加 Ethernet 或 USB 轉串口升級。F205 這顆芯片有幾個點很對我的胃口。第一它有多個硬件 I2C 和 USART 外設I2C1 接傳感器USART2 接 RS485 收發(fā)器外設之間不沖突代碼也不需要在同一個中斷里來回切換。第二它支持 DMAUSART 的收發(fā)可以用 DMA 搬運配合 Modbus RTU 的幀收發(fā)可以明顯降低 CPU 占用。第三它有足夠的 IO 和定時器資源后期哪怕要加兩路 PWM 控制風機轉速也不至于重新選型。有人可能會問用一顆更低端的芯片是不是也行比如 F103 系列。答案是看項目定位。F103 當然能跑同樣的邏輯但 F205 在 I2C 外設的穩(wěn)定性、SRAM 容量、DMA 通道數(shù)量上都要好一些。如果你做的是批量 HVAC 控制器追求極致成本F103 也完全撐得住但如果你做的是高端樓宇自控節(jié)點需要更充裕的資源跑后續(xù)功能F205 是更穩(wěn)妥的選擇。我這次用的正是 F205RB。2.3 系統(tǒng)布局本地采集、遠程上報的整體鏈路整個系統(tǒng)的結構可以理解為三層。第一層是本地采集層。STM32F205RB 通過 I2C 總線直接讀 PJ85718DM 的溫度數(shù)據(jù)。這里 I2C 線的長度建議控制在 30cm 以內傳感器盡量靠近主控板。如果傳感器模塊需要延長用屏蔽線并在傳感器端加 0.1uF 去耦電容否則在變頻器附近很容易讀到毛刺。第二層是遠程節(jié)點接入層。每個遠端測溫點放一塊小從機板板上有 STM32 最小系統(tǒng)、PJ85718DM、RS485 收發(fā)器。從機板負責采集本地溫度并在收到主站請求時把溫度數(shù)據(jù)返回。這里的“本地”是相對于從機板而言的實際上它也是遠程節(jié)點。第三層是集中管理上報層。主控板作為 Modbus 主站通過 RS485 總線輪詢各個從機節(jié)點。主站把各點溫度匯總后可以傳給觸摸屏、組態(tài)軟件或者再通過以太網(wǎng)上傳到樓宇管理平臺。這樣客戶在值班室就能看到每個風道口、每個房間的溫度變化。說句實在話這種“從機采集 主站輪詢”的結構是 HVAC 行業(yè)最通用的方案因為 Modbus RTU 幾乎被所有觸摸屏和組態(tài)軟件原生支持不需要寫私有協(xié)議也不用裝額外驅動。項目驗收時客戶用一根 USB 轉 485 線就能看到數(shù)據(jù)說服力很強。3. 硬件設計從傳感器到 MCU 再到遠程總線的完整鏈路3.1 傳感器接線與電源設計PJ85718DM 的引腳不多通常包括 VDD、GND、SDA、SCL有些封裝還會引出一根 AD0 地址選擇腳。VDD 直接接 3.3VGND 就近回地SDA 和 SCL 各接一顆上拉電阻到 3.3V。上拉電阻的取值很有講究。我剛開始做的時候用 10kΩ 上拉結果 I2C 時鐘一提高到 400kHz 就經(jīng)常傳輸出錯波形上升沿太慢。后來換成 4.7kΩ問題立刻消失。如果你的板子比較緊湊、走線較短1.8kΩ 也可以但不要低于 1kΩ否則灌電流偏大對芯片 IO 不太友好。電源方面要特別注意傳感器盡量不要直接從 MCU 的 VDD 引腳上再拉一根線供電。MCU 引腳電流變化比較大尤其是驅動繼電器或者指示燈時電源噪聲會耦合到溫度數(shù)據(jù)里。我的習慣是用一個小功率 LDO 單獨給傳感器供電或者至少在傳感器 VDD 引腳旁邊并聯(lián)一顆 1uF 陶瓷電容和一顆 0.1uF 高頻去耦電容兩者配合使用。多次實測下來這樣做能把溫度數(shù)據(jù)的隨機跳變減少一半以上。另外如果傳感器模塊是成品模塊板上一般自帶濾波電容和上拉電阻。自己做板子時PCB 布線要保證傳感器底下不要鋪大塊地銅避免雜散電容影響 SCL 波形。傳感器盡量靠近 MCU 引腳讓 I2C 走線保持短、直、左右有地線包裹。3.2 RS485 遠程通信電路要點RS485 收發(fā)器我用的是 SP3485 這類 3.3V 供電的芯片直接和 STM32F205RB 的 USART 引腳連接不需要電平轉換。收發(fā)器的 A、B 引腳接到接線端子對外走雙絞線。這里有幾個細節(jié)特別容易翻車我逐個說一下。第一A、B 之間要并接 120Ω 終端電阻。這個電阻放在總線最遠端作用是吸收反射信號。如果總線上只有兩塊板而且距離很短不接也能跑但距離一超過幾十米或節(jié)點一多不接就會偶發(fā)幀錯誤。終端電阻的計算很簡單雙絞線的特征阻抗通常在 120Ω 左右終端電阻等于特征阻抗時反射最小。第二收發(fā)器的 DE 和 RE 引腳要連到一起由 MCU 的一個 GPIO 控制。發(fā)送數(shù)據(jù)前拉高發(fā)送完再拉低切回接收。切換時機如果不對最后幾個字節(jié)會出現(xiàn)截斷。我一般發(fā)完最后一個字節(jié)后延時 1 個字符時間再拉低或者干脆用發(fā)送中斷里加個延時。你也可以用硬件自動收發(fā)電路但我覺得用 GPIO 控制更直觀、排查問題更方便。第三A、B 線上要加 TVS 管防止現(xiàn)場長線感應雷擊或電機啟停造成的浪涌損壞收發(fā)器。HVAC 現(xiàn)場經(jīng)常有變頻器、風機、水泵這些設備啟停瞬間會產生很強的干擾這個問題我在第 6 章還會單獨說。RS485 總線布線建議用屏蔽雙絞線屏蔽層單端接地。如果是多節(jié)點總線要手拉手連接絕對不能搞成星形星形會產生大量反射。這是個老生常談的問題但現(xiàn)場施工時幾乎每回都要強調一遍因為很多施工隊習慣就近接線。3.3 樣機焊接與布局注意事項如果是自己打樣調試焊接傳感器之前先確認引腳定義最好用萬用表量一下 VDD 和 GND防止反接把芯片燒掉。PJ85718DM 這類貼片芯片很小焊接時焊臺溫度控制在 350℃ 左右時間要短。我見過有人焊了太久溫度傳感器被烙鐵烤偏了零點常溫下讀數(shù)比正常高了 2 度后來怎么軟件校準都不穩(wěn)定最后換了一顆芯片才好。MCU 核心板的選擇上如果不想自己畫板直接買帶 STM32F205RB 的最小系統(tǒng)板也行但一定要確認 3.3V 電源干凈。有些開發(fā)板的 LDO 紋波比較大在做溫度采集時表現(xiàn)出來就是讀數(shù)最后一位不停跳動換一塊供電穩(wěn)定的板子立刻就好。板子上如果有繼電器、蜂鳴器這些感性負載它們的電源要和傳感器供電分開走線地線盡量采用單點接地。這樣做能減少地彈噪聲對 ADC 和 I2C 的影響。雖然是“經(jīng)驗之談”但在現(xiàn)場調試時往往就是這些細節(jié)決定成敗。4. 軟件實現(xiàn)驅動、濾波與遠程通信代碼拆解4.1 I2C 驅動讀取溫度軟件上第一步是把傳感器讀出來。我用 STM32 的 HAL 庫打開 I2C1主機模式時鐘設成 100kHz 先跑通后面再提速到 400kHz。讀溫度寄存器的邏輯很簡單先發(fā)送寄存器地址再讀兩個字節(jié)把兩個字節(jié)拼成 16 位整數(shù)最后按分辨率系數(shù)轉成溫度值。#define PJ85718DM_ADDR 0x48 #define REG_TEMP 0x00 int16_t read_temp_raw(void) { uint8_t reg REG_TEMP; uint8_t buf[2]; if (HAL_I2C_Master_Transmit(hi2c1, PJ85718DM_ADDR, reg, 1, 100) ! HAL_OK) { return INT16_MIN; // 返回無效值交給上層處理 } if (HAL_I2C_Master_Receive(hi2c1, PJ85718DM_ADDR, buf, 2, 100) ! HAL_OK) { return INT16_MIN; } return (int16_t)((buf[0] 8) | buf[1]); } float read_temp_celsius(void) { int16_t raw read_temp_raw(); if (raw INT16_MIN) { return -999.0f; // 用明顯異常值表示讀取失敗 } // 這里以 16 位分辨率 0.0078125℃/LSB 為例 return raw * 0.0078125f; }這段代碼有幾個地方要解釋一下。第一I2C 地址為什么是 0x48 左移位之后的格式HAL 庫里的地址參數(shù)是 8 位地址也就是包含讀寫位的格式7 位地址 0x48 需要左移一位變成 0x90才能和 HAL 庫的讀寫位拼接正確。我上面的寫法會有人直接用宏不同人的寫法可能差一位這點特別容易坑。你寫代碼時用數(shù)據(jù)手冊里的地址配合 HAL 庫時記得左移或者直接查你手上例程的定義。第二讀到的 raw 值是帶符號的因為寬溫度范圍下負溫會出現(xiàn)最高位為 1 的情況。如果我把它定義成 uint16_t零下溫度轉換出來會變成很大的正數(shù)后臺顯示一團亂麻。所以用 int16_t 接收再轉 float。第三為什么溫度轉換系數(shù)是 0.0078125因為分辨率是 1/128 0.0078125也就是 16 位溫度寄存器的最低位表示 0.0078125℃。如果你的芯片數(shù)據(jù)手冊寫明精度是 12 位、13 位或 14 位轉換公式要按實際有效位調整不能盲目套。讀取周期方面HVAC 溫度變化慢我把讀溫度放在 1s 定時中斷里觸發(fā)。如果需要更快響應可以縮短到 200ms但對大多數(shù)風道、房間溫度來說沒必要反而會讓濾波更難做。4.2 溫度數(shù)據(jù)處理均值濾波與防毛刺直接讀出來的溫度值往往不能直接用因為現(xiàn)場有變頻器、開關電源這些干擾源原始數(shù)據(jù)偶爾會冒出一個明顯偏大的尖峰。我在項目里用了兩重處理第一重是滑動平均濾波用來平滑隨機噪聲第二重是限幅判斷用來剔除明顯毛刺?;瑒悠骄拇a可以直接看下面的實現(xiàn)#define FILTER_SIZE 8 static float temp_hist[FILTER_SIZE]; static uint8_t temp_idx 0; static uint8_t temp_count 0; float temp_sliding_avg(float new_sample) { float sum 0.0f; uint8_t i; temp_hist[temp_idx] new_sample; temp_idx (temp_idx 1) % FILTER_SIZE; if (temp_count FILTER_SIZE) { temp_count; } for (i 0; i temp_count; i) { sum temp_hist[i]; } return sum / temp_count; }用 8 個樣本做平均1s 讀一次的話就是 8s 平滑窗口。對 HVAC 來說這個響應速度完全足夠而且曲線會非常漂亮。如果你要做壓縮機保護這種對快速響應有要求的場景可以把窗口縮到 4 個樣本或者干脆不做平均直接用原始值只是再疊加一道限幅濾波。限幅濾波的核心思想是“上次合法值和這次采樣值之差超過一個閾值就認為是毛刺”。比如正常溫度變化在 0.5℃/s那設置變化閾值 2℃ 已經(jīng)足夠寬松。一旦檢測到突變直接丟棄這次采樣用上次值代替。float temp_anti_glitch(float new_sample) { static float last_valid 25.0f; const float max_step 2.0f; if (fabsf(new_sample - last_valid) max_step) { return last_valid; } last_valid new_sample; return new_sample; }實際調試時我先把毛刺日志全部打出來看是周期性的還是偶發(fā)的。如果是周期性尖峰多半是周圍有開關動作和 I2C 時鐘重疊如果是偶發(fā)可能是電源抖動。命令先抓波形再改參數(shù)“拍腦袋”加濾波參數(shù)只會掩蓋問題不會根治問題。4.3 Modbus RTU 從機通信實現(xiàn)遠程節(jié)點上跑的協(xié)議我直接用 Modbus RTU。它是 Modbus 協(xié)議在串行鏈路上的標準實現(xiàn)幀格式是地址 功能碼 數(shù)據(jù) CRC16。每個從機節(jié)點有一個唯一的地址主站發(fā)請求幀從機地址匹配后回響應幀。我用功能碼 03 讀保持寄存器來開放溫度數(shù)據(jù)。保持寄存器規(guī)劃如下寄存器地址內容說明0x0000本地溫度整數(shù)部分例如 23℃0x0001本地溫度小數(shù)部分例如 0.450℃0x0002設備狀態(tài)bit0 傳感器在線bit1 通信正常0x0003固件版本例如 0x0101 表示 v1.01溫度用整數(shù)加小數(shù)兩部分存是為了避免浮點數(shù)在 Modbus 寄存器里表示時的字節(jié)序爭議。上位機拿到兩個寄存器后拼成 23.450℃。這種方法最直觀也最容易和第三方組態(tài)軟件對接。Modbus 從機核心處理邏輯可以寫成這樣uint16_t crc16_modbus(uint8_t *data, uint16_t len) { uint16_t crc 0xFFFF; uint16_t i; while (len--) { crc ^ *data; for (i 0; i 8; i) { if (crc 0x0001) { crc (crc 1) ^ 0xA001; } else { crc 1; } } } return crc; } void modbus_rtu_poll(void) { uint8_t rxbuf[32]; uint16_t rxlen 0; uint16_t crc_rev, crc_cal; // 這里假設 USART 中斷已經(jīng)按幀接收到 rxbuf并解析出 rxlen if (rxlen 8) { return; } // 檢查從機地址 if (rxbuf[0] ! SLAVE_ADDR) { return; } // 校驗 CRC注意 Modbus RTU 的 CRC 低字節(jié)在前 crc_rev (uint16_t)(rxbuf[rxlen - 1] 8) | rxbuf[rxlen - 2]; crc_cal crc16_modbus(rxbuf, rxlen - 2); if (crc_rev ! crc_cal) { return; } // 功能碼 03讀保持寄存器 if (rxbuf[1] 0x03) { uint16_t start_reg (rxbuf[2] 8) | rxbuf[3]; uint16_t reg_count (rxbuf[4] 8) | rxbuf[5]; uint8_t resp[64]; uint8_t pos 0; uint16_t crc_send; resp[pos] SLAVE_ADDR; resp[pos] 0x03; resp[pos] (uint8_t)(reg_count * 2); for (uint16_t i 0; i reg_count; i) { uint16_t reg_val get_holding_register(start_reg i); resp[pos] (uint8_t)(reg_val 8); resp[pos] (uint8_t)(reg_val 0xFF); } crc_send crc16_modbus(resp, pos); resp[pos] (uint8_t)(crc_send 0xFF); resp[pos] (uint8_t)(crc_send 8); // 發(fā)送響應 usart_send_bytes(resp, pos); } }CRC16 的實現(xiàn)網(wǎng)上有很多版本我每次都是拿一個已知幀去驗證比如請求幀01 03 00 00 00 02 C4 0B如果算出來的 CRC 等于 C4 0B說明算法正確。這個習慣非常重要因為 CRC 寫錯會導致所有從機都不響應而排查 CRC 問題非常費時間。從機地址、波特率這些參數(shù)我習慣用配置項放在程序開頭方便現(xiàn)場更改。波特率固定用 9600 或者 19200。HVAC 項目對速度要求不高9600 反而抗干擾更好因為同樣一幀數(shù)據(jù)占的時間更長抗瞬時干擾能力更強。5. 實測過程與數(shù)據(jù)表現(xiàn)5.1 本地測溫精度測試硬件焊接完、驅動跑通后要做系統(tǒng)的溫度準確性驗證。我把節(jié)點板和一顆經(jīng)過計量的標準鉑電阻溫度計放在同一個恒溫環(huán)境里分別測了三個溫度點冰水混合物 0℃、室溫 25℃、恒溫槽 50℃。實測結果大概是這樣標準溫度℃PJ85718DM 讀數(shù)℃偏差℃0.000.250.2525.0024.80-0.2050.0050.150.15單顆芯片的偏差在 ±0.25℃ 左右滿足 HVAC 環(huán)境監(jiān)測的 ±1℃ 要求。如果你碰到偏差比較固定且大頭在同一方向的可以先做軟件校準。校準方法很簡單就是兩點校正冰水混合物是天然的 0℃ 標準器再把傳感器放到一個穩(wěn)定的溫水槽里用高精度溫度計記錄實際溫度然后算出增益系數(shù)和偏移量。公式就是標準的線性修正修正值 原始讀數(shù) * 增益 偏移先測到兩個點的原始讀數(shù)和標準溫度解二元一次方程組就能算出增益和偏移。校準參數(shù)存到 STM32 的 Flash 里每次上電讀取這樣傳感器一致性就能拉平。5.2 遠程讀取驗證遠程通信這塊我用 USART 轉 USB 線把主站和從機連起來先用 PC 上的串口工具直接發(fā) Modbus 幀測試。給從機 1 發(fā)讀取幀請求01 03 00 00 00 02 C4 0B從機響應01 03 04 00 17 00 0F CRC解析一下數(shù)據(jù)寄存器 0x0000 是 0x0017十進制 23表示 23℃寄存器 0x0001 是 0x000F十進制 15表示 0.015℃這里要看你小數(shù)部分是存多少位。如果約定小數(shù)部分存的是千分位那 0x000F 就是 0.015℃不太對應該等于 0.450℃。這里我特意提醒一下兩個寄存器拼接時必須確認高位在前還是低位在前以及小數(shù)位數(shù)的約定。我在項目里習慣用“整數(shù)部分 千分位小數(shù)部分”比如 23.450℃ 就存成寄存器 0x0000 23寄存器 0x0001 450。這樣既不會丟精度上位機拼接也簡單。測試時如果發(fā)現(xiàn)溫度差得離譜先查是不是這里拼接錯了而不是懷疑協(xié)議寫錯。5.3 現(xiàn)場安裝位置與熱耦合技巧HVAC 項目里測溫點位選在哪對控制效果的影響比傳感器精度還大。我的體會是“測得到”不等于“測得準”。比如回風溫度傳感器如果離送回風口太近測到的其實是混合后的溫度而不是房間典型溫度風道溫度傳感器如果貼在外壁上測量的其實是管道壁溫度跟空氣溫度差好幾度。安裝時一般要把傳感器的感溫部分盡量伸進氣流中間或者緊貼管壁并加導熱硅脂。如果傳感器探頭裝在鋁制套管里套管和傳感器之間一定要填充導熱材料空氣層的導熱系數(shù)很低會導致響應變慢、讀數(shù)滯后。另一個容易忽略的是太陽輻射。室外補償溫度探頭如果被陽光直射讀數(shù)會偏高好幾度必須加遮陽罩。我見過一個項目室外探頭裝在屋面中午比實際溫度高 5℃導致系統(tǒng)不停地調節(jié)最后排查了半天才發(fā)現(xiàn)是太陽直射的問題。6. 常見問題與排查技巧實錄6.1 讀不到溫度或溫度跳變癥狀是 I2C 讀回的數(shù)值要么一直是 0xFF要么值明顯亂跳。排查順序我建議按電流從外到內走。先用示波器或萬用表量傳感器 VDD 電壓確認是 3.3V 而不是 2.8V 之類。接著量 SCL 和 SDA 的波形看有沒有上下拉電阻。如果沒有上拉I2C 總線根本拉不高讀取必然失敗。如果波形正常但讀值亂跳多半是電源噪聲。在傳感器 VDD 和 GND 之間焊一個 10uF 電解電容和一個 0.1uF 陶瓷電容跳變問題通常能消除大半。還要看一下你的 I2C 時鐘是不是在傳感器允許的范圍內。有些傳感器最高只支持 400kHz你把它掛到 1MHz 就覺得“反正都是 I2C 應該能跑”這是不行的。6.2 遠程通信不穩(wěn)定RS485 通信不穩(wěn)定是我在 HVAC 現(xiàn)場遇到最多的問題。典型表現(xiàn)是主站偶爾收不到響應或者收到的數(shù)據(jù) CRC 校驗失敗。第一步檢查 A、B 兩根線是不是接反了。接反了通常完全不通但如果收發(fā)器內置偏置電阻有時也能通只是信號余量很差距離一長就周期性丟包。這種情況我用萬用表量 A、B 間的電壓正??臻e時在 0.2V 到 0.5V 左右如果接近 0V 或者負值基本判定接反或者缺少終端電阻。第二步檢查終端電阻。掛兩個節(jié)點以上且距離超過 50m總線兩端必須各并一個 120Ω 電阻。注意是“兩端”不是每個節(jié)點都接。如果每個節(jié)點都接了 120Ω總線上并聯(lián)電阻會太小收發(fā)器負載過重信號幅度被拉低照樣丟包。第三步是檢查接地。RS485 總線最好用屏蔽雙絞線屏蔽層在主機側單點接地。如果現(xiàn)場噪聲特別強比如旁邊有變頻器可以考慮在 A、B 之間加 TVS 管同時串聯(lián)兩個 10Ω 電阻限制電流尖峰。6.3 校準方法與系統(tǒng)聯(lián)調建議校準出來的參數(shù)要能覆蓋傳感器本身的分散性。生產線批量校準時不能只校單點因為單點校準只能修正偏移沒法修正斜率。兩點校準時第一點盡量靠近實際工作范圍的下限第二點靠近上限這樣全量程內誤差最小。系統(tǒng)聯(lián)調時我建議先做“最小系統(tǒng)調試”一塊主控板、一塊從機板、一個傳感器把從 I2C 讀到最終 RS485 返回的全鏈路跑通再逐步加節(jié)點。一次就把 10 個節(jié)點全掛上去出了問題很難定位。另外給每塊從機板刷寫地址時最好用一個獨立的小工具。地址重復是 Modbus 通信中非常隱蔽的問題兩個相同地址的從機同時響應主站收到的數(shù)據(jù)就是亂的而且 CRC 校驗時好時壞排查起來極其痛苦。我現(xiàn)在的習慣是在板子出廠前寫好地址標簽并在軟件里做一次地址沖突檢測每次上電時從機在總線上收到比自己地址低的所有節(jié)點都無響應后才允許進入工作狀態(tài)。這個邏輯雖然簡單但能省掉很多現(xiàn)場問題。還有個細節(jié)不要忽視看門狗。HVAC 現(xiàn)場偶爾會有非常強的電源跌落或電磁干擾導致 MCU 跑飛。沒有獨立看門狗的話從機可能一直死在那里主站怎么叫都不應。我將獨立看門狗超時設成 3 秒正常工作狀態(tài)下不停喂狗一旦死機就自動復位。這個功能看似不起眼但整個項目在客戶現(xiàn)場運行半年后你就會知道它有多重要。說到這我再分享一點自己的體會這類測溫項目真正體現(xiàn)功夫的地方往往不在芯片有多高級而在于把底層細節(jié)弄扎實。I2C 上拉、濾波窗口、CRC 校驗、終端電阻、安裝位置每一處看起來都是小事但每一處都可能在現(xiàn)場放大成故障。先保證數(shù)據(jù)采集可信再談通信穩(wěn)定最后做精度修正按這個順序去做項目的成功率會高很多。如果你也正在做類似的嵌入式或 HVAC 溫度監(jiān)測方案建議第一版先按我這套思路搭起來跑通之后再去優(yōu)化成本和尺寸。后面你還可以在這個基礎上擴展更多功能比如增加兩路 PWM 控制風機、加入在線校準、對接以太網(wǎng)網(wǎng)關等。等這些點都補齊了它就不僅僅是個溫度采集節(jié)點而是一個完整的 HVAC 邊緣控制器了。