C# 讀寫歐姆龍(Omron)PLC ,C#使用Fins-tcp協議讀寫資料

來源:互聯網
上載者:User

標籤:精度   reads   install   模式   nss   send   strong   建議   上位機   

 

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

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

 

English Version : https://github.com/dathlin/HslCommunication/blob/master/docs/Siemens.md

 

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

Install-Package HslCommunication

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

 

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

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

 

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

 

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

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

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

using HslCommunication;using HslCommunication.Profinet.Omron;

 

 

隨便聊聊

當我們一個上位機需要讀取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

舉個例子:

omronFinsNet.LogNet = new HslCommunication.LogNet.LogNetSingle( "omron.log.txt" );

 

 

關於通訊的說明

使用FINS-TCP協議實現資料互動,如果在測試的過程中,發現寫入失敗的話,有可能是因為

 

訪問測試專案

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

為:

 

示範項目

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

https://github.com/dathlin/RemoteMonitor

下面的圖片樣本中的左邊程式就是伺服器程式,它應該和PLC直接連接並接入區域網路,然後把資料推送給用戶端顯示。注意:一個複雜進階的程式就應該把處理邏輯程式和介面程式分開,比如這裡的伺服器程式實現資料擷取,推送,儲存。讓用戶端程式去實現資料的整理,分析,顯示,這樣即使用戶端程式因為BUG奔潰,伺服器端仍然可以正常的工作。

示範項目使用的西門子訪問,可以方便的改成歐姆龍的項目

 

地址支援

支援地址及樣本如下:

  • DM區  D100
  • CIO區 C100
  • WR區 W100
  • HR區 H100
  • AR區 A100

 

特別感謝
  • 感謝 酒罷舞 對本組件的測試
  • 感謝 一貝水 對本組件的測試

 

 

執行個體化
 
private OmronFinsNet omronFinsNet = new OmronFinsNet( "192.168.0.100", 6000 );

 

在串連伺服器前需要設定三個參數,PLC的單元號,PLC的網路節點,PC的網路節點,如下是舉例,你需要根據實際情況來填寫。

            omronFinsNet.SA1 = 0x20; // PC網路號,PC的IP地址的最後一個數            omronFinsNet.DA1 = 0x10; // PLC網路號,PLC的IP地址的最後一個數            omronFinsNet.DA2 = 0x00; // PLC單元號,通常為0

 

 

 

串連伺服器,也可以放在視窗的Load方法中,一般建議使用長串連,速度更快,又是安全執行緒的(調用下面的方法就是使用了長串連,如果不串連直接讀取資料,那就是短串連):
            try            {                OperateResult connect = omronFinsNet.ConnectServer( );                 if (connect.IsSuccess)                {                    MessageBox.Show( "串連成功!" );                }                else                {                    MessageBox.Show( "串連失敗!" );                }            }            catch (Exception ex)            {                MessageBox.Show( ex.Message );            }

 

 

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

omronFinsNet.ConnectClose( );

 

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

            // 讀取操作,這裡的D100可以替換成C100,A100,W100,H100效果時一樣的            bool D100_7 = omronFinsNet.ReadBool( "D100.7" ).Content;  // 讀取D100.7是否通斷,注意D100.0等同於D100            short short_D100 = omronFinsNet.ReadInt16( "D100" ).Content; // 讀取D100組成的字            ushort ushort_D100 = omronFinsNet.ReadUInt16( "D100" ).Content; // 讀取D100組成的無符號的值            int int_D100 = omronFinsNet.ReadInt32( "D100" ).Content;         // 讀取D100-D101組成的有符號的資料            uint uint_D100 = omronFinsNet.ReadUInt32( "D100" ).Content;      // 讀取D100-D101組成的無符號的值            float float_D100 = omronFinsNet.ReadFloat( "D100" ).Content;   // 讀取D100-D101組成的單精確度值            long long_D100 = omronFinsNet.ReadInt64( "D100" ).Content;      // 讀取D100-D103組成的大資料值            ulong ulong_D100 = omronFinsNet.ReadUInt64( "D100" ).Content;   // 讀取D100-D103組成的無符號大資料            double double_D100 = omronFinsNet.ReadDouble( "D100" ).Content; // 讀取D100-D103組成的雙精確度值            string str_D100 = omronFinsNet.ReadString( "D100", 5 ).Content;// 讀取D100-D104組成的ASCII字串資料            // 寫入操作,這裡的D100可以替換成C100,A100,W100,H100效果時一樣的            omronFinsNet.Write( "D100", (byte)0x33 );            // 寫單個位元組            omronFinsNet.Write( "D100", (short)12345 );          // 寫雙位元組有符號            omronFinsNet.Write( "D100", (ushort)45678 );         // 寫雙位元組無符號            omronFinsNet.Write( "D100", (uint)3456789123 );      // 寫雙字無符號            omronFinsNet.Write( "D100", 123.456f );              // 寫單精確度            omronFinsNet.Write( "D100", 1234556434534545L );     // 寫大整數有符號            omronFinsNet.Write( "D100", 523434234234343UL );     // 寫大整數無符號            omronFinsNet.Write( "D100", 123.456d );              // 寫雙精確度            omronFinsNet.Write( "D100", "K123456789" );// 寫ASCII字串

 

 

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

            OperateResult<byte[]> read = omronFinsNet.Read( "D100", 5 );            {                if (read.IsSuccess)                {                    // 此處需要根據實際的情況來自訂來處理複雜的資料                    short D100 = omronFinsNet.ByteTransform.TransInt16( read.Content, 0 );                    short D101 = omronFinsNet.ByteTransform.TransInt16( read.Content, 2 );                    short D102 = omronFinsNet.ByteTransform.TransInt16( read.Content, 4 );                    short D103 = omronFinsNet.ByteTransform.TransInt16( read.Content, 6 );                    short D104 = omronFinsNet.ByteTransform.TransInt16( read.Content, 7 );                }                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 = omronFinsNet.ReadCustomer<UserType>( "M100" );if (read.IsSuccess){    UserType value = read.Content;}// write valueomronFinsNet.WriteCustomer( "M100", new UserType( ) );

 

 

究極資料的讀取:

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

46494E530000001A000000020000000080000200210000C000000101820000000002

        private void userButton23_Click_1(object sender, EventArgs e)        {            byte[] buffer = HslCommunication.BasicFramework.SoftBasic.HexStringToBytes(                "46494E530000001A000000020000000080000200210000C000000101820000000002");            OperateResult<byte[]> operate = omronFinsNet.ReadFromServerCore(buffer);            if (operate.IsSuccess)            {                // 顯示伺服器返回的報文                TextBoxAppendStringLine(HslCommunication.BasicFramework.SoftBasic.ByteToHexString(operate.Content));            }            else            {                // 顯示網路錯誤                MessageBox.Show(operate.ToMessageShowString());            }        }

 

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

 

 

創作不易,感謝打賞

 

 

C# 讀寫歐姆龍(Omron)PLC ,C#使用Fins-tcp協議讀寫資料

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.