基于C#實(shí)現(xiàn)ModbusTCP服務(wù)器接口的方法
一、NModbus4
ModbusTCP服務(wù)器的本質(zhì)就是TCP服務(wù)器,根據(jù)識(shí)別ModbusTCP請(qǐng)求報(bào)文,返回對(duì)應(yīng)的ModbusTCP報(bào)文。
雖然原理很容易理解,但是自己開(kāi)發(fā)還是需要一點(diǎn)時(shí)間的,當(dāng)然我們也可以通過(guò)開(kāi)源庫(kù)來(lái)實(shí)現(xiàn),我們這里采用的是NModbus4。
NModbus4是一個(gè)開(kāi)放源碼的Modbus庫(kù)。
我們通過(guò)Nuget搜索NModbus4即可搜索安裝。
二、ModbusTCPServer
安裝好NModbus4后,我們進(jìn)行封裝一下,創(chuàng)建一個(gè)ModbusTCPServer類(lèi),對(duì)于進(jìn)行封裝,封裝了以下幾個(gè)方法:
方法一:開(kāi)啟服務(wù)
//ModbusTcpSlave對(duì)象 private ModbusTcpSlave modbusTcpSlave = null; //TcpListener對(duì)象 private TcpListener tcpListener; public void StartServer(string ip, int port) { tcpListener = new TcpListener(IPAddress.Parse(ip), port); modbusTcpSlave = ModbusTcpSlave.CreateTcp(1, tcpListener); modbusTcpSlave.Listen(); }
方法二:關(guān)閉服務(wù)
public void StopServer() { modbusTcpSlave?.Dispose(); }
方法三:向保持寄存器存儲(chǔ)區(qū)中寫(xiě)入數(shù)據(jù)
public void SetHoldingRegisterFloatValue(int offset, float value) { byte[] buffer = BitConverter.GetBytes(value); ushort highValue = BitConverter.ToUInt16(buffer, 0); ushort lowValue = BitConverter.ToUInt16(buffer, 2); //獲取保持型寄存器存儲(chǔ)區(qū) ModbusDataCollection<ushort> data = modbusTcpSlave.DataStore.HoldingRegisters; data[offset] = lowValue; data[offset + 1] = highValue; } public void SetHoldingRegisteUShortValue(int offset, ushort value) { //獲取保持型寄存器存儲(chǔ)區(qū) ModbusDataCollection<ushort> data = modbusTcpSlave.DataStore.HoldingRegisters; data[offset] = value; }
方法四:如果需要獲取報(bào)文,可以添加一些事件
public event Action<object, ModbusSlaveRequestEventArgs> ModbusSlaveRequestReceived; private void ModbusTcpSlave_ModbusSlaveRequestReceived(object sender, ModbusSlaveRequestEventArgs e) { ModbusSlaveRequestReceived?.Invoke(sender,e); } public event Action<object, ModbusSlaveRequestEventArgs> ModbusSlaveWriteComplete; private void ModbusTcpSlave_WriteComplete(object sender, ModbusSlaveRequestEventArgs e) { ModbusSlaveWriteComplete?.Invoke(sender, e); }
三、案例應(yīng)用
有了以上方法后,編寫(xiě)一個(gè)案例來(lái)進(jìn)行功能測(cè)試。
開(kāi)啟服務(wù)和關(guān)閉服務(wù)代碼很簡(jiǎn)單,就是調(diào)用ModbusTCPServer及其中的對(duì)應(yīng)方法即可。
private ModbusTCPServer modbusTCPServer = new ModbusTCPServer(); private void btn_Start_Click(object sender, EventArgs e) { if (this.btn_Start.Text == "開(kāi)啟服務(wù)") { try { int port = Convert.ToInt32(this.txt_Port.Text); modbusTCPServer.StartServer(this.txt_IP.Text, port); AddLog("開(kāi)啟服務(wù)成功"); this.btn_Start.Text = "關(guān)閉服務(wù)"; } catch (Exception ex) { AddLog("開(kāi)啟服務(wù)失敗:" + ex.Message); } } else { modbusTCPServer.StopServer(); this.btn_Start.Text = "開(kāi)啟服務(wù)"; } }
服務(wù)開(kāi)啟后,可以通過(guò)按鈕向指定寄存器中寫(xiě)入數(shù)據(jù),這里已經(jīng)封裝好了方法,直接調(diào)用即可。
private void btn_WriteFloat_Click(object sender, EventArgs e) { int address = Convert.ToInt32(this.txt_Address.Text); float value = Convert.ToSingle(this.txt_Value.Text); modbusTCPServer.SetHoldingRegisterFloatValue(address, value); AddLog("寫(xiě)入地址:" + address + " 浮點(diǎn)數(shù):" + value); } private void btn_WriteUShort_Click(object sender, EventArgs e) { int address = Convert.ToInt32(this.txt_Address.Text); ushort value = Convert.ToUInt16(this.txt_Value.Text); modbusTCPServer.SetHoldingRegisteUShortValue(address, value); AddLog("寫(xiě)入地址:" + address + " 整數(shù):" + value); }
最終實(shí)現(xiàn)效果如下所示:
用Modbus Poll軟件讀取結(jié)如下:
到此這篇關(guān)于基于C#實(shí)現(xiàn)ModbusTCP服務(wù)器接口的方法的文章就介紹到這了,更多相關(guān)C# ModbusTCP服務(wù)器接口內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
異步/多線(xiàn)程/任務(wù)/并行編程之一:如何選擇合適的多線(xiàn)程模型?
本篇文章小編為大家介紹,異步/多線(xiàn)程/任務(wù)/并行編程之一:如何選擇合適的多線(xiàn)程模型?需要的朋友參考下2013-04-04WPF實(shí)現(xiàn)能自由改變形狀的四邊形和六邊形
這篇文章主要為大家詳細(xì)介紹了WPF如何實(shí)現(xiàn)能自由改變形狀的四邊形和六邊形,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-03-03C#使用channel實(shí)現(xiàn)Plc異步任務(wù)之間的通信
在C#的并發(fā)編程中,Channel是一種非常強(qiáng)大的數(shù)據(jù)結(jié)構(gòu),用于在生產(chǎn)者和消費(fèi)者之間進(jìn)行通信,本文將給大家介紹C#使用channel實(shí)現(xiàn)Plc異步任務(wù)之間的通信,文中有相關(guān)的代碼示例供大家參考,感興趣的朋友跟著小編一起來(lái)看看吧2024-05-05C#中數(shù)據(jù)類(lèi)型的轉(zhuǎn)換介紹
大家好,本篇文章主要講的是C#中數(shù)據(jù)類(lèi)型的轉(zhuǎn)換介紹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話(huà)記得收藏一下,方便下次瀏覽2022-01-01C#使用Directoryinfo類(lèi)獲得目錄信息和屬性的方法
這篇文章主要介紹了C#使用Directoryinfo類(lèi)獲得目錄信息和屬性的方法,涉及C#操作目錄的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04C#在PDF中繪制不同風(fēng)格類(lèi)型的文本方法實(shí)例
這篇文章主要給大家介紹了關(guān)于C#在PDF中繪制不同風(fēng)格類(lèi)型的文本的相關(guān)資料,文中通過(guò)圖文以及示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07