滑動平均值濾波)
簡介面向S7-200SMART PLC編程與現(xiàn)場調(diào)試人員的實用技術(shù)文檔針對模擬量信號波動大、硬件濾波難以滿足平穩(wěn)輸入的場景給出基于表格指令實現(xiàn)滑動平均值濾波的完整方法。資源包共1個docx文件壓縮包約255KB內(nèi)容精煉便于快速查閱與落地。文檔以符號表變量建立為起點依次說明上電初始化時通過FILL_IN指令構(gòu)造表格并清零累加和、數(shù)據(jù)更新時用FIFO指令彈出最早元素并同步扣減累加和、使用AD_T_TBL指令把新模擬量值填入表格并更新總和待元素達(dá)到設(shè)定數(shù)量后計算平均值并輸出同時給出了相關(guān)指令的手冊查閱指引和源程序下載提示方便對照實操。已有1382人學(xué)習(xí)下載適合需要提升模擬量采樣穩(wěn)定性、掌握S7-200SMART表指令應(yīng)用的工程師參考。 做自動化項目最常遇到的一個問題模擬量信號明明接好了屏蔽線也換了可AIW讀出來的數(shù)值就是不穩(wěn)定。溫度在屏幕上跳來跳去液位跟著變頻器一抽一抽地波動上位機(jī)曲線畫出來跟心電圖似的。有人加電容有人換屏蔽層有人在程序里寫了七八種平均算法——這些我都折騰過但最順手、改起來最靈活的還是在PLC里直接做軟件濾波。這篇就聊S7-200SMART用表格指令實現(xiàn)模擬量信號滑動平均值濾波的方法。材料不復(fù)雜一條ATT填表指令、一條FIFO出表指令再加一個定時中斷就夠了。如果你是搞現(xiàn)場調(diào)試的電氣工程師或者正在自學(xué)S7-200SMART的西門子初學(xué)者這篇可以直接照著抄作業(yè)。1. 核心思路為什么用表格指令來濾模擬量1.1 模擬量信號為什么非濾不可現(xiàn)場模擬量信號的噪聲來源比很多人想象的多。變頻器輸出側(cè)的高頻諧波會通過輻射耦合進(jìn)信號線繼電器接觸器動作時會產(chǎn)生尖峰脈沖傳感器本身也有熱噪聲和測量誤差24V開關(guān)電源的紋波同樣會疊加到4-20mA回路上。線纜再短、屏蔽再好也只能把外部干擾壓到一定水平不可能完全消除。這種噪聲如果不處理后果往輕了說是顯示數(shù)字來回跳往重了說就是PID輸出跟著亂擺調(diào)節(jié)閥或者變頻器被反復(fù)驅(qū)動執(zhí)行機(jī)構(gòu)磨損加劇系統(tǒng)報警誤報不斷。所以在信號進(jìn)入控制邏輯之前必須做一層軟件上的處理把隨機(jī)噪聲過濾掉讓參與運(yùn)算和顯示的是一個平滑、真實的數(shù)值。硬件RC濾波也算一種思路無非是在模擬量端子前串個電阻電容但響應(yīng)速度是固定的現(xiàn)場想調(diào)參數(shù)還得動螺絲刀拆端子排而且大電容帶來的滯后往往比軟件濾波更嚴(yán)重。相比之下軟件濾波零成本、參數(shù)可在線調(diào)整還不占柜內(nèi)空間屬于性價比最高的方案。1.2 滑動平均、一階慣性、中值濾波怎么選滑動平均值濾波的原理很簡單就是把最近N次采樣值存起來每次都取這N個數(shù)的平均值作為當(dāng)前輸出。它的數(shù)學(xué)表達(dá)式是 y(n)[x(n)x(n-1)...x(n-N1)]/N這個算法本身不難難在S7-200SMART里怎么高效地維護(hù)“最近N次采樣值”這個隊列。常見的替代方案有一階慣性濾波公式是y(n)a·y(n-1)(1-a)·x(n)參數(shù)少、計算快但濾完的曲線不夠平直而且相位滯后不容易直觀預(yù)估。中值濾波對脈沖尖峰效果最好不過需要在PLC里對N個數(shù)做排序S7-200SMART的指令集做排序又慢又啰嗦不適合高頻采樣。三種方案對比下來滑動平均的噪聲抑制能力均衡數(shù)學(xué)意義直觀尤其適合溫度、液位、壓力這類慢變模擬量。而S7-200SMART恰好提供了表格指令天生就能管理先進(jìn)先出的數(shù)據(jù)隊列讓滑動平均的實現(xiàn)變得非常簡潔這才是我推薦這個方案的核心原因。1.3 表格指令的內(nèi)部機(jī)制先弄懂S7-200SMART的表格指令里最常用的兩條是ATTAdd To Table填表和FIFOFirst In First Out先入先出出表。它們操作的內(nèi)存區(qū)域叫“表格”表格的內(nèi)存布局是固定的偏移含義示例TBL起始于VB1000最大填表數(shù)量字節(jié)0~255VB100 101當(dāng)前填表數(shù)量字節(jié)PLC自動維護(hù)VB101 0~102數(shù)據(jù)區(qū)第1個字VW1023數(shù)據(jù)區(qū)第2個字VW104...依次往后...ATT指令執(zhí)行時會把一個16位整數(shù)追加到表格數(shù)據(jù)區(qū)的末尾同時當(dāng)前計數(shù)自動加1。如果表格已滿ATT不再填入并置位SM1.4標(biāo)志。FIFO指令執(zhí)行時會把數(shù)據(jù)區(qū)最前面的數(shù)據(jù)取出送給指定地址后面所有數(shù)據(jù)逐個前移當(dāng)前計數(shù)自動減1。表格為空時FIFO不執(zhí)行置位SM1.5。換句話說ATT加FIFO組合起來就是一個標(biāo)準(zhǔn)的FIFO隊列。數(shù)據(jù)依次從尾部進(jìn)、從頭部出隊列里永遠(yuǎn)保持著最近N次采樣值?;瑒悠骄詈诵牡摹皾L動窗口”數(shù)據(jù)管理用這兩條指令就解決了不需要手動移位或者循環(huán)搬數(shù)據(jù)代碼量直接砍掉一大半。2. 實操步驟在S7-200SMART里搭滑動平均濾波器2.1 地址規(guī)劃先把變量表列清楚寫程序之前先把地址規(guī)劃好。我最怕的是邊寫邊想最后數(shù)據(jù)區(qū)重疊、初始化漏了一行在線查半天。以窗口長度N10為例需要在V區(qū)開辟連續(xù)的表格區(qū)和相關(guān)變量區(qū)實際占用22×N22字節(jié)的連續(xù)V區(qū)。我習(xí)慣用的地址分配表如下地址用途備注VB100表格最大填表數(shù)初始化寫10后續(xù)程序不改VB101表格當(dāng)前填表數(shù)由ATT/FIFO自動維護(hù)程序只讀VW102~VW120表格數(shù)據(jù)區(qū)10個字存放最近10次采樣值VW200最新采樣值暫存從AIW0讀取后先放這里VW210FIFO取出的舊值供累加器做減法VD300窗口內(nèi)數(shù)據(jù)累加和32位見后面溢出分析VD304類型轉(zhuǎn)換暫存器16位轉(zhuǎn)32位時用VD400累加和副本用于除法避免破壞VD300VD404除數(shù)常量N10初始化寫入VW500濾波結(jié)果輸出主程序、觸摸屏直接引用這里有個容易踩的坑表格區(qū)起始地址是VB100但ATT指令的TBL參數(shù)必須指向表格起始字節(jié)VB100而不是VW100。表格指令認(rèn)的是字節(jié)地址操作數(shù)里寫VB100、VB200、VB300均可但一定得保證后面跟著的22N字節(jié)都是空閑的V區(qū)不能和其他邏輯共用。2.2 初始化程序把表格和中斷都準(zhǔn)備好初始化用SM0.1也就是CPU首次掃描時執(zhí)行一次。需要做的事有四件設(shè)置表格最大填表數(shù)、清零當(dāng)前填表數(shù)、清零累加和、配置定時中斷。// 主程序 - 初始化網(wǎng)絡(luò) LD SM0.1 MOVB 10, VB100 // 最大填表數(shù) 濾波窗口N MOVB 0, VB101 // 當(dāng)前填表數(shù)清零 MOVD 0, VD300 // 窗口累加和清零 MOVD 10, VD404 // 除數(shù)常量 10 MOVB 100, SMB34 // 定時中斷0間隔 100ms ATCH INT_0, 10 // 中斷事件10關(guān)聯(lián)到INT_0 ENI // 全局開放中斷有些資料里會省去MOVB 0, VB101這一步理由是表格計數(shù)會隨著ATT/FIFO自動變化。但PLC上電后V區(qū)是隨機(jī)值或者掉電保持的舊值不清零后患無窮。我的建議是這一行必須寫寧可重復(fù)初始化也不要賭內(nèi)存默認(rèn)是0。SMB34是定時中斷0的時間寄存器單位毫秒允許范圍1~255。100ms是我給一般慢變量的推薦值具體怎么選后面專門講。ATCH指令的作用是把中斷事件10定時中斷0關(guān)聯(lián)到中斷程序INT_0ENI是全局中斷允許三者結(jié)合才能讓中斷真正跑起來。2.3 中斷程序填表出表加累加中斷程序是整個濾波器的核心每次定時中斷到來時順序執(zhí)行三個動作判斷表格是否已滿、滿了就先出表、讀取最新模擬量并填表、更新累加和并計算平均值。// 中斷程序 INT_0 // 網(wǎng)絡(luò)1表格已滿則先執(zhí)行FIFO取出最舊數(shù)據(jù) LD SM0.0 LDB VB101, 10 FIFO VB100, VW210 ITD VW210, VD304 -D VD304, VD300 // 網(wǎng)絡(luò)2讀取模擬量并填表更新累加和 LD SM0.0 MOVW AIW0, VW200 ATT VW200, VB100 ITD VW200, VD304 D VD304, VD300 // 網(wǎng)絡(luò)3計算當(dāng)前窗口平均值 LD SM0.0 MOVD VD300, VD400 /D VD404, VD400 MOVW VW402, VW500這里有個先后順序的問題FIFO必須在ATT之前執(zhí)行否則表格永遠(yuǎn)處于滿的狀態(tài)ATT就會觸發(fā)SM1.4而不填入。我初始時把VB101清零前9次中斷只執(zhí)行ATT和累加第10次開始VB101達(dá)到10之后每次都先FIFO再ATT窗口長度恒定為10VD300的累加和也始終對應(yīng)當(dāng)前窗口中10個數(shù)據(jù)之和整個邏輯閉環(huán)相當(dāng)嚴(yán)密。關(guān)于最后一行MOVW VW402, VW500我需要解釋一下VD400是個32位地址高16位是VW400低16位是VW402。雙整數(shù)除法/D執(zhí)行完后商保存在VD400中它的低16位VW402就是我們要的整數(shù)平均值。把VW402傳送到VW500VW500就是濾波結(jié)果的輸出地址。如果你需要浮點結(jié)果做更精細(xì)的運(yùn)算可以在除法之前用DTR指令把雙整數(shù)轉(zhuǎn)成實數(shù)再除實數(shù)10.0但一般顯示和PID控制用整數(shù)就足夠。2.4 梯形圖和STL如何對應(yīng)移植很多朋友習(xí)慣用梯形圖實在看不慣STL指令表。其實這個程序在Micro/WIN SMART里無論是LAD還是STL都能編寫上面給的STL只是方便發(fā)布和核對。梯形圖的做法是網(wǎng)絡(luò)1拖一個常開觸點SM0.0、一個字節(jié)等于比較器VB10110、一個FIFO指令TBL填VB100DATA填VW210、一個I_DI整數(shù)轉(zhuǎn)雙整數(shù)指令、一個雙整數(shù)減法指令。 網(wǎng)絡(luò)2拖一個常開觸點SM0.0、一個MOVW指令A(yù)IW0→VW200、一個ATT指令DATA填VW200TBL填VB100、一個I_DI轉(zhuǎn)換、一個雙整數(shù)加法。 網(wǎng)絡(luò)3拖一個常開觸點SM0.0、一個MOVD指令VD300→VD400、一個雙整數(shù)除法指令、一個MOVW指令VW402→VW500。關(guān)鍵點在于梯形圖里的ATT指令左側(cè)有兩個輸入EN和DATA下面一行是TBL。別把DATA和TBL填反了否則運(yùn)行的時候數(shù)據(jù)會寫進(jìn)你根本想不到的內(nèi)存地址。3. 關(guān)鍵參數(shù)怎么定才不踩坑3.1 窗口長度N和采樣周期T怎么配合窗口總時間等于N乘以T濾波后的響應(yīng)滯后大約為N×T/2。比如N10、T100ms那么窗口總共覆蓋1秒滯后約0.5秒。如果你控制的是室溫這種大慣性對象0.5秒的滯后毫無壓力但如果你采樣的是液壓系統(tǒng)壓力0.5秒滯后可能讓PID直接震蕩。根據(jù)我做過項目的經(jīng)驗不同信號類型的推薦參數(shù)大致如下信號類型采樣周期T窗口N窗口總時長適用場景室溫、水溫500ms~1s10~205~20s暖通、水箱液位200~500ms10~202~10s水池、罐體管道壓力100~200ms5~100.5~2s供水、氣路流量100~300ms5~80.5~2s總管、支管計量電機(jī)電流20~50ms5~100.1~0.5s電流監(jiān)控這個表格不是死的。判斷標(biāo)準(zhǔn)很簡單窗口總時長最好不超過對象本身響應(yīng)時間的五分之一。如果工藝上要求快速報警比如壓力超高連鎖停機(jī)濾波就不能做太重寧可讓信號帶一點噪聲也要保證報警及時性。N的取值還要考慮S7-200SMART表格指令的一個限制表格計數(shù)是字節(jié)型最大只有255。模擬量濾波一般10~50就夠用了很少有人會填到255因為窗口太長數(shù)據(jù)幾乎“凝固”失去實時性。3.2 用定時中斷還是用SM0.5時鐘脈沖有朋友會問為什么不用SM0.5這位0.5秒的時鐘脈沖去觸發(fā)采樣原因是SM0.5的精度太差它跟掃描周期不同步而且在主程序里用SM0.5觸發(fā)采樣時如果當(dāng)次掃描正好被某段程序拖長采樣間隔會抖動濾波質(zhì)量跟著下降。定時中斷的優(yōu)勢在于嚴(yán)格的等間隔采樣。SMB34的定時基準(zhǔn)不依賴掃描周期哪怕主程序里跑了一段長延時中斷照樣準(zhǔn)點觸發(fā)。對滑動平均來說等間隔采樣是算法成立的前提所以我的做法是優(yōu)先用TIMER0中斷也就是SMB34ATCH事件10。關(guān)于中斷程序有幾個操作紀(jì)律要守住中斷程序里不要調(diào)用有不確定執(zhí)行時間的子程序不要在里面做輪詢通信不要輕易用循環(huán)指令。中斷程序應(yīng)該保持短小只做和采樣、濾波直接相關(guān)的事。如果需要把濾波結(jié)果傳給通信或顯示邏輯就只寫公共變量VW500由主程序自己去讀。3.3 溢出問題其實不用太擔(dān)心但要注意除法截斷S7-200SMART的AIW模擬量輸入范圍一般是0~27648或0~32000取決于模塊和量程設(shè)置即使按最大值32000來算N50時累加和是32000×501,600,000遠(yuǎn)小于32位雙整數(shù)的上限2,147,483,647所以用32位累加器VD300完全不會溢出。哪怕N取到255最大值32000×2558,160,000也安全。真正需要留意的是整數(shù)除法會截斷余數(shù)。VD400除以VD404的結(jié)果只保留整數(shù)部分例如平均值算出來是123.7VW402得到的是123。對于濾波輸出這個精度大多數(shù)場合能接受。如果連0.7的誤差都會影響控制精度那就在除之前用DTR把被除數(shù)轉(zhuǎn)實數(shù)用實數(shù)除法算到小數(shù)點后一位再根據(jù)需要ROUND回去。但這樣一來運(yùn)算量增加對執(zhí)行速度影響很小只是代碼會多幾行我一般建議先用整數(shù)除法不行再升級。4. 實戰(zhàn)問題與經(jīng)驗速查4.1 表格不更新、計數(shù)一直不變、濾波值恒定這種問題十有八九是ATT指令根本沒執(zhí)行原因集中在三個方面一是初始化里忘記寫ENI中斷雖然有ATCH但根本沒開放程序壓根沒進(jìn)過INT_0二是表格起始地址與數(shù)據(jù)區(qū)重疊比如TBL寫成了VW102數(shù)據(jù)區(qū)被表格頭占用ATT一執(zhí)行就把表格頭覆蓋掉三是你在主程序里把SM0.1那段初始化邏輯復(fù)制到了循環(huán)段每次掃描都把VB101清零表格當(dāng)前計數(shù)永遠(yuǎn)停留在0。排查方法很簡單在狀態(tài)表里在線監(jiān)視VB101。如果VB101一直為0看初始化是否被反復(fù)執(zhí)行如果VB101一直是255或者隨機(jī)數(shù)看表格頭是否被破壞如果VB101正常遞增但VW500不變檢查VW500的設(shè)備地址是不是被觸摸屏或者上位機(jī)重復(fù)寫了。4.2 濾完還有毛刺或者滯后大到工藝投訴濾波效果不理想先不要急著調(diào)參數(shù)分清是“濾不掉”還是“滯后大”。如果濾完的曲線仍然毛刺明顯說明窗口總時長太短后臺變頻器干擾頻率很高單次窗口內(nèi)噪聲沒有被充分平均這時候要增大N或T。如果曲線很平滑但閥門動作跟不上設(shè)定變化說明窗口太長操作員調(diào)節(jié)后很久數(shù)值才到位這時候要減小N或T?,F(xiàn)場最常見的操作是只調(diào)N不調(diào)T或者反過來。我的建議是保持N在5~20之間優(yōu)先調(diào)T。因為N是數(shù)據(jù)點數(shù)太小和太大的曲線差異很直觀T則直接對應(yīng)采樣頻率和硬件回路的抗干擾特性更相關(guān)。一次只動一個變量調(diào)完用狀態(tài)表里的趨勢圖看曲線這是最穩(wěn)妥的調(diào)試方式。4.3 調(diào)試技巧狀態(tài)表、趨勢圖和地址分區(qū)管理Micro/WIN SMART的在線狀態(tài)表可以同時監(jiān)控AIW0、VB101、VW200、VW500這些變量。更直觀的是它的趨勢圖功能可以把AIW0和VW500兩條曲線疊加顯示原始信號噪聲有多大、濾波后有多平一眼就能看出來。我每接一個項目都會在狀態(tài)表里預(yù)先配好這組變量省得每次現(xiàn)場都要重新添加。另外一個經(jīng)驗是把濾波相關(guān)變量集中在一個V區(qū)連續(xù)段。表格區(qū)、采樣暫存、累加器、輸出寄存器全部放在一個規(guī)劃好的地址塊里。這樣做的好處是調(diào)試狀態(tài)表時地址連續(xù)好記下載程序后排查覆蓋問題時也容易用“V區(qū)內(nèi)存監(jiān)視”整體查看。我見過不少同事程序風(fēng)格瀟灑變量東一個西一個最后在線監(jiān)視時滿屏地址亂飛效率極低。最后分享一個小技巧如果你手頭有S7-200SMART的練習(xí)手冊建議把上面的地址分配改成手冊里的示例地址在仿真或者實體PLC上完整跑一遍。先看現(xiàn)象再對照程序邏輯理解會比光看文章深很多。這套表格指令的玩法其實不止濾波設(shè)備歷史故障記錄、產(chǎn)品數(shù)據(jù)FIFO緩存都可以套用原理完全一樣學(xué)會一次就能遷移到好幾個場景。本文還有配套的精品資源點擊獲取