C#使用Modbus协议读写汇川PLC的M区寄存器(基本接口封装)

本文档详细介绍了如何使用C#通过Modbus-TCP协议与汇川PLC进行通信,包括读写基本数据类型、字节流和字符串。代码实现了连接、断开PLC,以及读写不同数据类型的函数,特别处理了字符串的字节顺序和长度问题。

C#使用Modbus-TCP协议读取汇川PLC,Modbus读写是按照MW地址来处理的

【寄存器单位是字WORD,占用两个字节,类似于C#中的ushort(UInt16)】,实际测试发现字符串是按照字节颠倒的

本文封装函数为基础数据类型读写,字节流读写、长字符串读写。

主要封装函数有:

public int WriteValue<T>(int startAddress, T value, out string msg) where T : struct

public int WriteValue(int startAddress, byte[] buffer, out string msg)

public int WriteString(int startAddress, int length, string barcode, out string msg)

public int WriteLongString(int startAddress, string longString, out string msg)

public int ReadValue<T>(int startAddress, out T value, out string msg) where T : struct

public int ReadValue(int startAddress, int length, out byte[] values, out string msg)

public int ReadLongString(int startAddress, int length, out string longString, out string msg)

源程序如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace InovancePlcDemo
{
    /// <summary>
    /// 汇川PLC读写地址表
    /// 斯内科 20210907
    /// </summary>
    public class InovanceTcp
    {
        /// <summary>
        /// 是否已连接
        /// </summary>
        public bool IsConnected;
        /// <summary>
        /// 字节存放类型,汇川PLC默认为CDAB
        /// </summary>
        public StoreByteCategory StoreByteCategory { get; set; }
        /// <summary>
        /// 是否字符串颠倒,相邻两个字符交换位置【比如:ABCD存放是BADC】
        /// </summary>
        public bool IsStringReverse = true;
        string ip;
        int port;
        /// <summary>
        /// TCP客户端对象
        /// </summary>
        TcpClient msender;
        /// <summary>
        /// TCP连接成功后生成的发送和接收Session会话对象
        /// </summary>
        Socket msock;
        /// <summary>
        /// 记录Modbus的发送和接收数据包事件
        /// 第一个参数是发送的数据包,第二个参数是响应的数据包,第三个参数的获取到响应数据包所花费的时间(ms)
        /// </summary>
        public event Action<byte[], byte[], double> RecordDataEvent;

        /// <summary>
        /// 汇川PLC的Modbus协议Tcp连接的构造函数(PLC的IP地址、PLC端口号、本机节点)
        /// </summary>
        /// <param name="ip">IP地址</param>
        /// <param name="port">端口号,默认502</param>
        /// <returns>实例化一个Modbus协议Tcp连接</returns>
        public InovanceTcp(string ip, int port, StoreByteCategory storeByteCategory = StoreByteCategory.CDAB, bool isStringReverse = true)
        {
            this.ip = ip;
            this.port = port;
            this.StoreByteCategory = storeByteCategory;
            this.IsStringReverse = isStringReverse;
            IsConnected = false;
        }

        /// <summary>
        /// 断开连接
        /// </summary>
        public void DisConnect()
        {
            msender?.Close();
            msock?.Close();
            msock?.Dispose();
            IsConnected = false;
        }

        /// <summary>
        /// 连接PLC
        /// </summary>
        public void Connect()
        {
            if (!IsConnected)
            {
                msender = new TcpClient(ip, port);
                msock = msender.Client;
                msock.ReceiveTimeout = 3000;
                IsConnected = true;
            }
        }

        /// <summary>
        /// 写基本数据类型到PLC,如bool,short,int,uint,float等
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="startAddress">起始寄存器地址,以字(WORD)为单位,形如MW32000</param>
        /// <param name="value"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public int WriteValue<T>(int startAddress, T value, out string msg) where T : struct
        {
            byte[] datas = new byte[0];
            if (typeof(T) == typeof(bool))
            {
                datas = BitConverter.GetBytes(Convert.ToBoolean(value));
            }
            else if (typeof(T) == typeof(sbyte))
            {
                datas = new byte[1] { (byte)Convert.ToSByte(value) };
            }
            else if (typeof(T) == typeof(byte))
            {
                datas = new byte[1] { Convert.ToByte(value) };
            }
            else if (typeof(T) == typeof(short))
            {
                datas = BitConverter.GetBytes(Convert.ToInt16(value));
            }
            else if (typeof(T) == typeof(ushort))
            {
                datas = BitConverter.GetBytes(Convert.ToUInt16(value));
            }
            else if (typeof(T) == typeof(int))
            {
                datas = BitConverter.GetBytes(Convert.ToInt32(value));
            }
            else if (typeof(T) == typeof(uint))
            {
                datas = BitConverter.GetBytes(Convert.
评论 10
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

斯内科

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值