C# 讀寫西門子PLC資料,包含S7協議和Fetch/Write協議,s7支援200smart,300PLC,1200PLC,1500PLC

來源:互聯網
上載者:User

標籤:建立   long   資料類型   mes   plc   網路   短串連   多線程同步   nuget   

本文將使用一個gitHub開源的組件技術來讀寫西門子plc資料,使用的是基於乙太網路的TCP/IP實現,不需要額外的組件,讀取操作只要放到後台線程就不會卡死線程,本組件支援超級方便的高效能讀寫操作

github地址:https://github.com/dathlin/HslCommunication 如果喜歡可以start或是fork,還可以打賞支援。

 

在Visual Studio 中的NuGet管理器中可以下載安裝,也可以直接在NuGet控制台輸入下面的指令安裝

Install-Package HslCommunication

 如果需要教程:Nuget安裝教程:http://www.cnblogs.com/dathlin/p/7705014.html

 

支援人員QQ群:592132877  (組件的版本更新細節也將第一時間在群裡發布)最後編輯日期:2018年4月1日 09:42:29

裡面各種小夥伴,為您解答資料互動,編程技巧,如果對本介面提供的API有任何疑問,都可以加群諮詢,如果有更好的建議,歡迎提出。

 

組件的完整資訊和其他API介紹參照:http://www.cnblogs.com/dathlin/p/7703805.html   組件的授權協議,更新日誌,都在該頁面裡面。

 

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

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

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

using HslCommunication;using HslCommunication.Profinet.Siemens;

 

隨便聊聊

當我們一個上位機需要讀取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連接埠機制也是這樣的。以下代碼預設使用長串連,效能更高,還支援多線程同步。

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

 

關於日誌記錄

不管是三菱的資料訪問類,還是西門子的,還是Modbus tcp訪問類,都有一個LogNet屬性用來記錄日誌,該屬性是一個介面類,ILogNet,凡事繼承該介面的都可以用來記錄日誌,該日誌會在訪問失敗時,尤其是因為網路的原因導致訪問失敗時會進行日誌記錄(如果你為這個 LogNet 屬性配置了真實的日誌記錄器的話):如果你想使用該記錄日誌的功能,請參照如下的部落格進行執行個體化:

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

 

關於兩種協議

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

 

訪問測試專案

在上述的github原始碼裡有個測試專案,HslCommunicationDemo,裡麵包含了各種用戶端的Demo項目,不需要編寫任何的代碼就可以測試資料的訪問了。

 

示範項目

下面的三篇示範了具體如何去訪問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 提供的圖片) (如果碰到讀取資料時出現長度驗證失敗的資訊,請務必檢查下面的勾是否打上)

 

 

執行個體化:

siemensTcpNet = new SiemensS7Net( siemensPLCS, "192.168.0.100" ) {                ConnectTimeOut = 5000            };

  

 

串連伺服器,也可以放在視窗的Load方法中,一般建議使用長串連,速度更快,又是安全執行緒的(調用下面的方法就是使用了長串連,如果不串連直接讀取資料,那就是短串連):

                OperateResult connect = siemensTcpNet.ConnectServer( );                if (connect.IsSuccess)                {                    MessageBox.Show( "串連成功!" );                }                else                {                    MessageBox.Show( "串連失敗!" );                }

 

中斷連線,也就是關閉了長串連,如果再去請求資料,就變成了短串連

siemensTcpNet.ConnectClose( );

 

下面就示範一些簡單的資料操作,省去了對結果是否成功的驗證,所有的讀寫結果都是OperateResult類型及衍生類別型,都有一個IsSuccess屬性來判斷成功與否

            // 讀取操作,這裡的M100可以替換成I100,Q100,DB20.100效果時一樣的            bool M100_7 = siemensTcpNet.ReadBool( "M100.7" ).Content;  // 讀取M100.7是否通斷,注意M100.0等同於M100            byte byte_M100 = siemensTcpNet.ReadByte( "M100" ).Content; // 讀取M100的值            short short_M100 = siemensTcpNet.ReadInt16( "M100" ).Content; // 讀取M100-M101組成的字            ushort ushort_M100 = siemensTcpNet.ReadUInt16( "M100" ).Content; // 讀取M100-M101組成的無符號的值            int int_M100 = siemensTcpNet.ReadInt32( "M100" ).Content;         // 讀取M100-M103組成的有符號的資料            uint uint_M100 = siemensTcpNet.ReadUInt32( "M100" ).Content;      // 讀取M100-M103組成的無符號的值            float float_M100 = siemensTcpNet.ReadFloat( "M100" ).Content;   // 讀取M100-M103組成的單精確度值            long long_M100 = siemensTcpNet.ReadInt64( "M100" ).Content;      // 讀取M100-M107組成的大資料值            ulong ulong_M100 = siemensTcpNet.ReadUInt64( "M100" ).Content;   // 讀取M100-M107組成的無符號大資料            double double_M100 = siemensTcpNet.ReadDouble( "M100" ).Content; // 讀取M100-M107組成的雙精確度值            string str_M100 = siemensTcpNet.ReadString( "M100", 10 ).Content;// 讀取M100-M109組成的ASCII字串資料            // 寫入操作,這裡的M100可以替換成I100,Q100,DB20.100效果時一樣的            siemensTcpNet.Write( "M100.7", true );                // 寫位,注意M100.0等同於M100            siemensTcpNet.Write( "M100", (byte)0x33 );            // 寫單個位元組            siemensTcpNet.Write( "M100", (short)12345 );          // 寫雙位元組有符號            siemensTcpNet.Write( "M100", (ushort)45678 );         // 寫雙位元組無符號            siemensTcpNet.Write( "M100", 123456789 );             // 寫雙字有符號            siemensTcpNet.Write( "M100", (uint)3456789123 );      // 寫雙字無符號            siemensTcpNet.Write( "M100", 123.456f );              // 寫單精確度            siemensTcpNet.Write( "M100", 1234556434534545L );     // 寫大整數有符號            siemensTcpNet.Write( "M100", 523434234234343UL );     // 寫大整數無符號            siemensTcpNet.Write( "M100", 123.456d );              // 寫雙精確度            siemensTcpNet.Write( "M100", "K123456789" );// 寫ASCII字串

 

下面說明複雜的資料操作,以及批量化的資料操作,例如讀取M100-M109

            OperateResult<byte[]> read = siemensTcpNet.Read( "M100", 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                {                    // 發生了異常                }            }

這樣就把所有的位元組資料都提取上來了,如果資料比較複雜,還可以根據實際情況處理。當然也支援批量的寫入資料資訊

如果想實現自訂的資料類型,需要繼承一個介面

public class UserType : HslCommunication.IDataTransfer{    #region IDataTransfer    private HslCommunication.Core.IByteTransform ByteTransform = new HslCommunication.Core.ReverseBytesTransform( );    public ushort ReadCount => 20;    public void ParseSource( byte[] Content )    {        int count = ByteTransform.TransInt32( Content, 0 );        float temp = ByteTransform.TransSingle( Content, 4 );        short name1 = ByteTransform.TransInt16( Content, 8 );        string barcode = Encoding.ASCII.GetString( Content, 10, 10 );    }    public byte[] ToSource( )    {        byte[] buffer = new byte[20];        ByteTransform.TransByte( count ).CopyTo( buffer, 0 );        ByteTransform.TransByte( temp ).CopyTo( buffer, 4 );        ByteTransform.TransByte( name1 ).CopyTo( buffer, 8 );        Encoding.ASCII.GetBytes( barcode ).CopyTo( buffer, 10 );        return buffer;    }    #endregion    #region Public Data    public int count { get; set; }    public float temp { get; set; }    public short name1 { get; set; }    public string barcode { get; set; }    #endregion}

  這樣我們就是可以實現特殊資料的讀寫了

OperateResult<UserType> read = siemensTcpNet.ReadCustomer<UserType>( "M100" );if (read.IsSuccess){    UserType value = read.Content;}// write valuesiemensTcpNet.WriteCustomer( "M100", new UserType( ) );

  

支援M,I,Q,DB,T,C資料的讀寫操作

 

究極資料的讀取:

此處提供一個核心的報文讀取機制,你可以自己傳入自己的報文,然後接收伺服器的報文,再自己解析操作,可以根據報文格式實現任意的操作,當然,前提是需要報文支援。假設我要實現寫入M100,為0x3B,那麼最終的報文為

03 00 00 24 02 F0 80 32 01 00 00 00 01 00 0E 00 05 05 01 12 0A 10 02 00 01 00 00 83 00 03 20 00 04 00 08 3B

        private void userButton23_Click_1(object sender, EventArgs e)        {            byte[] buffer = HslCommunication.BasicFramework.SoftBasic.HexStringToBytes(                "03 00 00 24 02 F0 80 32 01 00 00 00 01 00 0E 00 05 05 01 12 0A 10 02 00 01 00 00 83 00 03 20 00 04 00 08 3B");            OperateResult<byte[]> operate = siemensTcpNet.ReadFromServerCore(buffer);            if (operate.IsSuccess)            {                // 顯示伺服器返回的報文                TextBoxAppendStringLine(HslCommunication.BasicFramework.SoftBasic.ByteToHexString(operate.Content));            }            else            {                // 顯示網路錯誤                MessageBox.Show(operate.ToMessageShowString());            }        }

 

更詳細的資訊,可以參照原始碼裡面的測試專案。

 

如果使用Fetch/Write協議進行讀寫操作,PLC端的配置不一致,執行個體化的類不一致,其他都是一樣的,不再贅述了,就重點說明下PLC網路模組的配置

 

環境:此處使用了STEP 7V5.5 sp4編程軟體作為樣本,在添加乙太網路模組(6GK7 343-1EX30-0E0 CP343-1)到組態中時,可以設定IP地址及子網路遮罩, 此處測試使用,所以不使用路由器,如果您的西門子需要串連到內網中的話,需要配置路由器。目前只支援M,I,Q資料的讀寫。 然後點擊建立,建立一個Ethernet(1)網路。乙太網路參數配置如:



將乙太網路的模組添加到機架中以後,現在開啟網路組態 ,開啟後點擊組態上的PLC模組。會出現如下介面,在箭頭出進行雙擊操作,可以彈出對話方塊,並進行一系列操作:

 

 

 



按照上面一套操作下來,建立了一個讀取的連接埠,連接埠號碼為2000,後面有用,需要記住, 按照上述的步驟再建立一個寫入的連接埠,只有最後一步不一致,如下:



配置完之後的如下,建立了兩個連接埠,一個用於讀取資料,一個用於寫入資料。 <strong>注意:設定完成後一定要寫入到PLC才算真的完成。</strong>



如所示,配置錯誤,應該配置一個同時支援讀寫的操作的連接埠

 

 

執行個體化的類的時候

private SiemensFetchWriteNet siemensFWNet = null;

  

siemensFWNet = new SiemensFetchWriteNet( )            {                IpAddress = "192.168.0.100",                Port = 2000,                ConnectTimeOut = 5000,            };

  

 

 

創作不易,感謝打賞

 

 

 

C# 讀寫西門子PLC資料,包含S7協議和Fetch/Write協議,s7支援200smart,300PLC,1200PLC,1500PLC

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.