Modbus通信、tcp、udp

页面:

image

代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Modbus.Device;
namespace WinUpperCourse
{public partial class WinNModbus4Test : Form{public WinNModbus4Test(){InitializeComponent();}//声明串口SerialPort serialPort = null;TcpClient tcpClient = null;UdpClient udpClient = null;//创建主站对象IModbusSerialMaster modbusSerialMaster = null; //串口IModbusMaster modbusMaster = null;//网口private void WinNModbus4Test_Load(object sender, EventArgs e){//初始化控件值this.cmInfoType.Items.AddRange(new[] { "串口", "TCP", "UDP" });this.cmInfoType.SelectedIndex=0;//初始化串口string[] portItem = SerialPort.GetPortNames();this.cmPort.Items.AddRange(portItem);this.cmPort.SelectedIndex = 0;this.cmBaudRate.Items.Add("9600");this.cmBaudRate.SelectedIndex = 0;Parity[] parityItem = new[] { Parity.None, Parity.Odd, Parity.Even };cmParity.Items.AddRange(parityItem.Cast<object>().ToArray());this.cmParity.SelectedIndex = 0;this.cmDataBits.Items.AddRange(new string[] { "8", "9" });this.cmDataBits.SelectedIndex = 0;StopBits[] stopBitsItem = new[] { StopBits.One, StopBits.None };this.cmStopBits.Items.AddRange(stopBitsItem.Cast<object>().ToArray());this.cmStopBits.SelectedIndex = 0;this.txtIP.Text="127.0.0.1";this.txtPort.Text="302";this.btnStatue.Text="未连接";this.rdRTU.Checked=true;}/// <summary>/// 通信方式选择改变事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void cmInfoType_SelectedIndexChanged(object sender, EventArgs e){if (this.cmInfoType.Text=="串口"){this.txtIP.Enabled = false;this.txtPort.Enabled = false;this.cmPort.Enabled = true;this.cmPort.Enabled=true;this.cmBaudRate.Enabled = true;this.cmParity.Enabled = true;this.cmDataBits.Enabled = true;this.cmStopBits.Enabled = true;this.cmParity.Enabled = true;}else{this.cmPort.Enabled = false;this.cmPort.Enabled=false;this.cmBaudRate.Enabled = false;this.cmParity.Enabled = false;this.cmDataBits.Enabled = false;this.cmStopBits.Enabled = false;this.cmParity.Enabled = false;this.txtIP.Enabled = true;this.txtPort.Enabled = true;}}/// <summary>/// 打开连接/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnOpen_Click(object sender, EventArgs e){//如果是串口if (this.cmInfoType.Text=="串口"){// 1. 转换波特率、数据位int baudRate = int.Parse(cmBaudRate.Text);int dataBits = int.Parse(cmDataBits.Text);// 2. 校验位文本转 Parity 枚举  校验位// Enum.TryParse(cmParity.Text, true, out Parity parity);Parity parity = Enum.Parse<Parity>(cmParity.Text);// 3. 停止位文本转 StopBits 枚举 停止位Enum.TryParse(cmStopBits.Text, true, out StopBits stopBits);// 4. 实例化串口serialPort = new SerialPort(cmPort.Text,baudRate,parity,dataBits,stopBits);//打开
                serialPort.Open();if (serialPort!=null&&serialPort.IsOpen){this.Invoke(new Action(() => { this.btnStatue.Text = "串口已连接"; }));//判断是 RTU还是ASCIIif (rdRTU.Checked==true){//创建RTU主站modbusSerialMaster=ModbusSerialMaster.CreateRtu(serialPort);}else{modbusSerialMaster=ModbusSerialMaster.CreateAscii(serialPort);}}}else{//tcpif (this.cmInfoType.Text=="TCP"){tcpClient=new TcpClient(this.txtIP.Text, int.Parse(this.txtPort.Text));this.Invoke(new Action(() => { this.btnStatue.Text = "tcp已连接"; }));modbusMaster=ModbusIpMaster.CreateIp(tcpClient);}else //upd
                {udpClient=new UdpClient(this.txtIP.Text, int.Parse(this.txtPort.Text));this.Invoke(new Action(() => { this.btnStatue.Text = "upd已连接"; }));modbusMaster=ModbusIpMaster.CreateIp(udpClient);}}}/// <summary>/// 断开连接/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnClose_Click(object sender, EventArgs e){if (this.cmInfoType.Text=="串口"){serialPort.Close();this.Invoke(new Action(() => { this.btnStatue.Text = "串口连接断开"; }));}else if (this.cmInfoType.Text=="TCP"){tcpClient.Close();this.Invoke(new Action(() =>{this.btnStatue.Text="TCP连接断开";}));}else{udpClient.Close();this.Invoke(new Action(() =>{this.btnStatue.Text="UDP连接断开";}));}}/// <summary>/// 读取数据/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnRead_Click(object sender, EventArgs e){OperationAction(1);}/// <summary>/// 写入/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnWrite_Click(object sender, EventArgs e){OperationAction(2);}/// <summary>/// 读写操作/// </summary>/// <param name="type">1:读,2:写</param>public void OperationAction(int type){//从站地址byte slaveId = byte.Parse(this.txtSlaveId.Text);//开始地址ushort startAddres = ushort.Parse(this.txtStartAdders.Text);//写入开始地址ushort writeStartAdder = 0;if(type==2){writeStartAdder= ushort.Parse(this.txtWriteStartAdder.Text);}//读取数量ushort count = ushort.Parse(this.txtReadQty.Text);//功能码byte funtionCode = byte.Parse(this.txtFuntionCode.Text);bool[] bValue = null;ushort[] uValue = null;switch (funtionCode){//写操作 只能是功能码1和3 读写都可以,     2和4是只读case 1://读线一个或多个圈状态if (type==1){if (this.cmInfoType.Text=="串口"){bValue = modbusSerialMaster.ReadCoils(slaveId, startAddres, count);}else  //tcp  udp
                        {bValue = modbusMaster.ReadCoils(slaveId, startAddres, count);}this.lbData.Items.Add(string.Join(",", bValue));}else{//写入线圈//  bValue=  this.txtValue.Text.Split(',').Select(str => str=="1" ? true : false).ToArray();bValue=   this.txtValue.Text.Split(',', StringSplitOptions.RemoveEmptyEntries).Select(str => str.Trim() == "1" ? true : false).ToArray();if (this.cmInfoType.Text=="串口"){//写入多线圈if (bValue.Length>1){modbusSerialMaster.WriteMultipleCoils(slaveId, writeStartAdder, bValue);}else{modbusSerialMaster.WriteSingleCoil(slaveId, writeStartAdder, bValue[0]);}}else  //tcp  udp
                        {//写入多线圈if (bValue.Length>1){modbusMaster.WriteMultipleCoils(slaveId, writeStartAdder, bValue);}else{modbusMaster.WriteSingleCoil(slaveId, writeStartAdder, bValue[0]);}}}break;case 2: //读一个或多个输入线圈if (this.cmInfoType.Text=="串口"){bValue = modbusSerialMaster.ReadInputs(slaveId, startAddres, count);}else  //tcp  udp
                    {bValue = modbusMaster.ReadInputs(slaveId, startAddres, count);}this.lbData.Items.Add(string.Join(",", bValue));break;case 3: //读一个或多个保持寄存器if(type==1){if (this.cmInfoType.Text=="串口"){uValue = modbusSerialMaster.ReadHoldingRegisters(slaveId, startAddres, count);}else  //tcp  udp
                        {uValue = modbusMaster.ReadHoldingRegisters(slaveId, startAddres, count);}this.lbData.Items.Add(string.Join(",", uValue));}else{ushort[] sValue = this.txtValue.Text.Split(',', StringSplitOptions.RemoveEmptyEntries).Select(str => ushort.Parse(str.Trim())).ToArray();if (this.cmInfoType.Text=="串口"){//写入多线圈if (sValue.Length>1){modbusSerialMaster.WriteMultipleRegisters(slaveId, writeStartAdder, sValue);}else{modbusSerialMaster.WriteSingleRegister(slaveId, writeStartAdder, sValue[0]);}}else  //tcp  udp
                        {//写入多线圈if (sValue.Length>1){modbusMaster.WriteMultipleRegisters(slaveId, writeStartAdder, sValue);}else{modbusMaster.WriteSingleRegister(slaveId, writeStartAdder, sValue[0]);}}}break;case 4: //读一个或多个输入寄存器if (this.cmInfoType.Text=="串口"){uValue = modbusSerialMaster.ReadInputRegisters(slaveId, startAddres, count);}else  //tcp  udp
                    {uValue = modbusMaster.ReadInputRegisters(slaveId, startAddres, count);}this.lbData.Items.Add(string.Join(",", uValue));break;}}}
}