C#使用NModbus4库创建Modbus TCP Slave(服务器)简朴示例
本文续上篇Codesys—标准库ModbusTCP Master(客户端)配合C#的NModbus4库的通讯示例链接:https://blog.csdn.net/wushangwei2019/article/details/136375234?spm=1001.2014.3001.5501
上篇描述在Codesys端的Modbus TCP Master(客户端)的设备添加、IO映射、通讯简朴展示等方面,本文记录PC端C#利用NModbus4通讯库创建Modbus TCP Slave(服务器)的方法。
注:本文只记录怎样使用NModbus4的部分功能,步伐结构较为简朴,并不适用于项目工程。
本文分以下几个步调分享NModbus4的使用:
1.添加NModbus4库
2.ModbusTcpSlave从站的创建
3.事件订阅
4.通讯示例
界面附加表现功能:
1.在收到客户端报文的事件后,将会在信息提示框中表现报文内容,报文内容不包含CRC;在服务器写入完成后,将会在信息提示框中表现写入完成的报文内容。
2.在服务器线程中,获取已连接的客户端的IP地址以及端标语信息,并在最底下表现出来。
软件界面如下,本文针对左侧服务器(从站)端:
https://img-blog.csdnimg.cn/direct/3068a598530c4aa1ae80c6755a7fc97d.jpeg
1.添加NModbus4库
菜单栏点击【工具】-》【NuGet包管理器】-》【管理办理方案的NuGet步伐包】
https://img-blog.csdnimg.cn/direct/3615bbe5a89344c189b654a77e1fdb79.png
弹出以下画面,搜刮【NModbus4】 ,选择必要安装的项目,并点击右下角的【安装】即可。
https://img-blog.csdnimg.cn/direct/e681afeee0bb412491aa75a2504cfc1e.png
在步伐中添加如下代码:
using Modbus.Data;
using Modbus.Device;
using Modbus.Extensions.Enron; 2.使用TcpListener创建服务器
焦点代码:
listener = new TcpListener(IPAddress.Parse(textBox2.Text), Convert.ToInt32(textBox3.Text));
listener.Start();
slave = ModbusTcpSlave.CreateTcp(1, listener);
slave.DataStore = DataStoreFactory.CreateDefaultDataStore();
slave.Listen();
分析:
1.TcpListener,用于创建服务器,必要输入参数待创建服务器的【IP地址】和【端标语】。
2.ModbusTcpSlave.CreateTcp方法,用于创建ModbusTCP Slave从站,创建后的从站对象为slave。
3.DataStoreFactory.CreateDefaultDataStore()方法,用于清除Modbus TCP Slave的数据存储区,寄存器区值全部写0。
4.slave.Listen()方法,Modbus TCP Slave开始监听哀求,我的理解是有客户端连接后,Slave开始响应客户端的报文,此方法应该放在有客户端连接后再使用较好,但在此处调用也能正常运行。
try
{
listener = new TcpListener(IPAddress.Parse(textBox2.Text), Convert.ToInt32(textBox3.Text));
listener.Start();
slave = ModbusTcpSlave.CreateTcp(1, listener);
slave.DataStore = DataStoreFactory.CreateDefaultDataStore();
WriteInfo("创建服务器成功!" + "线程ID:" + Thread.CurrentThread.ManagedThreadId + "\r\n");
//订阅数据到达事件,不能获取具体接收到的报文
//slave.DataStore.DataStoreWrittenTo += DataStoreWrittenToHandle;
//订阅接收到报文请求事件,可以打印接收到的报文
slave.ModbusSlaveRequestReceived += ModbusSlaveRequestReceivedHandle;
//订阅接收到写入完成事件,可以打印写入完成响应
slave.WriteComplete += WriteCompleteHandle;
slave.Listen();
isServerCreated = true;
WriteInfo("服务器创建成功!" +"\r\n");
count2 = 0;
}
catch(Exception ex)
{
count2++;
WriteInfo("创建服务器失败!" + "失败次数:"+count2.ToString()+ "\r\n");
isServerCreated = false;
creatServer= false;
return;
} 3.事件订阅
分别说明以下三个事件的功能。
//订阅数据到达事件,不能获取具体接收到的报文
//slave.DataStore.DataStoreWrittenTo += DataStoreWrittenToHandle;
//订阅接收到报文哀求事件,可以打印接收到的报文
slave.ModbusSlaveRequestReceived += ModbusSlaveRequestReceivedHandle;
//订阅接收到写入完成事件,可以打印写入完成响应
slave.WriteComplete += WriteCompleteHandle;
1.DataStore.DataStoreWrittenTo事件:当DataStore通过Modbus下令被写入数据时触发。
2.ModbusSlaveRequestReceived事件:当Slave收到主站报文时触发。
3.WriteComplete事件:当Slave接收到主站报文,并写入完成后触发。
本例重要使用后面【ModbusSlaveRequestReceived事件】和【WriteComplete事件】。
ModbusSlaveRequestReceived事件触发时,调用函数在提示框中打印报文信息,报文信息转换成16进制表现。
private void ModbusSlaveRequestReceivedHandle(object obj, ModbusSlaveRequestEventArgs e)
{
string str = "";
foreach (var item in e.Message.MessageFrame)
{
str += item.ToString("x2").PadLeft(2, '0').ToUpper() + "";
}
WriteInfo("服务器收到报文:" + str + "\r\n");
} WriteComplete事件,调用函数在提示框中打印报文信息,报文信息转换成16进制表现。
private void WriteCompleteHandle(object sender, ModbusSlaveRequestEventArgs e)
{
string str = "";
foreach (var item in e.Message.MessageFrame)
{
str += item.ToString("x2").PadLeft(2, '0').ToUpper() + "";
}
WriteInfo("服务器写入完成:" + str + "\r\n");
} 4.通讯示例
在服务器侧画面上,输入【IP】:127.0.0.1,【Port】:502,点击【创建服务器】,可观察到下方提示框中表现【创建服务器乐成】。
https://img-blog.csdnimg.cn/direct/b18806df2c77434a8ef092613b7c2bb0.png
打开Modbus Poll软件,在连接设置在远端服务器侧输入【IP地址】和【端标语】,点击确认连接。
连接乐成后,PC端软件提示服务器收到报文,报文信息没有包含CRC字节信息;Modbus Poll端软件表现Tx=11,不停增加,这是由于默认使用了03功能读保持寄存器,数量长度为20个字,并循环读取。
https://img-blog.csdnimg.cn/direct/08d4c63920bd4abc9ef14bd7328ab6b2.png
Modbus Poll的设置如下:
https://img-blog.csdnimg.cn/direct/6542728e2b1c4916b9b57fdcaa36fd07.png
根据PC端软件已有功能,进行测试。
从站(服务器)写入,Modbus Poll(主站/客户端)读取:
【Value】输入2,点击【写1~10】,将向保持寄存器地址【1~10】写入值为Value*地址值,如:地址1=2;
地址2=4;
地址3=6;
地址4=8;
依次类推...如下图所示。
https://img-blog.csdnimg.cn/direct/d8fe5f31bc3e468fa37202d0afc8b866.png
Modbus Poll(主站/客户端)写入,从站(服务器)读取:
Modbus Poll使用03功能码往保持寄存器地址11,写入123。 左侧软件提示框表现“服务器收到报文+收到报文”,此提示是由【ModbusSlaveRequestReceived事件】触发后发出;然后表现“服务器写入完成+收到报文”,此提示是由【WriteComplete事件】触发后发出。
https://img-blog.csdnimg.cn/direct/0522c265e3f54454b29386a61706f8fe.png
Modbus Poll使用16功能码往保持寄存器地址11开始写10个寄存器,下令设置如下:
https://img-blog.csdnimg.cn/direct/e06d44fd191048319d375eb744d9dc99.png
观察左侧软件提示框信息:
报文数据中的 00 0B 00 0C 00 0D 00 0E 00 0F 00 10 00 11 00 12 00 13 00 14
转换成10进制为11(00 0B),12(00 0C),13,14,15,16,17,18,19,20。
https://img-blog.csdnimg.cn/direct/f3f5f417d72f40c09f8b711ffd00d0e0.png
至此,根本通讯测试完成。
下面补充服务器端,怎样对保持寄存器进行读写,其实很简朴,就是直接访问slave.DataStore.HoldingRegisters中的数据即可。
如下为写入代码:
if (listener != null && slave!=null) {
for (int i = 1;i<11;i++)
{
slave.DataStore.HoldingRegisters = (ushort)(numericUpDown2 .Value* i);
}
WriteInfo("服务器写入1~10完成" + "\r\n");
} 以下为读取代码:
if(slave!=null)
{
string str = "";
for(int i=10;i<20;i++)
{
str += slave.DataStore.HoldingRegisters.ToString() + "";
}
WriteInfo("读取寄存器(地址为10~20):"+str +"\r\n");
}
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]