使用者定義功能塊(UDFB)之於可程式邏輯控制器(PLC)就像功能之於微控制器一樣。兩者都是用於簡化程式碼的結構,使其更容易編寫,故障排除和維護。它們也是允許程式碼在將來被重複使用的基本結構。
本文概述了在 Arduino Opta 中使用的簡單 UDFB 的構造。此 UDFB 採用 Arduino PLC 整合開發環境 (IDE)1.0.3.0版本開發。本文提出的廣義 UDFB 概念和程序適用於大多數 PLCs。
什麼是UDFB?
UDFB 是一種類型的程式組織單元(POU),用於組織 IEC 61131-3 標準中所述的 PLC 程式碼。從 C 程式設計的角度來看,UDFB 就像一個具有多個輸入和輸出的函數,其中包含所有變數的 static 關鍵字。換句話說,UDFB 具有跨函數呼叫存在的記憶體。
為了清楚起見,我們應該提到另一種 POU,簡稱為「函數」。與 UDFB 不同,POU 函數不具有靜態記憶體的特性。另一種比較的方法是使用數位邏輯語言,UDFB 是一個順序電路,而函數是一個組合(無記憶體)運算。
為了簡單起見,我們有意將該函數與 UDFB 合併。從程式設計的角度來看,函數的操作可以由 UDFB 執行,而不是反過來。如果可以建構 UDFB,那麼建構更簡單的函數就沒有問題了。
小貼士:一名機械技師和一名電氣技師正在修理一台柴油引擎。工作進行得不是特別順利,因為兩人都認為問題出在對方的技術人員的駕駛室。 UDFB 也是如此。即使是構造和文件最好的 UDFB 也會受到一定程度的懷疑,特別是在故障排除事件發生幾個小時後。建構一個好的微控制器函數的相同規則適用於 UDFB。讓它們簡單,讓它們把一件事做得很好。不要太聰明。相反,要簡潔明了。
如何建立UDFB
最困難的任務之一是定義 UDFB 的行為。我們必須理解 UDFB 要執行的輸入參數、輸出和任務。我們也必須了解頂層程式將如何實例化(使用或呼叫)UDFB。在我看來,這是整個過程中最困難的部分,因為寫 UDFB 的機制相對簡單。
小貼士:弗雷德·布魯克斯在他的經典著作《The Mythical Man-Month》中有一句老話。轉述一下,它說我們需要計劃一個迭代的設計過程,「因此計劃扔掉一個;無論如何,你都會這麼做。」我希望它不是那樣的,但是我們經常需要構建並實例化 UDFB 為學習經驗的一部分。只有透過建構第一個原型,我們才能了解它是如何運作的,以及它對更大的軟體專案的影響。
作為範例,我們將建立如圖 1 中突出顯示的 UDFB。這個區塊被用作狀態機的一部分。它的作用是充當看門人。如果機器的 uiState 狀態變數等於1,並且啟用了該區塊,則執行該行的其餘部分。從 C 程式設計的角度來看,這就像是以 uiState 為索引的開關語句。請注意,前碼「ui」是匈牙利語的無符號整數表示法。
這種特殊的構造導致了一個相對乾淨的階梯邏輯。梯級3的英文描述是這樣的:
- 如果 UDFB FBuiEqual 被啟用並且機器狀態(uiState)繼續
- 另外,如果主開關是打開的
- 同樣,如果瞬時選擇開關處於前進位置,則切換到狀態 2
- 否則,如果瞬間選擇開關處於反向位置,則切換到狀態 4
我們將在此結束,因為狀態對於我們的 UDFB 討論並不重要。也許我們可以在以後的文章中探討狀態機。相反,關注 UDFB 和它正在尋找的兩個條件:是否啟用和值是否匹配。
「設定輸出線」功能的實用程式
請注意, 梯級(rung)從 xEqual 行而不是 ENO 行繼續從 UDFB 開始。這是一個方便的 Arduino PLC IDE 功能,稱為「Set Output Line」。如果我們沒有使用這個選項,就需要一個中間變數來保存 eEqual 的值,同時還需要第二個梯級來執行狀態改變操作。這將使梯級的數量增加一倍,從而降低程式碼的可讀性。
圖 1:所反白的 UDFB 在第 3 行實例化,其操作類似 C 程式中的 switch 語句。
定義輸入和輸出接口
建構 UDFB 的第一步是確定輸入/輸出介面以及所需的變數。這是使用圖 2 上半部所示的局部變數表完成的。觀察有兩個標記為 uiA 和 uiB 的無符號整數(ui)輸入。還有一個布林函數(Boolean(x))輸出名為 xEqual。沒有顯示隱含的「rung hanging」EN 和 ENO I/O。這些元素在圖 1 中很明顯,它顯示了實例化的 UDFB。
小貼士:如您所知,PLC 可以用幾種不同的 IEC 61131-3 語言程式設計。當我們在語言之間切換時,事情就變得有趣了。例如,將區塊掛在階梯邏輯梯級上的預設 EN 和 ENO 行在所有語言中都不是通用的。很明顯,像結構化文字這樣的語言並沒有圖形化的梯級。因此,「rung hanging」的 I/O 沒有直接的目的,或至少我們應該說,目的和實現是可以解釋的。 Arduino 設計團隊似乎忽略了這些行,例如在結構化文字中呼叫 EQ 函數:OUT:= EQ(TRUE, FALSE);如您所見,EN 和 ENO 行不存在,因為該函數只分析要比較的兩個值。
對了,還記得我說過的「搭上去就丟了」嗎? UDFB 中有一個 bug。你永遠不會在階梯邏輯實現中看到它,但它可能是結構化文字的問題。我把問題留給你自己去發現。提示:我們的 UDFB 需要多少輸入參數(隱式和顯式)。
定義 UDFB 操作
圖 2 所示的表格包含兩個局部變量,包括 eEN 和 xisEqual。在第一級,我們有一個 equal 函數的實例化。在第 2 行,我們詢問是否啟用了 UDFB,以及兩個值是否相等。請注意,UDFB 的操作與原來的相等函數之間存在細微的差異。根據 Arduino 文檔,EQ 區塊的 EN 行不涉及操作。對於 UDFB,我們放置了一個額外的約束,該約束要求啟用區塊以及 UDFB 求值為 true 的值相等。
圖 2:過定義 I/O 介面、變數和程式碼來建立 UDFB。
總結
UDFB 是 PLC 程式設計的一個強大的、必須具備的技術。UDFB 可以簡化程式碼,並提供預先建置和測試模組的有價值的程式庫。同時,我要再次提醒您為了清晰而編程。不要太聰明!難以理解的 UDFB 可能會為故障排除過程增加混亂和延遲。這是非常不可取的,因為當我們考慮到生產損失,商譽損失,浪費材料,閒置勞動力以及恢復目標的高加班成本時,PLC 的停機是非常昂貴的。