java android 讀寫西門子PLC數據,包含S7協議和Fetch/Write協議,s7支持200smart,300PLC,1200PLC,1500PLC


本文將使用HSL組件技術來讀寫西門子plc數據,使用的是基於以太網的TCP/IP實現,不需要額外的組件,讀取操作只要放到后台線程就不會卡死線程,本組件支持超級方便的高性能讀寫操作

C# 版本nuget地址:https://www.nuget.org/packages/HslCommunication/       nuget     下載

C# 版本github地址:https://github.com/dathlin/HslCommunication      fork      star                     如果喜歡可以star或是fork,還可以打賞支持。

聯系作者及加群方式(激活碼在群里發放):http://www.hslcommunication.cn/Cooperation

 

Java版本的Demo代碼 https://github.com/dathlin/HslCommunicationJavaDemo

 

在Maven里搜索 HslCommunication 即可。

com.github.dathlin:HslCommunication

  

本文將展示如何配置網絡參數及怎樣使用代碼來訪問PLC數據,希望給有需要的人解決一些實際問題。主要對西門子PLC的M,Q,I,DB塊的數據讀寫,親測有效。

此處使用了網線直接的方式,如果PLC接進了局域網,就可以進行遠程讀寫了^_^

此處使用到了2個命名空間:

import HslCommunication.Profinet.Siemens.SiemensPLCS;
import HslCommunication.Profinet.Siemens.SiemensS7Net;
import HslCommunication.Core.Types.OperateResultExOne;

  

隨便聊聊(C#版本服務器)


當我們一個上位機需要讀取100台西門子PLC設備(此處只是舉個例子,凡是都是使用Modbus tcp的都是一樣的)的時候,你采用服務器主動去請求100台設備的機制對性能來說是個極大的考驗,如果開100個線程去輪詢100台設備,那么性能損失將是非常大的,更不用說再增加設備,如果搭建Modbus tcp服務器,就可以完美的解決性能問題,因為連接的壓力將會平均分攤給每一台PLC,服務器端只要新增一個時間戳就可以知道客戶端有沒有連接上。

我們在100台PLC里都增加發送Modbus tcp方法,將數據發送到服務器的ip和端口上去,服務器根據站號來區分設備。這樣就可以搭建一個高性能總站。 本組件支持快速搭建一個高性能的Modbus tcp總站。

http://www.cnblogs.com/dathlin/p/7782315.html

 

關於兩種模式


本組件所提供的所有客戶端類,包括三菱,西門子,歐姆龍,modbus-tcp,以及SimplifyNet都是繼承自雙模式基類,雙模式包含了短連接和長連接,下面就具體介紹下兩個模式的區別

短連接:每次讀寫都是一個單獨的請求,請求完畢也就關閉了,如果服務器的端口僅僅支持單連接,那么關閉后這個端口可以被其他連接復用,但是在頻繁的網絡請求下,容易發生異常,會有其他的請求不成功,尤其是多線程的情況下。

長連接:創建一個公用的連接通道,所有的讀寫請求都利用這個通道來完成,這樣的話,讀寫性能更快速,即時多線程調用也不會影響,內部有同步機制。如果服務器的端口僅僅支持單連接,那么這個端口就被占用了,比如三菱的端口機制,西門子的Modbus tcp端口機制也是這樣的。以下代碼默認使用長連接,性能更高,還支持多線程同步。

在短連接的模式下,每次請求都是單獨的訪問,所以沒有重連的困擾,在長連接的模式下,如果本次請求失敗了,在下次請求的時候,會自動重新連接服務器,直到請求成功為止。另外,盡量所有的讀寫都對結果的成功進行判斷。

 

關於日志記錄


暫時只是預留了接口,具體可以自己實現

 

關於兩種協議


本組件支持的西門子通信有兩種協議,一種是S7協議,在PLC側幾乎不需要配置參數,另一個協議Fetch/Write協議,相對比較麻煩一點,如果S7不方便讀取的話,可以選擇Fetch/Write,相對而言,S7更加方便點。

這兩個協議除了實例化的類型不一致,讀寫PLC的代碼和連接機制都是一致的,所以FW協議的具體代碼就不粘貼了,詳細參照下面的Demo項目。

 

訪問測試項目


下載JAVA版本的Demo源代碼,然后運行即可,當然你也可以使用C#版本的來測試。

https://github.com/dathlin/HslCommunicationJavaDemo

 

 

 

 

演示項目(C#服務器+asp.net + C#客戶端 + android客戶端)


下面的三篇演示了具體如何去訪問PLC的數據,我們在訪問完成后,通常需要進行處理,以下的示例項目就演示了后台從PLC讀取數據后,前台顯示並推送給所有在線客戶端的功能,客戶端並進行圖形化顯示,具有一定的參考意義,項目地址為:

https://github.com/dathlin/RemoteMonitor

下面的圖片示例中的左邊程序就是服務器程序,它應該和PLC直接連接並接入局域網,然后把數據推送給客戶端顯示。注意:一個復雜高級的程序就應該把處理邏輯程序和界面程序分開,比如這里的服務器程序實現數據采集,推送,存儲。讓客戶端程序去實現數據的整理,分析,顯示,這樣即使客戶端程序因為BUG奔潰,服務器端仍然可以正常的工作。

 

S7協議下的tcp直接通訊,配置簡單,一般PLC都支持


 

測試通過的PLC:1200系列 本人親測

                          200smart  感謝 無名①終止^^ 的測試

                          300系列  感謝 懂PLC不懂c# 的測試

                          1500系列 感謝 ∮溪風-⊙_⌒ 的測試

 

 報文的格式參考了如下的兩篇文章

http://www.itpub.net/thread-2052649-1-1.html

https://wenku.baidu.com/view/d93b88b06394dd88d0d233d4b14e852459fb3912.html

如果你擅長於網絡通信和組件開發,可以通過報文格式開發出自己的西門子通信庫,我所做的就是基於報文格式進行了二次封裝,隱藏了socket通信的細節,還包含了異常處理,提供了簡單方便的API來讀寫數據。提供了整數數據的讀寫,字符串讀寫,來豐富各種需求,從事實上來說,只要可以讀寫字節,相當於任何數據了。

准備:在西門子PLC上配置好IP地址,就只有一個IP地址就夠了,然后打開電腦的cmd指令,只要能ping通西門子PLC即可。

還需要在PLC側配置打開  GET/SET通訊允許:(感謝網友 OLIFE 提供的圖片) (如果碰到讀取數據時出現長度驗證失敗的信息,請務必檢查下面的勾是否打上)

 

 

 

 

最簡單的一條應用,只需要兩行代碼,示例:讀取M100的byte值

    private static void SiemesTest(){
        SiemensS7Net siemens_net = new SiemensS7Net(SiemensPLCS.S1200,"192.168.1.195");
        System.out.println(siemens_net.ReadByte("M100").Content);
    }

 

上述使用了短連接的模式,隨用隨連,我們下面演示長連接

SiemensS7Net siemens_net = new SiemensS7Net(SiemensPLCS.S1200,"192.168.1.195");
        OperateResult connect = siemens_net.ConnectServer();
        if(connect.IsSuccess){
            System.out.println("connect success!");
        }
        else {
            System.out.println("failed:"+connect.Message);
        }

程序退出的時候需要關閉長連接

siemens_net.ConnectClose();

  

以下演示了一些簡單的常用的讀寫操作,不過並未對結果進行判斷,實際生產代碼中,需要對結果進行嚴格的判定

        byte m100_byte = siemens_net.ReadByte("M100").Content;
        short m100_short = siemens_net.ReadInt16("M100").Content;
        int m100_int = siemens_net.ReadInt32("M100").Content;
        long m100_long = siemens_net.ReadInt64("M100").Content;
        float m100_float = siemens_net.ReadFloat("M100").Content;
        double m100_double = siemens_net.ReadDouble("M100").Content;
        String m100_string = siemens_net.ReadString("M100",(short) 10).Content;
        
        siemens_net.Write("M100",(byte) 123);
        siemens_net.Write("M100",(short) 123);
        siemens_net.Write("M100",(int) 123);
        siemens_net.Write("M100",(long) 123);
        siemens_net.Write("M100", 123.456f);
        siemens_net.Write("M100", 123.456d);
        siemens_net.Write("M100","1234567890");

  

 

下面說明復雜的數據操作,並對結果進行判斷,以及批量化的數據操作,例如讀取M100-M109

        OperateResultExOne<byte[]> read = siemens_net.Read( "M100", (short) 10 );
        {
            if(read.IsSuccess)
            {
                byte m100 = read.Content[0];
                byte m101 = read.Content[1];
                byte m102 = read.Content[2];
                byte m103 = read.Content[3];
                byte m104 = read.Content[4];
                byte m105 = read.Content[5];
                byte m106 = read.Content[6];
                byte m107 = read.Content[7];
                byte m108 = read.Content[8];
                byte m109 = read.Content[9];
            }
            else
            {
                // 發生了異常
            }
        }

  

讀寫的數據類型,支持 M。I。Q,DB塊,T、C

M   地址示例:M100

I 地址示例:I100

Q 地址示例 Q100

DB 塊。DB1.100     對於smart200來說,V區100就是DB1.100

T 地址示例 T100

C 地址示例: C100

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM