測系統(tǒng)設(shè)計與HVAC部署復(fù)盤)
前陣子接了一套暖通空調(diào)的溫度監(jiān)測改造現(xiàn)場情況是主控板放在電控柜里要測柜內(nèi)溫度、回風(fēng)溫度還要把風(fēng)管末端、室外機附近幾個點的溫度遠程匯聚到同一塊板子上。開始我也想圖省事直接上NTC加ADC后來算完精度和布線成本還是定了PJ85718DM加STM32F303RC這套方案。整套做下來從選型、硬件鏈路、固件處理到現(xiàn)場調(diào)校里面有不少東西值得記下來這篇就當(dāng)作一次完整復(fù)盤。1. 項目為什么盯上PJ85718DM STM32F303RC選型邏輯與系統(tǒng)定位1.1 溫度監(jiān)測看起來很簡單為什么還要專用方案很多嵌入式項目里測溫度最簡單粗暴的做法是NTC熱敏電阻加ADC采樣便宜、電路簡單幾毛錢就能搞定。但HVAC現(xiàn)場和桌面實驗不太一樣一是溫度點分散控制柜、風(fēng)管、回風(fēng)口、冷媒管可能隔了幾十米模擬信號長距離拉線會被電機啟停的干擾帶著跑ADC讀數(shù)跳來跳去二是空調(diào)系統(tǒng)對穩(wěn)定性和一致性要求高溫差一兩度可能直接影響到壓縮機啟停策略和舒適度判斷三是現(xiàn)場維護的人不一定懂電路傳感器壞了最好能直接上報而不是讓調(diào)試人員拿萬用表去量分壓電阻。所以這個案子從一開始就不打算走模擬量方案。數(shù)字溫度傳感器天然帶總線地址多個傳感器能掛一條總線上數(shù)據(jù)直接給到MCU省掉一堆運放和校準(zhǔn)電阻。PJ85718DM就是一顆很典型的I2C/SMBus接口數(shù)字溫度傳感器工業(yè)級精度能覆蓋-40℃到125℃的量程對HVAC來說綽綽有余。配上STM32F303RC整套系統(tǒng)就脫離了“搭個電路試試”的階段往產(chǎn)品化的方向走了。1.2 PJ85718DM這類總線式數(shù)字溫度傳感器能解決什么PJ85718DM這類芯片最核心的價值是把溫度變成數(shù)字量而且這顆芯片是有SMBus兼容能力的意味著它不只給MCU讀還能被其他主機設(shè)備查詢。芯片內(nèi)部自帶ADC和溫度寄存器主機只需要通過I2C時序去讀寄存器不用管模擬前端怎么處理。對這個項目來說它解決了三個具體問題。第一一致性問題每顆芯片出廠前做過校準(zhǔn)芯片間偏差可以壓到很小不像NTC還要逐路做分壓電阻匹配和查表校準(zhǔn)。第二抗干擾問題溫度信號在芯片內(nèi)部就完成數(shù)字化總線上傳輸?shù)氖请娖椒D(zhuǎn)的時鐘和數(shù)據(jù)不是緩慢變化的模擬電壓對電機、變頻器產(chǎn)生的共模干擾沒那么敏感。第三地址擴展問題PJ85718DM這類芯片一般有多個地址引腳通過硬件上拉或下拉可以配置出多個可用地址一條I2C總線上掛幾顆、十幾顆不是問題正好符合這個項目“本地加遠程多點測溫”的需求。我也看到有人問為什么不用MCU內(nèi)部溫度傳感器這里要說清楚內(nèi)部傳感器測的是芯片結(jié)溫不是環(huán)境溫度。電機驅(qū)動板上的MCU本身發(fā)熱加上功率器件熱傳導(dǎo)結(jié)溫和真實室溫能差出好幾度拿來估環(huán)境溫度根本不合格。真要省掉外部傳感器除非你只做芯片過熱保護不做HVAC溫度控制。1.3 主控為什么選STM32F303RC而不是更常見的F103選主控的時候有人提過用F103便宜量大資料多。但我最后還是定了F303RC理由有三。第一F303是Cortex-M4內(nèi)核帶FPU。HVAC系統(tǒng)里除了讀溫度往往還要跑PID控制、做風(fēng)量計算、處理電機電流反饋F4內(nèi)核的單精度浮點運算能力比M3強不少后面想加邏輯控制和故障診斷算法不用換平臺。第二F303的定時器和模擬外設(shè)配置很豐富尤其是電機控制相關(guān)的資源。暖通系統(tǒng)里壓縮機和風(fēng)機的控制是重頭戲這次只做測溫但板子后續(xù)要往一控多路電機、變頻調(diào)速方向擴展F303這套外設(shè)組合能省下重新選型的功夫。第三F303RC的供電和引腳兼容性也友好3.3V單電源就能工作I2C外設(shè)引腳可以做重映射方便我在布線的時候把I2C和RS-485的引腳分開避開電機驅(qū)動的強干擾區(qū)。當(dāng)然選型不是為了堆料而是讓系統(tǒng)在“當(dāng)前夠用、后續(xù)有擴展空間”這個平衡點上。如果只做單點測溫、純實驗室環(huán)境F103甚至8位單片機都夠但凡是跟暖通設(shè)備湊在一起我建議主控選的時候還是多留點余量。2. 從“感溫點”到“控制板”本地與遠程測溫的硬件鏈路設(shè)計2.1 本地測溫I2C短距直連的幾個布局要點本地測溫指的是傳感器就在主控板附近距離在幾十厘米以內(nèi)。這個場景我直接用PJ85718DM的I2C接口做主控和傳感器之間的物理連接板內(nèi)走線傳感器可以放在板子上也可以引一小段排線到機殼表面。這里有三個實際經(jīng)驗想分享。第一I2C的上拉電阻不能照搬開發(fā)板。開發(fā)板上通常用4.7kΩ但如果你把傳感器通過排線引出線間電容變大4.7kΩ的上拉會拖慢上升沿導(dǎo)致通信不穩(wěn)定。我實測在30cm排線下上拉改成2.2kΩ通信穩(wěn)很多。如果傳感器離主控更遠上拉還要繼續(xù)減小但也不能太小否則灌電流變大接口電平容易出問題。第二傳感器底下別鋪完整的地銅皮。很多畫板習(xí)慣是打滿地過孔、鋪地銅來抗干擾但PJ85718DM這類傳感器對自身發(fā)熱很敏感鋪地銅等于把整個板子的熱量導(dǎo)到傳感器附近讀數(shù)會偏高。我給傳感器底下做了鏤空處理留一個小的熱隔離島讓它只感知空氣溫度。第三傳感器旁邊不要放電源穩(wěn)壓芯片或功率電阻。電源芯片本身燙加上PCB導(dǎo)熱幾十秒就能讓傳感器讀數(shù)往上升1℃到2℃這個誤差在HVAC控制里非常致命。2.2 遠程測溫RS-485總線匯聚與傳感器節(jié)點組織方式遠程測溫是這個項目的重頭戲。風(fēng)管末端、室外機附近、水泵房這些點離主控板動輒幾十米甚至上百米直接用I2C拉長線是不現(xiàn)實的。一是SDA/SCL的容性負(fù)載太大時序根本跑不起來二是長線本身就是天線電機啟動的瞬態(tài)干擾能直接打穿電平閾值。我的做法是遠端傳感器各自組成小節(jié)點每個節(jié)點用PJ85718DM就近感知溫度然后通過UART轉(zhuǎn)RS-485收發(fā)器把數(shù)據(jù)送回主控板。RS-485是差分信號抗共模干擾能力強布線用雙絞線最遠距離做到幾百米沒壓力完全覆蓋暖通現(xiàn)場。節(jié)點內(nèi)部結(jié)構(gòu)很簡單一片MCU負(fù)責(zé)讀PJ85718DM或者直接把PJ85718DM掛到485節(jié)點板上由節(jié)點MCU讀回溫度后再通過RS-485協(xié)議上報。我這里采用了后者每個節(jié)點板上都有獨立的MCU好處是傳感器數(shù)據(jù)處理和總線通信解耦單個節(jié)點出問題不會拖垮整條總線。總線上用主從模式主控板做主機每個節(jié)點分配一個地址比如01、02、03...主機定時輪詢。波特率選9600或19200這個檔位在長線上更穩(wěn)雖然看起來慢但溫度數(shù)據(jù)本身變化慢一秒輪詢一輪幾十個點根本用不完帶寬。RS-485布線還有個老生常談的細節(jié)總線兩端要加120Ω終端電阻而且只在物理首尾兩端加中間節(jié)點不要加。很多人圖省事在每個節(jié)點都焊上電阻結(jié)果阻抗不匹配反射信號疊加數(shù)據(jù)錯亂排查起來頭疼。2.3 供電、線與接地的細節(jié)容易翻車的三個地方遠程節(jié)點的供電我踩過坑。最初圖簡單直接從主控板拉5V到遠端結(jié)果壓降嚴(yán)重距離一長傳感器工作電壓掉到4V以下讀數(shù)開始漂。后來給每個節(jié)點用獨立的24V轉(zhuǎn)5V DC-DC再在節(jié)點板上做LDO濾波穩(wěn)定多了。如果項目允許盡量就近取電電壓等級統(tǒng)一用24V暖通現(xiàn)場很多執(zhí)行器本來就用24V取電方便。RS-485的A、B線要用雙絞線屏蔽層單端接地。屏蔽層千萬別兩端都接地否則屏蔽層和大地之間形成環(huán)路感應(yīng)電流竄進來比不接地還糟。我走線時讓雙絞線遠離變頻器輸出線至少保持30cm以上的間距交叉的地方垂直穿過不平行走線。還有地電位差的問題??刂乒窭锏牡睾瓦h端風(fēng)機基坑里的地并不一定是等電位兩端的參考地可能差十幾伏。RS-485收發(fā)器通常能承受-7V到12V的共模電壓但如果設(shè)備接地做得很差這個電壓也能被突破。穩(wěn)妥起見我給板子上的485部分做了隔離用隔離電源和數(shù)字隔離器把信號和主控側(cè)分開實測在電柜和遠端風(fēng)機之間電壓差明顯的情況下通信依然穩(wěn)定。隔離的成本高一點但在工業(yè)現(xiàn)場值得。3. 固件側(cè)的關(guān)鍵實現(xiàn)從寄存器讀取到數(shù)據(jù)可靠化3.1 基礎(chǔ)讀取流程與寄存器理解PJ85718DM這類數(shù)字溫度傳感器的固件操作看起來簡單就是讀寄存器但有幾個細節(jié)決定穩(wěn)不穩(wěn)。先看基礎(chǔ)流程初始化時配置I2C外設(shè)時鐘設(shè)到100kHz或400kHz。400kHz通常沒問題但如果PCB走線質(zhì)量一般、線比較長我建議降到100kHz寧可慢一點也要穩(wěn)。配置芯片的工作模式、報警閾值等參數(shù)然后周期性讀取溫度寄存器。讀取代碼大致是這個樣子#define TEMP_SENSOR_ADDR 0x48 // 具體地址依硬件配置而定 /* * 讀取16位溫度寄存器原始值 */ uint8_t temp_sensor_read_reg(uint8_t reg, uint16_t *raw) { uint8_t tx[1] {reg}; uint8_t rx[2] {0}; // 發(fā)送寄存器地址 HAL_I2C_Master_Transmit(hi2c1, TEMP_SENSOR_ADDR 1, tx, 1, 50); // 連續(xù)讀2字節(jié) HAL_I2C_Master_Receive(hi2c1, TEMP_SENSOR_ADDR 1, rx, 2, 50); if (raw) { *raw (rx[0] 8) | rx[1]; } return 0; } /* * 原始值轉(zhuǎn)換為溫度保留小數(shù) */ float temp_sensor_to_celsius(uint16_t raw) { int16_t s_raw (int16_t)raw; return (float)s_raw * 0.0078125f; // 16位 / 7.8125m℃ }這里最需要留意的是高低字節(jié)的順序。不同廠家的芯片有的先高字節(jié)后低字節(jié)有的反過來不查手冊直接用示例代碼讀出來的溫度會是一個極其離譜的“負(fù)數(shù)”這個我遇到過不止一次。另外芯片默認(rèn)寄存器可能有“未啟動轉(zhuǎn)換”的狀態(tài)上電后要給一點時間等首次轉(zhuǎn)換完成再讀否則第一次采樣值為空或為0。3.2 滑動平均濾波與異常值剔除溫度傳感器讀出來的原始值就算本身精度沒問題在暖通現(xiàn)場也會出現(xiàn)毛刺。尤其當(dāng)風(fēng)機變頻器啟動時瞬間電流沖擊大到足以干擾傳感器內(nèi)部ADC。我一開始直接拿原始值去控制邏輯結(jié)果溫度曲線上經(jīng)常出現(xiàn)單點跳變PID控制器跟著一抖一抖壓縮機頻繁加卸載。解決辦法是老生常談的滑動平均濾波但要注意窗口大小。溫度變化本來就慢我用每秒采一次、窗口取16個點也就是16秒內(nèi)的平均值。這個窗口既能濾掉突發(fā)干擾又不會把真實變化拖得太過分。如果窗口取64甚至更長空調(diào)溫度已經(jīng)明顯變化了顯示和控制還鈍鈍的用戶體驗很差。代碼很簡單typedef struct { float buf[16]; uint8_t idx; float sum; } sliding_filter_t; float sliding_filter_push(sliding_filter_t *f, float v) { f-sum - f-buf[f-idx]; f-buf[f-idx] v; f-sum v; f-idx (f-idx 1) % 16; return f-sum / 16; }除了濾波還要做異常值剔除。我參照了近三年采樣值的統(tǒng)計特征溫度跳變超過5℃且下一秒又跳回基本可以判定是干擾或通信錯誤。我用一個計數(shù)器記錄連續(xù)異常次數(shù)超過閾值就進入傳感器故障狀態(tài)而不是把臟數(shù)據(jù)送進控制鏈。這個邏輯是很多教程里不會提的但在現(xiàn)場極其重要否則一個干擾脈沖就可能讓機組錯誤動作。3.3 故障識別與看門狗保護保證系統(tǒng)不死機HVAC設(shè)備通常連續(xù)運行沒人隔三差五盯著控制板。所以固件里必須自帶診斷能力。我實現(xiàn)了三類故障判斷傳感器通信失敗、溫度值越界、溫度變化速率異常。通信失敗是I2C從機無響應(yīng)連續(xù)5次讀取超時直接上報“傳感器離線”。溫度值越界是指讀出來的溫度超過合理物理范圍比如低于-50℃或高于130℃肯定是數(shù)據(jù)鏈路出問題了。跳躍過大就進入“傳感器惡化”預(yù)警狀態(tài)提醒現(xiàn)場人員檢查探頭??撮T狗層面用了IWDG獨立看門狗主循環(huán)里喂狗。RS-485總線偶爾被異常幀占住、程序卡在某個阻塞等待里看門狗能在1秒內(nèi)把系統(tǒng)拉回來。同時每輪讀完所有溫度點后把最新數(shù)據(jù)快照存到備份寄存器重啟后能直接恢復(fù)上次的數(shù)據(jù)狀態(tài)不會讓上層控制器拿到一組初始化默認(rèn)溫度。#define IWDG_RELOAD_VALUE 4095 void watchdog_init(void) { // 使能獨立看門狗預(yù)分頻 /64約1秒超時 IWDG-KR 0x5555; IWDG-PR 0x04; IWDG-RLR IWDG_RELOAD_VALUE; IWDG-KR 0xAAAA; IWDG-KR 0xCCCC; } void main_loop(void) { while (1) { // 主邏輯處理各個傳感器數(shù)據(jù) temp_sensor_process_all(); comm_rs485_process(); // 一切正常后喂狗 IWDG-KR 0xAAAA; } }4. 現(xiàn)場實測與調(diào)校復(fù)盤誤差、串?dāng)_與經(jīng)驗教訓(xùn)4.1 實測數(shù)據(jù)與誤差分析系統(tǒng)做完后我拿了標(biāo)準(zhǔn)溫度計在幾個測溫點上做了對比。在室溫25℃左右的環(huán)境中PJ85718DM讀數(shù)與標(biāo)準(zhǔn)溫度計偏差在±0.3℃以內(nèi)這個精度對HVAC控制完全夠用。但是在風(fēng)管上、電機附近的點位偏差明顯變大最大到過1.2℃。挨個查原因發(fā)現(xiàn)主要不是芯片問題而是安裝方式造成的一是傳感器探頭直接貼在風(fēng)管金屬壁上風(fēng)管本身溫度受冷凍水影響測出來的其實是管壁溫度不是空氣溫度這是“測點錯了”不是“測不準(zhǔn)”二是探頭線束和電機電源線綁在一起走了半米雖然傳感器抗干擾能力強但線束耦合的噪聲還是會在I2C時序上造成毛刺偶爾出現(xiàn)一個跳變點。針對這兩類誤差的解決辦法我總結(jié)成一個表誤差來源現(xiàn)象對策傳感器貼金屬壁讀數(shù)遲緩、偏差大探頭懸空安裝保持2cm以上空氣隙線束與動力線平行偶發(fā)數(shù)據(jù)跳變重新走線強弱電分開供電電壓偏低讀數(shù)整體偏高且漂移獨立供電加LDO穩(wěn)壓傳感器自發(fā)熱靜態(tài)溫度偏高PCB挖空隔熱降低轉(zhuǎn)換頻率4.2 兩個現(xiàn)場典型問題解決過程第一個問題出在RS-485總線上。剛裝完時輪詢到第6個節(jié)點返回的數(shù)據(jù)偶爾會丟幀但重新上電又恢復(fù)正常過一會又出現(xiàn)非常隱蔽。我折騰了很久換了好幾套線后來發(fā)現(xiàn)是節(jié)點地址配置問題有兩個傳感器節(jié)點被撥碼開關(guān)設(shè)成了同一個地址雖然我設(shè)計時允許多個地址但現(xiàn)場有人把撥碼撥錯了。兩臺設(shè)備同時應(yīng)答總線瞬間沖突產(chǎn)生亂幀。排查出來以后我把地址映射表和撥碼關(guān)系打印出來貼在控制柜門上這個問題才算徹底根除。這件事給我最大的教訓(xùn)硬件故障排除前先把配置檢查三遍接口層的軟件問題往往比硬件問題多得多。第二個問題在本地I2C上。運行一段時間后主控讀取傳感器偶發(fā)超時用示波器抓SDA波形發(fā)現(xiàn)波形邊沿很緩上升時間明顯超限。原因是傳感器通過長排線引出后線間電容變大上拉電阻還是最初板上的4.7kΩ。我把上拉改成2.2kΩ后波形立刻變干凈超時問題消失了。后來這塊布局上也多了一版優(yōu)化把傳感器的位置直接挪到接線端子附近縮短排線長度治標(biāo)治本。4.3 標(biāo)定與出廠校準(zhǔn)的思路PJ85718DM這類芯片出廠前已經(jīng)做了校準(zhǔn)正常情況下不需要用戶再做兩點標(biāo)定但對精度有更高要求或者現(xiàn)場有系統(tǒng)偏差時可以通過軟件做補正。我的做法是在恒溫環(huán)境中記錄芯片讀數(shù)和參考值的偏差得到零點偏差offset然后在另一個溫度點再測一次得到增益偏差gain。之后每幀溫度都用這個線性公式補償float temp_corrected(float temp_raw) { // offset 和 gain 在標(biāo)定時寫入Flash return (temp_raw - offset) * gain; }標(biāo)定流程沒有想象中復(fù)雜拿一個已知準(zhǔn)的溫度計放在探頭旁邊靜置15分鐘熱平衡后記錄兩組數(shù)據(jù)就能算出offset和gain。如果項目采購批次穩(wěn)定一組標(biāo)定參數(shù)可以復(fù)用到整批設(shè)備上。要注意的是傳感器探頭材質(zhì)不同貼裝方式不同標(biāo)定參數(shù)會有一定出入追求極致精度時每個通道單獨標(biāo)定更穩(wěn)妥。5. 在HVAC場景里部署這套系統(tǒng)的維護經(jīng)驗5.1 傳感器布點與探頭封裝的選擇現(xiàn)場布點對最終效果的影響比選哪顆芯片更大。風(fēng)管測溫探頭要插到風(fēng)管中心不能貼著管壁管壁溫度受外界環(huán)境影響嚴(yán)重?;仫L(fēng)口的探頭要避開新風(fēng)直接吹到的位置否則測的是新風(fēng)溫度而不是回風(fēng)溫度。室外機附近的探頭要加防輻射罩防止太陽直射導(dǎo)致讀數(shù)偏高。探頭封裝有幾種形式裸芯片適合PCB板載測溫帶不銹鋼套管的適合插風(fēng)管帶防水頭的適合水管表面。HVAC現(xiàn)場灰塵大、濕度高我推薦優(yōu)先使用帶護套的封裝既保護芯片又方便現(xiàn)場固定。裸芯片直接裸露在濕空氣中引腳容易氧化腐蝕時間一長讀數(shù)飄得厲害。5.2 長期運行的漂移判斷與巡檢方式數(shù)字傳感器雖然不像模擬電路那樣容易老化漂移但長期運行在潮濕、溫差大的環(huán)境里可能會因為引腳氧化或探頭內(nèi)部進水導(dǎo)致數(shù)據(jù)異常。我給系統(tǒng)加了巡檢機制每隔一段時間自動對比傳感器讀數(shù)和設(shè)備啟動前的基準(zhǔn)值如果差值越來越大就提示“校準(zhǔn)維護”?,F(xiàn)場的巡檢方式也很簡單拿一個手持溫度計貼近傳感器探頭位置待讀數(shù)穩(wěn)定后和后臺數(shù)據(jù)對比偏差超過1℃就觸發(fā)標(biāo)定流程。這個工作建議每季度做一次尤其在空調(diào)換季啟停頻繁的時候傳感器受冷凝水影響概率最大。5.3 擴展思路接入樓宇自控或云端這套系統(tǒng)的數(shù)據(jù)鏈路是現(xiàn)成的后期擴展不用推翻重來。RS-485總線可以接上協(xié)議網(wǎng)關(guān)把溫度數(shù)據(jù)轉(zhuǎn)發(fā)到樓宇自控系統(tǒng)讓上位機統(tǒng)一管理。如果想上云端加一塊帶以太網(wǎng)或Wi-Fi的模塊把主控采集到的溫度打包成JSON上報就能做遠程監(jiān)控和歷史趨勢分析。STM32F303RC的資源比純測溫應(yīng)用要求的富余很多我后來還在同一個主控上接了風(fēng)機的啟??刂坪碗娏鞅O(jiān)測實現(xiàn)了溫度與風(fēng)機聯(lián)動的閉環(huán)整套系統(tǒng)的價值比單純“看溫度”高了一個檔次。如果你也在做類似的嵌入式測溫項目建議一開始就給主控留點升級空間別把代碼寫得太“省”后面加功能會舒服很多。最后再分享一個小建議這種多節(jié)點測溫系統(tǒng)做固件時一定要把各個傳感器通道的原始值、濾波值、故障狀態(tài)用日志或調(diào)試串口輸出出來現(xiàn)場排查時能省一半的時間。數(shù)據(jù)和現(xiàn)象對不上時先懷疑物理鏈路再懷疑軟件邏輯順序別搞反。