C#上位机:Modbus TCP通讯实例
前言
前文中讲述了使用串口通讯操作Modbus协议报文,但在实际生产环境中,也有很多硬件需要通过TCP接口来操作Modbus 协议。在理解了Modbus的线圈寄存器(可见前文)之后,Modbus TCP可不通过报文的形式来进行读写。在这里我们运用NModbus4,来直观的进行操作。
附上前文链接:
C#上位机:串口通讯
C#上位机:Modbus RTU
一些重点:
所需驱动
在Nuget中引用添加NModbus4,这个包里有着全面的读写函数可直接使用,让我们不用再去复杂的预设报文。
然后添加库
using System;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Modbus.Device;
程序设计
现在我们来从零设计一个Demo。首先,核心的流程如下:
画一个简易页面:
完成了设置的确认,我们来写连接部分:
首先在Load添加接口
Task task1 = new Task(() =>
{
ConnectServer();
});
task1.Start();//启动Task1
我们采用Socket类的TcpClient方式来连接,并异步进行减少卡顿。
public void ConnectServer()
{
if (tcpClient != null) tcpClient.Close();
tcpClient = new TcpClient();
//开始异步
string IP = IPaddress.Text;
IAsyncResult con = tcpClient.BeginConnect(IPAddress.Parse(IP), 502, null, null);
con.AsyncWaitHandle.WaitOne(2000);
if (tcpClient.Connected == false)
{
tcpClient.Close();
ConnStatus.Text = "正在连接服务器 " + ipAddr;
Console.WriteLine("服务器未开启,正在重新连接...");
ConnectServer();
}
else
{
ConnStatus.Text = "已连接-"+IPaddress.Text;
tcpClient.EndConnect(con);
}
}
在测试时请提前准备好供连接的Slave测试,同样可以使用Modbus Slave:
读写线圈
然后是最后一步,我们将对线圈进行读写操作,以写入寄存器为例,先准备好对应的Slave与寄存器:
使用对应的NModbus4提供的方法:
private void button1_Click(object sender, EventArgs e)
{
try
{
master = ModbusIpMaster.CreateIp(tcpClient);
lock (locker)
{
ushort value = (ushort)Convert.ToInt32(ValueForWrite.Text);
ushort adress = (ushort)Convert.ToInt32(AdressForWrite.Text);
slaveID = (byte)Convert.ToInt32(SlaveforWrite.Text);
master.WriteSingleRegister(slaveID,adress, value);
}
}
catch (Exception)
{
}
}
写入成功。
在这里不一一例举,我们可以看看其他可用的方法,
在前文中我们使用串口收发ModbusRTU协议的报文,而在这我们完成了在根本不care报文的情况下读写线圈与寄存器。
注意事项:
1.我都试了一遍之后,尽量使用带有SlaveID的重载函数,不然可能引发未知错误。
2.public static object locker = new object(); 添加互拆锁