Modbus通信、tcp、udp

页面:

image

代码:

using Modbus.Device;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics.Metrics;
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 static System.Runtime.InteropServices.JavaScript.JSType;
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还是ASCII
                    if (rdRTU.Checked==true)
                    {
                        //创建RTU主站
                        modbusSerialMaster=ModbusSerialMaster.CreateRtu(serialPort);
                    }
                    else
                    {
                        modbusSerialMaster=ModbusSerialMaster.CreateAscii(serialPort);
                    }
                }

            }
            else
            {
                //tcp
                if (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);
                            //异步方法 读取一个或多个保持型寄存器,返回 Task<ushort[]>类型
                            Task<bool[]> task01 = Task.Run(async () =>
                            {
                                return await modbusSerialMaster.ReadCoilsAsync(slaveId, startAddres, count);
                            });
                            //获取返回的数组
                            bool[] datas1 = task01.Result;
                        }
                        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);
                            //异步方法  读取一个或多个保持型寄存器,返回 Task<ushort[]>类型
                            Task<ushort[]> task01 = Task.Run(async () =>
                            {
                                return await modbusSerialMaster.ReadHoldingRegistersAsync(slaveId, startAddr, count);
                            });
                            //获取返回的数组
                            ushort[] datas1 = task01.Result;
                        }
                        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]);
                                //或用异步方法
                                Task.Run(async () =>
                                {
                                    await modbusSerialMaster.WriteSingleRegisterAsync(slaveId, writeStartAdder, sValue[0]);
                                });
                            }
                        }
                        else  //tcp  udp
                        {
                           
                            //写入多线圈
                            if (sValue.Length>1)
                            {
                                modbusMaster.WriteMultipleRegisters(slaveId, writeStartAdder, sValue);
                                //或者使用异步
                                Task.Run(async () =>
                                {
                                    await modbusMaster.WriteMultipleRegistersAsync(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;

            }
        }
    }
}

 

 

using Modbus.Device;using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Diagnostics.Metrics;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 static System.Runtime.InteropServices.JavaScript.JSType;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还是ASCII                    if (rdRTU.Checked==true)                    {                        //创建RTU主站                        modbusSerialMaster=ModbusSerialMaster.CreateRtu(serialPort);                    }                    else                    {                        modbusSerialMaster=ModbusSerialMaster.CreateAscii(serialPort);                    }                }
            }            else            {                //tcp                if (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);                            //异步方法 读取一个或多个保持型寄存器,返回 Task<ushort[]>类型                            Task<bool[]> task01 = Task.Run(async () =>                            {                                return await modbusSerialMaster.ReadCoilsAsync(slaveId, startAddres, count);                            });                            //获取返回的数组                            bool[] datas1 = task01.Result;                        }                        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);                            //异步方法  读取一个或多个保持型寄存器,返回 Task<ushort[]>类型                            Task<ushort[]> task01 = Task.Run(async () =>                            {                                return await modbusSerialMaster.ReadHoldingRegistersAsync(slaveId, startAddr, count);                            });                            //获取返回的数组                            ushort[] datas1 = task01.Result;                        }                        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]);                                //或用异步方法                                Task.Run(async () =>                                {                                    await modbusSerialMaster.WriteSingleRegisterAsync(slaveId, writeStartAdder, sValue[0]);                                });                            }                        }                        else  //tcp  udp                        {                                                       //写入多线圈                            if (sValue.Length>1)                            {                                modbusMaster.WriteMultipleRegisters(slaveId, writeStartAdder, sValue);                                //或者使用异步                                Task.Run(async () =>                                {                                    await modbusMaster.WriteMultipleRegistersAsync(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;
            }        }    }}
 
posted @ 2026-06-17 21:11  旧夏潜入梦  阅读(8)  评论(0)    收藏  举报