測方案)
1. 項目緣起與整體設(shè)計思路嵌入式溫度監(jiān)測這件事說起來簡單做起來坑多。我最早接觸這類需求是在一個HVAC控制板的項目上當(dāng)時的需求很樸素板子上要同時盯著本地幾個發(fā)熱點的溫度還要通過總線把遠(yuǎn)端幾個溫區(qū)的數(shù)據(jù)收回來統(tǒng)一做風(fēng)機(jī)調(diào)速和告警判斷。選型的時候翻了不少器件手冊最后定下來用PJ85718DM做本地多路溫度采集配合MKV42F256VLH16這顆MCU做數(shù)據(jù)處理和遠(yuǎn)程溫度數(shù)據(jù)的匯聚轉(zhuǎn)發(fā)。這套組合不是拍腦袋定的背后有幾層考量。先說PJ85718DM。它是一顆多通道遠(yuǎn)程溫度傳感器核心能力是支持多路遠(yuǎn)端二極管連接的測溫通道同時自身也集成了一路本地溫度檢測。遠(yuǎn)端測溫的原理是利用二極管的基極-發(fā)射極電壓與溫度之間的線性關(guān)系通過交替注入不同電流、測量電壓差來反推溫度。這種方式的好處是測溫點可以物理上遠(yuǎn)離主控板把二極管或者三極管接在需要監(jiān)測的位置比如換熱器表面、風(fēng)道出口、功率器件散熱片上用雙絞線拉回來就行。HVAC場景里測溫點分散是常態(tài)這個特性非常關(guān)鍵。再說MKV42F256VLH16。這顆MCU屬于主流工業(yè)級ARM Cortex-M系列主頻夠用外設(shè)資源豐富尤其是I2C、SPI、UART這些通信接口給得很足Flash和RAM容量對于跑溫度采集、濾波算法、簡單的PID風(fēng)機(jī)控制來說綽綽有余。它在這套方案里的角色是“中樞”通過I2C總線周期性讀取PJ85718DM的本地和遠(yuǎn)端溫度寄存器做數(shù)據(jù)校驗和濾波然后根據(jù)預(yù)設(shè)閾值驅(qū)動PWM輸出控制風(fēng)機(jī)同時把溫度數(shù)據(jù)打包通過UART或者CAN發(fā)給上位機(jī)。整體設(shè)計思路可以概括成三層感知層由PJ85718DM和外圍的測溫二極管組成負(fù)責(zé)把物理溫度轉(zhuǎn)換成數(shù)字量處理層由MKV42F256VLH16承擔(dān)負(fù)責(zé)輪詢采集、數(shù)據(jù)濾波、邏輯判斷執(zhí)行與通信層包括PWM風(fēng)機(jī)驅(qū)動、告警輸出、以及向上位機(jī)上報數(shù)據(jù)的通信接口。這三層各司其職耦合度低后期要擴(kuò)展測溫通道或者改通信協(xié)議都比較方便。為什么不用MCU自帶的ADC加熱敏電阻的方案熱敏電阻便宜但精度和一致性差尤其是多點測溫時每個點都要單獨校準(zhǔn)量產(chǎn)標(biāo)定工作量巨大。PJ85718DM這類專用遠(yuǎn)程溫度傳感器出廠一致性做得好遠(yuǎn)端二極管測溫的誤差可以控制在正負(fù)1度以內(nèi)而且支持串聯(lián)電阻補(bǔ)償長線纜帶來的誤差也能修掉。對于HVAC這種對溫度精度有一定要求、又要求長期穩(wěn)定運行的場景專用傳感器方案的綜合成本其實更低。注意遠(yuǎn)端測溫二極管的選擇有講究。普通開關(guān)二極管的一致性不夠好建議用專門為測溫設(shè)計的二極管連接三極管比如把集電極和基極短接當(dāng)二極管用這種器件的溫度系數(shù)更穩(wěn)定。2. 核心器件細(xì)節(jié)與硬件設(shè)計要點2.1 PJ85718DM的通道配置與寄存器操作PJ85718DM的寄存器映射是理解這顆芯片的鑰匙。它內(nèi)部有一組配置寄存器、一組溫度數(shù)據(jù)寄存器、還有狀態(tài)寄存器和限值寄存器。上電后第一件事是配置寄存器設(shè)定遠(yuǎn)端通道的使能、轉(zhuǎn)換速率、以及是否開啟串聯(lián)電阻補(bǔ)償。轉(zhuǎn)換速率這個參數(shù)直接決定了功耗和響應(yīng)速度的平衡HVAC場景里溫度變化慢一般設(shè)成1Hz到4Hz就夠了沒必要跑太高。溫度數(shù)據(jù)寄存器是16位格式高字節(jié)是整數(shù)部分低字節(jié)是小數(shù)部分分辨率可以到0.0625度。讀的時候要連續(xù)讀兩個字節(jié)先讀高字節(jié)再讀低字節(jié)中間不能被打斷否則數(shù)據(jù)會錯位。我踩過一次坑用中斷方式讀I2C結(jié)果在讀完高字節(jié)后被一個高優(yōu)先級中斷打斷等回來讀低字節(jié)時芯片已經(jīng)更新了數(shù)據(jù)導(dǎo)致整數(shù)和小數(shù)部分來自不同采樣周期溫度值跳變。后來改成用DMA一次性搬兩個字節(jié)問題解決。遠(yuǎn)端通道的串聯(lián)電阻補(bǔ)償也值得說。長線纜本身有電阻測溫二極管上流過的電流會在線阻上產(chǎn)生壓降導(dǎo)致測到的電壓偏高算出來的溫度就偏低。PJ85718DM內(nèi)部有補(bǔ)償機(jī)制可以通過配置寄存器設(shè)定補(bǔ)償電阻的值芯片在計算時會自動扣除這部分影響。補(bǔ)償電阻的估算方法是量出線纜單程電阻乘以2得到回路電阻再根據(jù)芯片手冊給出的補(bǔ)償步進(jìn)值換算成寄存器配置值。實測下來用一米左右的普通雙絞線補(bǔ)償電阻設(shè)成幾十毫歐量級就能把誤差壓到0.5度以內(nèi)。2.2 MKV42F256VLH16的外設(shè)分配與時鐘規(guī)劃MKV42F256VLH16在這套方案里要同時處理好幾件事I2C讀傳感器、PWM驅(qū)動風(fēng)機(jī)、UART上報數(shù)據(jù)、可能還有定時器做周期調(diào)度。外設(shè)分配要提前規(guī)劃好避免引腳沖突。我的分配方案是I2C1接PJ85718DM速率設(shè)成100kHz標(biāo)準(zhǔn)模式線纜不長的話400kHz快速模式也能跑PWM用TIM1的通道1和通道2分別驅(qū)動兩路風(fēng)機(jī)頻率設(shè)成25kHz這個頻率高于人耳聽覺范圍風(fēng)機(jī)不會發(fā)出嘯叫UART2用于調(diào)試和上報波特率115200TIM2做1ms系統(tǒng)滴答用于任務(wù)調(diào)度和超時計數(shù)。時鐘規(guī)劃容易被忽視。MKV42F256VLH16的主頻可以跑到比較高的水平但外設(shè)時鐘是分頻出來的。I2C時鐘如果分頻不當(dāng)實際速率會偏離設(shè)定值導(dǎo)致通信不穩(wěn)定。我的做法是先確定系統(tǒng)時鐘然后反推各外設(shè)的分頻系數(shù)確保I2C實際速率在90kHz到110kHz之間PWM頻率精確落在25kHz附近。這些參數(shù)在初始化代碼里都要算清楚不能隨手填。提示I2C總線上一定要接上拉電阻阻值根據(jù)總線電容和速率來選。100kHz速率下4.7k歐姆是常用值如果總線電容較大或者速率提到400kHz要減小到2.2k歐姆甚至更小。上拉電阻太大上升沿變緩?fù)ㄐ艜鲥e。2.3 測溫二極管的布局與走線遠(yuǎn)端測溫的精度很大程度上取決于二極管的布局和走線。二極管要盡量貼近被測點但又要避免直接貼在高壓或者大電流走線旁邊否則會引入噪聲。我的經(jīng)驗是如果測的是散熱片溫度二極管涂上導(dǎo)熱硅脂后用小夾子固定在散熱片表面引線用雙絞線絞距盡量密一些這樣能有效抑制共模干擾。走線方面測溫二極管的引線不要和PWM驅(qū)動線、繼電器控制線捆在一起走。PWM線的dv/dt很高耦合到測溫線上會直接反映成溫度讀數(shù)跳動。如果實在避不開就用屏蔽雙絞線屏蔽層單端接地。另外測溫線的長度也要控制太長的話線阻和分布電容都會影響測量一般建議不超過兩米。超過兩米的話除了開啟串聯(lián)電阻補(bǔ)償還要考慮降低I2C速率或者改用差分傳輸方案。3. 固件實現(xiàn)與核心環(huán)節(jié)拆解3.1 初始化流程與寄存器配置代碼固件的第一步是把MKV42F256VLH16的外設(shè)初始化好然后配置PJ85718DM。初始化順序有講究先配時鐘再配GPIO然后配I2C最后配PWM和UART。PJ85718DM的配置要在I2C初始化完成之后進(jìn)行配置內(nèi)容包括使能本地通道和遠(yuǎn)端通道、設(shè)定轉(zhuǎn)換速率、設(shè)定串聯(lián)電阻補(bǔ)償值、設(shè)定溫度限值寄存器。下面是一段配置PJ85718DM的偽代碼展示了關(guān)鍵寄存器的寫法// 假設(shè)I2C寫函數(shù)為 i2c_write(dev_addr, reg_addr, data) // PJ85718DM的I2C從機(jī)地址根據(jù)引腳配置確定 // 配置寄存器使能遠(yuǎn)端通道1和2本地通道使能轉(zhuǎn)換速率4Hz i2c_write(PJ85718_ADDR, CONFIG_REG, 0x0F); // 串聯(lián)電阻補(bǔ)償寄存器設(shè)定補(bǔ)償值 i2c_write(PJ85718_ADDR, SERIES_R_COMP, 0x08); // 遠(yuǎn)端通道1高溫限值設(shè)定為85度 i2c_write(PJ85718_ADDR, REMOTE1_HIGH_LIMIT, 0x55); // 遠(yuǎn)端通道1低溫限值設(shè)定為-20度 i2c_write(PJ85718_ADDR, REMOTE1_LOW_LIMIT, 0xEC);配置完成后芯片就開始周期性轉(zhuǎn)換溫度數(shù)據(jù)會更新到對應(yīng)的數(shù)據(jù)寄存器里。MCU只需要按需讀取即可不需要發(fā)命令觸發(fā)轉(zhuǎn)換。3.2 溫度數(shù)據(jù)讀取與濾波算法讀取溫度數(shù)據(jù)看起來簡單但要做好濾波才能得到穩(wěn)定的讀數(shù)。我的做法是每100ms讀一次所有通道的溫度連續(xù)讀8次去掉最大值和最小值剩下的取平均。這樣既能濾掉偶發(fā)的尖峰干擾又不會引入太大延遲。8次采樣在100ms周期內(nèi)完成相當(dāng)于每個通道的更新率是10Hz對于HVAC場景完全夠用。濾波算法用滑動窗口實現(xiàn)窗口大小設(shè)成8。每次新數(shù)據(jù)進(jìn)來替換掉最舊的數(shù)據(jù)然后重新計算平均值。為了省CPU可以維護(hù)一個累加和每次替換時減去舊值加上新值再除以窗口大小。這樣每次濾波只需要一次減法和一次加法效率很高。溫度數(shù)據(jù)的格式轉(zhuǎn)換也要注意。PJ85718DM返回的是16位有符號數(shù)高字節(jié)是整數(shù)部分低字節(jié)的高四位是小數(shù)部分。轉(zhuǎn)換公式是溫度 (高字節(jié) * 256 低字節(jié)) / 256.0。如果高字節(jié)的最高位是1表示負(fù)溫度要先做符號擴(kuò)展再計算。我見過有人直接拿高字節(jié)當(dāng)整數(shù)用結(jié)果負(fù)溫度全錯這種低級錯誤在調(diào)試時很浪費時間。3.3 風(fēng)機(jī)控制邏輯與PWM輸出風(fēng)機(jī)控制是這套方案的核心執(zhí)行環(huán)節(jié)。邏輯不復(fù)雜根據(jù)溫度讀數(shù)查表或者做線性插值算出目標(biāo)PWM占空比然后更新PWM寄存器。但有幾個細(xì)節(jié)要注意。第一PWM占空比的變化要平滑不能突變否則風(fēng)機(jī)會發(fā)出明顯的轉(zhuǎn)速變化聲體驗很差。我的做法是每次更新時限制變化量比如每次最多變化2%這樣從0到100%需要50個控制周期按100ms周期算就是5秒過渡很自然。第二要設(shè)置啟動占空比。風(fēng)機(jī)在低占空比下可能轉(zhuǎn)不起來尤其是含油軸承的風(fēng)機(jī)啟動扭矩不夠。我的經(jīng)驗是啟動占空比設(shè)成30%左右等轉(zhuǎn)起來之后再降到目標(biāo)值。這個邏輯可以用狀態(tài)機(jī)實現(xiàn)檢測到需要啟動時先輸出30%占空比持續(xù)500ms然后切換到正??刂啤5谌卸罗D(zhuǎn)檢測。如果PWM輸出正常但溫度持續(xù)上升可能是風(fēng)機(jī)堵轉(zhuǎn)或者損壞??梢酝ㄟ^檢測風(fēng)機(jī)反饋信號如果有或者觀察溫度變化趨勢來判斷。沒有反饋信號的話可以設(shè)定一個超時如果PWM占空比已經(jīng)加到80%以上但溫度在30秒內(nèi)沒有下降就觸發(fā)告警。3.4 遠(yuǎn)程溫度數(shù)據(jù)的匯聚與上報遠(yuǎn)程溫度數(shù)據(jù)通過UART或者CAN上報給上位機(jī)。協(xié)議設(shè)計要簡單可靠我一般用自定義的二進(jìn)制幀格式幀頭兩個字節(jié)然后是通道號、溫度值、狀態(tài)標(biāo)志最后是校驗和。幀頭用0xAA和0x55不容易和數(shù)據(jù)混淆。校驗和用累加和取反計算簡單檢錯能力夠用。上報周期根據(jù)上位機(jī)需求定一般1秒一次就夠了。如果溫度變化快可以縮短到200ms。上報的時候要把本地溫度和所有遠(yuǎn)端溫度都帶上上位機(jī)拿到完整的數(shù)據(jù)才能做全局判斷。如果某個通道讀取失敗要在狀態(tài)標(biāo)志里標(biāo)明上位機(jī)看到標(biāo)志就知道這個通道的數(shù)據(jù)不可信。注意UART通信要做好錯誤處理。如果連續(xù)多次收到校驗錯誤的幀或者發(fā)送緩沖區(qū)滿要有相應(yīng)的處理邏輯不能死等。我的做法是發(fā)送用DMA加環(huán)形緩沖區(qū)發(fā)送完成中斷里更新緩沖區(qū)指針主循環(huán)里檢查是否有數(shù)據(jù)要發(fā)這樣不會阻塞主循環(huán)。4. 常見問題與排查技巧實錄4.1 溫度讀數(shù)跳變或明顯偏差溫度讀數(shù)跳變是最常見的問題。原因可能有幾種I2C通信受干擾導(dǎo)致數(shù)據(jù)錯位、測溫二極管引線耦合了噪聲、電源紋波太大影響傳感器內(nèi)部基準(zhǔn)。排查的時候先看跳變的規(guī)律如果是隨機(jī)跳變多半是通信干擾如果是周期性跳變可能是PWM或者繼電器動作時耦合進(jìn)來的。我的排查步驟是先用示波器看I2C的SCL和SDA波形確認(rèn)上升沿是否干凈、有沒有過沖或者振鈴。如果波形不好先調(diào)上拉電阻和線纜。然后看測溫二極管引線附近有沒有大電流走線有的話挪開或者加屏蔽。最后檢查電源用示波器看傳感器供電引腳上的紋波如果超過50mV要加LC濾波或者換LDO。還有一種情況是讀數(shù)整體偏高或偏低但很穩(wěn)定。這通常是串聯(lián)電阻補(bǔ)償沒設(shè)對或者測溫二極管的溫度系數(shù)和芯片預(yù)期的不一致。解決辦法是拿一個標(biāo)準(zhǔn)溫度計做參考在已知溫度下校準(zhǔn)。校準(zhǔn)的時候至少取兩個點比如0度和50度算出偏移量和增益誤差然后在固件里做補(bǔ)償。4.2 I2C通信失敗或時斷時續(xù)I2C通信失敗的原因很多我整理了一個排查表現(xiàn)象可能原因排查方法解決措施完全無應(yīng)答從機(jī)地址錯、供電缺失、引腳接反用示波器看SDA是否有拉低核對地址、量供電、檢查引腳偶爾NACK總線電容大、上拉電阻不合適看波形上升沿時間減小上拉電阻、縮短線纜數(shù)據(jù)錯位中斷打斷讀時序、時鐘拉伸未處理檢查讀函數(shù)是否原子操作改用DMA、處理時鐘拉伸總線鎖死從機(jī)異常拉低SDA量SDA電平加總線恢復(fù)邏輯、復(fù)位從機(jī)總線鎖死是個棘手問題。如果從機(jī)在傳輸過程中異常復(fù)位可能會一直拉低SDA導(dǎo)致總線無法恢復(fù)。解決辦法是在I2C初始化時加一段恢復(fù)邏輯把SCL配置成GPIO手動發(fā)送9個時鐘脈沖然后發(fā)送停止條件這樣能強(qiáng)制從機(jī)釋放總線。這個邏輯在量產(chǎn)固件里一定要有否則現(xiàn)場偶發(fā)的總線鎖死會導(dǎo)致整個系統(tǒng)失效。4.3 遠(yuǎn)端測溫通道讀數(shù)異常遠(yuǎn)端通道讀數(shù)異常通常和二極管本身或者連線有關(guān)。如果某個通道讀數(shù)一直是滿量程或者零先檢查二極管是否接反或者損壞。用萬用表二極管檔量一下正向壓降應(yīng)該在0.5V到0.7V之間。如果讀數(shù)偏高很多可能是二極管開路芯片檢測到開路后會輸出一個特定值通常是最高溫度值作為標(biāo)志。如果讀數(shù)偏低可能是二極管兩端并了電容或者受到了漏電流影響。測溫二極管的反向漏電流會隨溫度升高而增大如果漏電流太大會影響測量精度。解決辦法是選漏電流小的二極管或者在二極管兩端并聯(lián)一個電阻給漏電流提供通路。電阻值一般選1M歐姆左右太小會影響測量太大起不到作用。還有一個容易被忽視的問題多個遠(yuǎn)端通道共用一根地線時地線上的壓降會串?dāng)_到測溫回路。如果每個通道的電流不同地線壓降就不同導(dǎo)致通道間相互影響。解決辦法是每個測溫通道用獨立的回線或者在軟件里做通道間補(bǔ)償。硬件上做星型接地是最穩(wěn)妥的。4.4 風(fēng)機(jī)控制異常與PWM輸出問題風(fēng)機(jī)不轉(zhuǎn)或者轉(zhuǎn)速異常先確認(rèn)PWM輸出是否正常。用示波器量PWM引腳看頻率和占空比是否符合預(yù)期。如果PWM正常但風(fēng)機(jī)不轉(zhuǎn)可能是驅(qū)動電路問題比如MOSFET沒導(dǎo)通、續(xù)流二極管接反、或者風(fēng)機(jī)本身損壞。如果PWM頻率不對檢查定時器配置特別是預(yù)分頻和自動重載值有沒有算錯。風(fēng)機(jī)轉(zhuǎn)速波動大通常是控制周期太短或者濾波不夠。溫度采樣本身有噪聲如果直接用單次采樣值算PWM占空比就會跟著噪聲跳。解決辦法是加長濾波窗口或者對PWM變化做斜率限制。我一般用滑動平均加變化率限制效果很好。還有一種情況是風(fēng)機(jī)在低速時發(fā)出異響。這通常是PWM頻率落在了人耳敏感區(qū)間或者占空比太低導(dǎo)致風(fēng)機(jī)電流不連續(xù)。把PWM頻率提到20kHz以上同時保證最低占空比不低于20%基本能解決。5. 實操心得與擴(kuò)展思路這套方案我在幾個不同的HVAC控制板上都用過積累了一些文檔里不會寫的經(jīng)驗。第一個心得是PJ85718DM的本地通道其實很有用可以用來監(jiān)測MCU或者板子附近的溫度作為環(huán)境溫度參考。如果本地溫度和遠(yuǎn)端溫度差異很大說明板子本身發(fā)熱嚴(yán)重可能需要加散熱或者調(diào)整布局。第二個心得是MKV42F256VLH16的Flash容量足夠可以把溫度限值、風(fēng)機(jī)曲線這些參數(shù)做成可配置的存在Flash的特定區(qū)域通過UART命令修改。這樣現(xiàn)場調(diào)試的時候不用重新燒固件改幾個參數(shù)就行效率高很多。參數(shù)存儲要做好校驗和備份防止Flash損壞導(dǎo)致參數(shù)丟失。第三個心得是I2C總線上可以掛多個PJ85718DM通過地址引腳區(qū)分。如果測溫通道不夠用直接再加一顆就行固件里把通道號映射改一下。但要注意總線電容掛太多器件會導(dǎo)致上升沿變緩這時候要么降低速率要么加I2C緩沖器。擴(kuò)展方面這套架構(gòu)很容易加上濕度傳感器或者壓力傳感器I2C總線上再掛幾個從機(jī)就行。如果要做聯(lián)網(wǎng)控制可以在UART上接一個通信模塊把數(shù)據(jù)轉(zhuǎn)發(fā)到云端。MKV42F256VLH16的運算能力還有富余跑一個簡單的Modbus協(xié)議棧完全沒問題。后續(xù)如果要加PID閉環(huán)控制風(fēng)機(jī)現(xiàn)在的PWM和溫度采集框架直接就能用只需要把控制邏輯從查表改成PID計算就行。最后分享一個調(diào)試小技巧在固件里加一個溫度數(shù)據(jù)日志功能把每次采樣的原始值和濾波后的值都存到RAM緩沖區(qū)里通過UART導(dǎo)出來用Excel畫曲線。這樣能直觀地看到濾波效果和干擾情況比盯著串口打印的數(shù)字有用得多。我靠這個辦法發(fā)現(xiàn)過好幾次偶發(fā)的干擾問題都是靠肉眼看數(shù)字發(fā)現(xiàn)不了的。