延續上一篇的文章,這次要說明的是業界實際最常使用的多點監控及資料讀取技術,寫入部分另外再說明



一樣工具書先準備好,或是參考我以前另2篇文章用LabVIEW計算三菱PLC FX-2N元件群組通訊用位址和用LabVIEW計算三菱PLC FX-2N字元群組通訊用位址來查詢通訊位址


重要事項:


※高速動作的機器不建議使用電腦去控制PLC,建議改用人機螢幕控制PLC或完全靠電腦用I/O模組控制機器。理由呢?首先說明電腦控制PLC的流程:下控制命令→等延遲時間→接收回應資料。PLC傳遞1個命令字元時間約1.64 ms(通訊速度9600),以只讀取1組D暫存器內容來說,總共要傳遞約20個字元,總共要花時間1032.8 ms,讀取的組數更多時時間還要在加長,所以不可能即時反應機器的狀況。若機器控制用信號變化時間間隔少於1.5秒,改用其他控制方式比較實際


※電腦和PLC連接線儘量短,太長時通訊時間會受到影響,同時容易受到外部訊號干擾而誤動作


※要讀取和控制的元件要連號,這樣才可以用最少的命令去控制,可以減少通訊時間


※非必要的元件和資料就不要監控,要連線監控的接點資料控制在最少的狀態

 


首先PLC_LabVIEW圖形監控這本書關於這部份有很多細節沒有交代清楚,多點監控及資料讀取技術只讀取1組位元和單一暫存器,若只是照書操作練習還不成問題,若要實際使用時千萬不要直接拿裡面的程式來改,當初我就是這樣又花了不知幾天時間才找到問題



先補充上一篇文章沒提到的部份,關於控制命令的起始碼和結束碼的產生方式,除了用書中提到的數值陣列轉換的方式,還有另一種常用的資料格式轉換方式
方法是設定單1數值元件為U8格式,然後連上Type Cast元件做轉換


下圖上半為數值陣列轉換方式,下半為資料格式轉換方式

20080828-13  

 

 

再來要說的是多點監控及資料讀取部分,書中拆散成好幾部分,但實際上使用的命令字串是相同的


完整的命令字串組成為:起始碼+控制碼+元件群組位址+讀取組數+結束碼+偵誤碼

起始碼和結束碼和上一篇相同,起始碼為16進制數值字串02,結束碼為16進制數值字串03,控制碼為0代表讀取指令。偵誤碼同上一篇文章方式計算,以控制碼+元件群組位址+讀取組數的所有字元轉成ASCII碼數值相加,然後不管進位只取最後2碼當偵誤值


元件群組位址部份所要輸入的是帶頭那一組的位址,要注意的是元件群組的分組方式,三菱PLC在通訊上是以每8個點分為1組

 

 

可以讀取的接點元件群組是S,X,Y,T,M,C等群組,注意這些元件群組是以每8個接點為1組


※T和C群組的位址是讀取狀態專用,不可拿來做強制ON和OFF的控制位址。T和C強制ON和強制OFF有另外專用的位址


※Y,M群組還有專用在上、下微分的控制位址,在實務上用不到

 

 

可以讀取的T,C元件的現在值被分在字元群組,也就是和暫存器D屬於同性質,又可再分為16位元和32位元群組


※T的現在值和D暫存器都屬於16位元群組,每次以2組共16個點來顯示資料


※C的現在值有分16位元和32位元群組,C200以後的都是32位元群組,32位元是以4組共32個點來顯示資料


※D暫存器可以連結相鄰的2個暫存器成為32位元的暫存器,如D0和D1就可組成32位元暫存器,在控制命令中要輸入D0的位址


※在實務上讀取T的現在值和C200以後的高速計數器值是無意義的,因為讀到的已是上一次輪詢時的值,而不是現在實際值。另外若T設定的時間少於1次輪詢要花的時間,則只會讀到已計時完畢的時間

 

 

讀取組數要輸入的是16進制的數值字串共2碼,依照使用手冊說明最多可輸入範圍是01到40,換算成10進制數值共為64組,等於512個接點。實際上這部份有很多細節沒有提到,以下一一說明


※X和Y接點實體上最多才64點,加上擴充模組也才128點。換算只有8組,加上擴充模組最多16組。可以設定的最大數值是10,正好16組,大於這個數值會讀取錯誤


※S接點最多有125組共1000點,M接點最多有384組共3072點,可以設定的最大數值是40,總共64組。要注意最大組數減去帶頭組數後小於64組時,要依實際組數換算數值,若輸入40一樣會讀取錯誤


※T和C讀取狀態的元件最多才256個點共32組,可以設定的最大數值是20


※T現在值和D暫存器因為是16位元,可以設定的數值是02或是02的倍數,以外的設定都是錯誤的


※若是結合2個D暫存器而成的32位元暫存器,可以設定的數值是04或是04的倍數,以外的設定都是錯誤的


※C0~C199的現在值是16位元,可以設定的數值是02或是02的倍數。C200~C255的現在值是32位元,可以設定的數值是04或是04的倍數

 

以上重要注意事項要熟記,再來是實際程式的寫作部份。控制的部份不採用上一篇的方法,那個方法在控制按鍵很多時很難搞,這次完全採用事件(Event Structure)來寫

 

 

因為要隨時讀取PLC的狀態,這程式採用的是業界稱之為輪詢的技術。就是把程式寫在Timeout事件中,讓程式不停的去讀取PLC狀態。若是使用上一篇的按鍵偵測技術,則要把程式寫到Case Structure元件的第0頁


※注意程式輪詢中無法馬上停止,會等到輪詢完畢才執行停止動作


※若一次就讀取64組元件,加上延遲時間最少需1237.8 ms,約1.24秒


※有不同PLC元件要讀取時,是無法以1個命令去完成的,要按照順序去編排。以實際做過讀取X接點16點,Y接點8點,D暫存器6個。命令順序為:寫入讀取X群組命令→延遲→讀取X群組狀態→寫入讀取Y群組命令→延遲→讀取Y群組狀態→寫入讀取D暫存器群組命令→延遲→讀取D暫存器群組狀態。整個過程有3個延遲加上傳送84個字元,共花費3137.76 ms,約3.1秒。以測試經驗若T設定值少於3.5秒,絕對讀不出現在值

 

 

程式控制面板部份依不同用途分別做3個程式:

 

1、由LED元件組成2D陣列,依每8個1組方式由上而下及由左而右排列,元件編號低往編號高的方式排列,用來顯示S,X,Y,T,M,C等接點的ON/OFF狀態

20080828-01  

 

2、由數值元件組成1D陣列,由上而下以元件編號低往編號高的方式排列,用來顯示16位元字元群組轉換後的10進制數值

20080828-02  

 

3、由數值元件組成1D陣列,由上而下以元件編號低往編號高的方式排列,用來顯示32位元字元群組轉換後的10進制數值

20080828-03  

 

這3個程式的完整程式組成架構如下圖,可以清楚看到程式是寫在Timeout事件中,而停止程式用的是Exit按鍵的Value Change事件

20080828-04  

 

 

再來依照程式的流程由左至右詳細說明:

首先程式執行中不會變動的通訊參數、起始碼、結束碼寫到迴圈左邊的外面

20080828-05  

 

關閉通訊埠的元件寫到迴圈右邊的外面

20080828-06  

 

在Timeout事件中放入Flat Sequence Structure順序控制元件,Flat Sequence Structure順序控制元件用Add Frame After選項產生共3格的框格。每增加1種讀取元件就必須在Flat Sequence Structure中追加3格

 


第1格寫讀取資料的命令,在開始碼和結束碼中間的命令字串部份,我是用控制碼+元件群組位址+組數以合成的方式來組成字串。之所以不用書中直接寫命令字串的方式,是因為考慮這程式還要做成SubVI以供其他程式使用

20080828-07  

 

控制碼用0,表示是要讀取PLC的資料


元件群組位址和組數的輸入規則參照文章前半的說明,輸入錯誤程式仍可動作,只是結果會是錯誤的


偵誤碼是以命令字串的所有字元轉成ASCII碼數值相加,然後不管進位只取最後2碼當偵誤值


組數那個16進制字串則另外又轉成10進制數值往後面格子拉線,這個數值是要用在解讀PLC傳來的資料用

 

 

第2格一樣是延遲等待PLC回應的時間,要注意的是若讀取的組數很多(約10組以上)時,延遲時間1000 ms最好不要再減少。若讀取超過約24組以上,可能還要再增加一些時間(約100~200 ms)

20080828-08  

 

第1格到第2格在3個程式中內容都相同,也是比較不會弄錯的部份,問題較多的是第3格讀取後的處理,也是書中沒說清楚混過去的部份

 


現在依讀取資料的不同來詳細解說第3格的程式

讀回來的資料有固定的格式(如下圖),是以起始碼+資料碼+結束碼+偵誤碼所組成的字串,其中資料碼是以每2個16進制數值字元為一組來表示一筆資料,要依照一定的順序去解碼還原

20080828-12  

 

第1個程式是由LED元件組成2D陣列顯示S,X,Y,T,M,C等接點:

20080828-09  

 

一開始同樣用Property Node元件設定為Bytes at Port接收判定PLC回應字串長度

 

再來使用For Loop迴圈加上移位暫存器(用Add Shift Register)來解碼。For Loop迴圈的執行次數就是第1格的組數字串轉成的數值,共使用2組移位暫存器解碼,一組連上PLC讀出的字串,另一組則連上用Initialize Array建立的2D空白Boolean元件陣列

 

字串的分解書中是用String Subset元件,但只能解出1組字元,這裡使用Replace Substring元件搭配移位暫存器來分離出各組字元

 

Replace Substring元件的offset接腳設定為1,表示要從編號第1號字元開始分離字元,第0號字元是起始碼要跳過

 

Replace Substring元件的length接腳設定為2,表示每次要分離2個字元,這是因為資料是以每2個字元為1組

 

分離出來的字元用Hexadecimal String To Number和Number To Boolean Array元件先轉成10進制數值再轉成2進制的Boolean資料狀態,字元的上下位會由Hexadecimal String To Number自動換位,所以可以省去換位這個動作。原書中只到這裡結束,但這樣是錯誤的。只讀1組時沒有問題,讀2組以上時資料的順序全部錯亂,讀超過4組以上則無法正確顯示所有資料

 

會有這問題是因為Number To Boolean Array元件不管連接多大數值,轉出的就是32個Boolean資料狀態,只讀1組時頂多是多了24個無效資料,讀2到4組時資料的順序會移位,讀出組數的是奇數時有些資料還會溢位消失

 

在這裡的解決方法是用Delete From Array元件,把轉出來的資料只取前8個有效資料,後面無效資料捨棄

 

取出的資料再重新組成新的陣列再輸出。這裡也可以設定成輸出1D陣列,但考慮面板上要方便監控,所以設定為輸出2D陣列

 

 

第2個程式是由數值元件組成1D陣列顯示16位元字元群組轉換後的10進制數值:

20080828-10  

 

同樣用Property Node元件設定為Bytes at Port接收判定PLC回應字串長度

 

再來同樣使用For Loop迴圈加上2組移位暫存器(用Add Shift Register)來解碼,將資料字串先重組為正確順序。Loop迴圈的執行次數同樣是第1格的組數字串轉成的數值,字串的解碼同樣是用Replace Substring元件搭配移位暫存器來分離出各組字元

 

Replace Substring元件的offset接腳設定為1,表示要從編號第1號字元開始分離字元,第0號字元是起始碼要跳過

 

Replace Substring元件的length接腳設定為2,表示每次要分離2個字元,這是因為資料是以每2個字元為1組

 

重組後的PLC讀出值是一連串的16進制數值字串,這個字串顯示元件可以不用,會放上去是為了方便查看

 

最後要把這字串還原為正確的數值並按照順序排列,於是再用1個For Loop迴圈加上2組移位暫存器(用Add Shift Register)來轉換

 

Loop迴圈的執行次數是由第1格的組數字串轉成的數值再除以2,因為16位元資料是以每2組共4個字元組成

 

這裡一樣是用Replace Substring元件搭配移位暫存器來分離出各組字元

 

Replace Substring元件的offset接腳設定為0,表示要從編號第0號字元開始分離字元

 

Replace Substring元件的length接腳設定為4,表示每次要分離4個字元,這是因為資料是以每4個字元為1組

 

接著用用Hexadecimal String To Number元件將字元轉換成10進制數值,最後組成1D陣列輸出

 

 

第3個程式是由數值元件組成1D陣列顯示32位元字元群組轉換後的10進制數值:

20080828-11  

 

同樣用Property Node元件設定為Bytes at Port接收判定PLC回應字串長度

 

再來同樣使用For Loop迴圈加上2組移位暫存器(用Add Shift Register)來解碼,將資料字串先重組為正確順序。Loop迴圈的執行次數同樣是第1格的組數字串轉成的數值,字串的解碼同樣是用Replace Substring元件搭配移位暫存器來分離出各組字元

 

Replace Substring元件的offset接腳設定為1,表示要從編號第1號字元開始分離字元,第0號字元是起始碼要跳過

 

Replace Substring元件的length接腳設定為2,表示每次要分離2個字元,這是因為資料是以每2個字元為1組

 

照樣要把這字串還原為正確的數值並按照順序排列,同樣再用1個For Loop迴圈加上2組移位暫存器(用Add Shift Register)來轉換

 

Loop迴圈的執行次數是由第1格的組數字串轉成的數值再除以4,因為32位元資料是以每4組共8個字元組成

 

這裡一樣是用Replace Substring元件搭配移位暫存器來分離出各組字元

 

Replace Substring元件的offset接腳設定為0,表示要從編號第0號字元開始分離字元

 

Replace Substring元件的length接腳設定為8,表示每次要分離8個字元,這是因為資料是以每8個字元為1組

 

接著用用Hexadecimal String To Number元件將字元轉換成10進制數值,最後組成1D陣列輸出



有關三菱PLC的多點監控及資料讀取技術到此說明完畢,也許可能還有遺漏的部份。所說明的程式是實際測試並使用過,可以確定能正確執行並讀出正確結果


下一篇也是很複雜的多點ON/OFF控制及資料寫入,待資料整理完畢再發表

 

 

最近進行其他案子時才發現犯了基本上的錯誤,之前在讀取暫存器資料時讀的都是沒超過範圍的正整數,所以程式沒有問題。最近的案子有讀取到負數,才發現轉換出來的數值有錯

LabVIEW的字串數值轉換元件可以正確的將10進制的正負數轉換成PLC能接受的16進制數值字串,但卻無法將PLC傳來的16進制數值字串轉換為正確的10進制數值,因為轉出來的一定是正整數數值,因此還要再經過換算才能將讀到的負數還原成正確的數值顯示


改寫16位元暫存器資料的處理部份程式

20080828-14  

 

改寫32位元暫存器資料的處理部份程式

20080828-15  

 

改寫的重點是把16進制數值字串先轉成10進制正整數數值,10進制數值在和PLC能接受的最大正整數(16位元的話就是16進制數值7FFF)比大小。是小的話表示讀到的正整數,不用再經過程式換算。是大的話就表示是負數,這時將讀到的數值減掉PLC能接受的最大正整數,再減掉(PLC能接受的最大正整數加2),算出的結果就是正確的負數數值

, ,

未出師的小工程師 發表在 痞客邦 PIXNET 留言(3) 人氣()


留言列表 (3)

發表留言
  • Alex
  • 版主大大可以說一下用Labview 控制台達plc的方式嗎?(一定要作modbus嗎)
  • 我沒有使用過台達PLC,且目前手邊沒有台達PLC的通訊手冊,你的問題目前無法回答

    未出師的小工程師 於 2015/11/17 19:20 回覆

  • 訪客
  • 您好,因為我們也看了很多資料了,但是不知道是不是我們查看的資料是錯誤的,導致我們一直無法順利連上台達PLC,請問這部分我們是否可以跟您討論看看呢?謝謝
  • 我昨天上台達網站找到一些資料,大致看來台達的產品是支援modbus規格,要連上還是要作modbus

    資料中範例有些地方沒有交代的很清楚,其中最重要的容易出錯的是被控制的元件位址和CRC校驗碼計算。CRC校驗碼資料中有提到演算法,但演算過程沒有交代資料的變化歷程,這樣計算過程是否有問題很難檢查,偏偏無法連線大都是出在這問題上。CRC碼的計算等我將資料讀透再來處理

    未出師的小工程師 於 2015/11/18 20:08 回覆

  • 悄悄話

您尚未登入,將以訪客身份留言。亦可以上方服務帳號登入留言

請輸入暱稱 ( 最多顯示 6 個中文字元 )

請輸入標題 ( 最多顯示 9 個中文字元 )

請輸入內容 ( 最多 140 個中文字元 )

請輸入左方認證碼:

看不懂,換張圖

請輸入驗證碼

【 X 關閉 】

【PIXNET 痞客邦】國外旅遊調查
您是我們挑選到的讀者!

填完問卷將有機會獲得心動好禮哦(注意:關閉此視窗將不再出現)

立即填寫取消