精华内容
下载资源
问答
  • C#读取Modbus数据

    万次阅读 多人点赞 2014-10-27 11:08:31
    C#如何读取Modbus数据,Modbus很多人可能一点都不知道,也正常,隔行如隔山嘛。Modbus在自动化行业就不一样,属于路人皆知的东西,很多设备、程序都与Modbus息息相关。 Modbus这个东西,本人也是个二把刀,只有半...

            前面连续写了关于SOCKET编程的东西,似乎有点高大上,为了学习而学习。因此这里我们来整点实际应用的东西。C#如何读取Modbus数据,Modbus很多人可能一点都不知道,也正常,隔行如隔山嘛。Modbus在自动化行业就不一样,属于路人皆知的东西,很多设备、程序都与Modbus息息相关。

            Modbus这个东西,本人也是个二把刀,只有半瓶水,所以在这里晃荡,写点Modbus东西,也是让自己能理解得更深一点,入门级别的东西,希望能帮助到那些像我一样不太了解Modbus,但是又想了解Modbus的同学。

            至于高手,可以吐槽,当然最好是直接绕过。

            闲话少说,书归正传。何谓Modbus

            Modbus通讯协议,ModBus网络是一个工业通信系统,由带智能终端的可编程序控制器和计算机通过公用线路或局部专用线路连接而成。其系统结构既包括硬件、亦包括软件。它可应用于各种数据采集和过程监控。

          Modbus通讯协议是施耐德电气公司......

            Modbus 协议是应用于电子控制器上的一种通用语言。通过此协议,控制器相互之间、控制器经由网络(例如以太网)和其它设备之间可以通信。它已经成为一通用工业标准。有了它,不同厂商生产的控制设备可以连成工业网络,进行集中监控......

          这些都是百度来的,呵呵,别吐槽。网上资料很多,有兴趣的可以自己撸,看多了感觉好像都差不多。

          个人认为所谓的通讯协议,机器、设备或者程序之间相互通讯的一种方式。人与人交流不也有不同的语言或者文字嘛,机器之间当然可以相互发送信息,只要定好规则即可。而Modbus就是与自动化设备用来交流的语言。

          这些理解了也好,不明白其实也不要紧。因为Modbus对于我们码农来说,我们可以大大的缩小理解范围,我们只需要关心与编码有关系东西,对于硬件的那些什么针脚、电缆、信号位都不用太关心,当然如果想成为为一个Modbus方面的专家,那就不同了。

         Modbus分两种模式,一种串口模式,一种是TCP/IP模式。串口模式感觉越来越少,现在大多都是TCP/IP模式,所以这里就暂时写TCP/IP模式

         首先要做就是SOCKET客户端与设备建立连接,因为前面的文章中,关于SOCKET,我们已经说过了,那么下面的代码就非常easy了。说简单点,先不要去想什么Modbus,就认为有一台服务器,开了SOCKET服务在哪里。所以如下代码就水到渠成了。

       

    private TcpClient tcpClient; 
    public bool Open(string ip,int port) {
                try {
                    tcpClient = new TcpClient();
    
                    tcpClient.Connect(IPAddress.Parse(ip), port);
    
                    return true;
                }catch(SocketException e){
                     //LogHelper.WriteLog(e.Message);
                    return false;
                }
            }

             LogHelper代码这里就不写,与主题无关,个人感觉这样的代码也没必要去运行一下,看看能明白就行了。去运行这个事情,有时会耽误太多的时间。这里IP和端口号都是由设备方提供的。真实程序一般都把这两个参数写配置文件中。

           设备连上以后,下一步当然就是读取数据。Modbus的基本原理就是程序向设备请求,需要读取哪个数据,设备就会返回相应的数据。我们知道机器或者说是电脑是只认识01001这样的字符串的。所以所谓的Modbus协议,说得简单一点,就是规定这样一个0101字符各代表什么含义。

        

    /// <summary>
            /// 读取数据 Modbus
            /// </summary>
            /// <param name="rData">结果</param>
            /// <param name="id">设备号</param>
            /// <param name="address">设备地址</param>
            /// <param name="len">长度-多少个设备</param>
            /// <returns>数据读取结果 是否成功</returns>
            public bool ReceiveData(ref short[] rData, short id, short address, short len)
            {
                try
                {
                    short m = Convert.ToInt16(new Random().Next(2, 20));
                    rData = null;
    
                    byte[] bs = Receive(m, id, address, len);
                    byte[] b = TrimModbus(bs, m, id, len);
    
                    if (b==null) { return false; }
    
                    List<short> data = new List<short>(255);
                    for (int i = 0; i < b.Length-1; i++)
                    {
                       if (!Convert.ToBoolean(i & 1))
                       {
                            byte[] temp = new byte[] { b[i+1], b[i] };
                            data.Add(BitConverter.ToInt16(temp, 0));
                       }
                    }
                    rData = data.ToArray();
    
                    return true;
                }
                catch (Exception e) {
                    LogHelper.WriteLog("返回Modbus数据错误"+ e.Message);
                    return false;
                }
            }

    这个其实更多的是处理数据异常,LogHelper与前面一样,核心好像还不在了,就是那个Receive方法。

            /// <summary>
            /// 读取 Modbus
            ///00 00 00 00 00 0d  01  03  0A 14 00  14 00  14 00  14 00  14 00
            /// </summary>
            /// <param name="m">标示</param>
            /// <param name="id">设备码</param>
            /// <param name="address">开始地址</param>
            /// <param name="len">设备数量</param>
            /// <returns></returns>
            private byte[] Receive(short m, short id, short address, short len)
            {
                try
                {
                    if (tcpClient == null || !tcpClient.Connected) { return null; }
    
                    byte[] data = GetSrcData(m, id, address, len);
                    
                    //00 00 00 00 00 06 01 03 00 00 00 05
                    tcpClient.Client.Send(data, data.Length, SocketFlags.None);
    
                    int size = len * 2 + 9;
    
                    byte[] rData = new byte[size];
    
                    tcpClient.Client.Receive(rData, size, SocketFlags.None);
    
                    //string t1 = TranBytes(rData);
    
                    return rData;
    
                }catch(SocketException e){
                    if (e.ErrorCode != 10004)
                    {
                        LogHelper.WriteLog(e.Message);
                    }
    
                    if (tcpClient != null) {
                        tcpClient.Close();
                        tcpClient = null;
                    }
    
                    return null;
                }
            }
            #endregion

    上面的代码可以说是Modbus协议核心,其实就是SOCKET发送数据和接受数据,发送是告诉主机需要取那些的数据。接受就是把主机返回来的数据接受过来。

    //发送
            //00 00 00 00 00 06 01 03 00 00 00 05
            /// <summary>
            /// 发送字节数
            /// </summary>
            /// <param name="m"></param>
            /// <param name="len"></param>
            /// <param name="id"></param>
            /// <param name="address"></param>
            /// <returns></returns>
            private byte[] GetSrcData(short m, short id, short add, short len)
            {
                List<byte> data = new List<byte>(255);
    
                data.AddRange(ValueHelper.Instance.GetBytes(m));                     //             00 01
                data.AddRange(new byte[] { 0x00, 0x00 });                            //             00 00
                data.AddRange(ValueHelper.Instance.GetBytes(Convert.ToInt16(6)));    //字节数       00 06
                data.Add(Convert.ToByte(id));                                        //路由码       01
                data.Add(Convert.ToByte(3));                                         //功能码 3-读  03
                data.AddRange(ValueHelper.Instance.GetBytes(add));                   //开始地址     00 00
                data.AddRange(ValueHelper.Instance.GetBytes(len));                   //设备数量     00 05
                return data.ToArray();
            }

     好,到这里基本上搞定了。其实很多逻辑都在代码中,说简单的就是某个ID设备,从哪个地址开始,读几个设备的值,这里需要注意是short 不要用32位的int去替换,结果会不一样的。仔细看看估计大家都能明白,也没有什么神秘的东西。

    哦,对了还ValueHelper代码

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Modbus {
        public class ValueHelper
        {
            #region 大小端判断
    
            public static bool LittleEndian = false;
    
            static ValueHelper()
            {
                unsafe
                {
                    int tester = 1;
                    LittleEndian = (*(byte*)(&tester)) == (byte)1;
                }
            }
            #endregion
    
            #region Factory
            public static ValueHelper _Instance = null;
            internal static ValueHelper Instance
            {
                get
                {
                    if (_Instance == null)
                    {
                        _Instance = LittleEndian ? new LittleEndianValueHelper() : new ValueHelper();
                        //_Instance = new ValueHelper();
                    }
                    return _Instance;
                }
            }
            #endregion
    
            protected ValueHelper()
            {
    
            }
    
            public virtual Byte[] GetBytes(short value)
            {
                return BitConverter.GetBytes(value);
            }
    
            public virtual Byte[] GetBytes(int value)
            {
                return BitConverter.GetBytes(value);
            }
    
            public virtual Byte[] GetBytes(float value)
            {
                return BitConverter.GetBytes(value);
            }
    
            public virtual Byte[] GetBytes(double value)
            {
                return BitConverter.GetBytes(value);
            }
    
            public virtual short GetShort(byte[] data)
            {
                return BitConverter.ToInt16(data, 0);
            }
    
            public virtual int GetInt(byte[] data)
            {
                return BitConverter.ToInt32(data, 0);
            }
    
            public virtual float GetFloat(byte[] data)
            {
                return BitConverter.ToSingle(data, 0);
            }
    
            public virtual double GetDouble(byte[] data)
            {
                return BitConverter.ToDouble(data, 0);
            }
        }
    
        internal class LittleEndianValueHelper : ValueHelper
        {
            public override Byte[] GetBytes(short value)
            {
                return this.Reverse(BitConverter.GetBytes(value));
            }
    
            public override Byte[] GetBytes(int value)
            {
                return this.Reverse(BitConverter.GetBytes(value));
            }
    
            public override Byte[] GetBytes(float value)
            {
                return this.Reverse(BitConverter.GetBytes(value));
            }
    
            public override Byte[] GetBytes(double value)
            {
                return this.Reverse(BitConverter.GetBytes(value));
            }
    
            public virtual short GetShort(byte[] data)
            {
                return BitConverter.ToInt16(this.Reverse(data), 0);
            }
    
            public virtual int GetInt(byte[] data)
            {
                return BitConverter.ToInt32(this.Reverse(data), 0);
            }
    
            public virtual float GetFloat(byte[] data)
            {
                return BitConverter.ToSingle(this.Reverse(data), 0);
            }
    
            public virtual double GetDouble(byte[] data)
            {
                return BitConverter.ToDouble(this.Reverse(data), 0);
            }
    
            private Byte[] Reverse(Byte[] data)
            {
                Array.Reverse(data);
                return data;
            }
        }
    }
    

    不好意思,有个方法给忘记了

     private byte[] TrimModbus(byte[] d, short m, short id, short len)
            {
                int size = Convert.ToInt32(len) * 2;
                int dLen = size + 9;
    
                if (d == null || d.Length != dLen || m != Convert.ToInt16(d[1]) || id != Convert.ToInt16(d[6]))
                {
                    return null;
                }
                byte[] n = new byte[size];
                Array.Copy(d, 9, n, 0, size);
                return n;
            }

    所有代码都贴出来了,但是如果实在想运行的,也是需要简单整理的。实在想要代码的,请发邮件 blank250@163.com

    展开全文
  • c#读取modbus数据

    2020-08-13 17:34:32
    https://www.cnblogs.com/MuZiJin/p/11753826.html

    https://www.cnblogs.com/MuZiJin/p/11753826.html

    展开全文
  • C#如何读取Modbus数据,Modbus很多人可能一点都不知道,也正常,隔行如隔山嘛。Modbus在自动化行业就不一样,属于路人皆知的东西,很多设备、程序都与Modbus息息相关。 Modbus这个东西,本人也是个二把刀,只有半...
    前面连续写了关于SOCKET编程的东西,似乎有点高大上,为了学习而学习。因此这里我们来整点实际应用的东西。C#如何读取Modbus数据,Modbus很多人可能一点都不知道,也正常,隔行如隔山嘛。Modbus在自动化行业就不一样,属于路人皆知的东西,很多设备、程序都与Modbus息息相关。
    
            Modbus这个东西,本人也是个二把刀,只有半瓶水,所以在这里晃荡,写点Modbus东西,也是让自己能理解得更深一点,入门级别的东西,希望能帮助到那些像我一样不太了解Modbus,但是又想了解Modbus的同学。
    
            至于高手,可以吐槽,当然最好是直接绕过。
    
            闲话少说,书归正传。何谓Modbus
    
            Modbus通讯协议,ModBus网络是一个工业通信系统,由带智能终端的可编程序控制器和计算机通过公用线路或局部专用线路连接而成。其系统结构既包括硬件、亦包括软件。它可应用于各种数据采集和过程监控。
    
          Modbus通讯协议是施耐德电气公司......
    
            Modbus 协议是应用于电子控制器上的一种通用语言。通过此协议,控制器相互之间、控制器经由网络(例如以太网)和其它设备之间可以通信。它已经成为一通用工业标准。有了它,不同厂商生产的控制设备可以连成工业网络,进行集中监控......
    
          这些都是百度来的,呵呵,别吐槽。网上资料很多,有兴趣的可以自己撸,看多了感觉好像都差不多。
    
          个人认为所谓的通讯协议,机器、设备或者程序之间相互通讯的一种方式。人与人交流不也有不同的语言或者文字嘛,机器之间当然可以相互发送信息,只要定好规则即可。而Modbus就是与自动化设备用来交流的语言。
    
          这些理解了也好,不明白其实也不要紧。因为Modbus对于我们码农来说,我们可以大大的缩小理解范围,我们只需要关心与编码有关系东西,对于硬件的那些什么针脚、电缆、信号位都不用太关心,当然如果想成为为一个Modbus方面的专家,那就不同了。
    
         Modbus分两种模式,一种串口模式,一种是TCP/IP模式。串口模式感觉越来越少,现在大多都是TCP/IP模式,所以这里就暂时写TCP/IP模式
    
         首先要做就是SOCKET客户端与设备建立连接,因为前面的文章中,关于SOCKET,我们已经说过了,那么下面的代码就非常easy了。说简单点,先不要去想什么Modbus,就认为有一台服务器,开了SOCKET服务在哪里。所以如下代码就水到渠成了。
        public bool Open(string ip,int port) {
                    try {
                        tcpClient = new TcpClient();
         
                        tcpClient.Connect(IPAddress.Parse(ip), port);
         
                        return true;
                    }catch(SocketException e){
                        string m = string.Format("modbus Client服务器连接错误:{0},ip:{1},port:{2}", e.Message, ip, port);
                        LogHelper.WriteLog(m);
                        return false;
                    }
                }
    
             其中LogHelper代码这里就不写,因为与主题无关,如果想运行上面代码的话,注释就行了,我个人推荐这样的代码也没必要去运行一下,看看能明白就行了。去运行这个事情,有事会耽误太多的时间。这里IP和端口号都是由设备方提供的。真实程序一般都把这两个参数写配置文件中。
    
           设备连上以后,下一步当然就是读取数据。Modbus的基本原理就是程序向设备请求,需要读取哪个数据,设备就会返回相应的数据。我们知道机器或者说是电脑是只认识01001这样的字符串的。所以所谓的Modbus协议,说得简单一点,就是规定这样一个0101字符各代表什么含义。
    
        
    
        /// <summary>
                /// 读取数据 Modbus
                /// </summary>
                /// <param name="rData">结果</param>
                /// <param name="id">设备号</param>
                /// <param name="address">设备地址</param>
                /// <param name="len">长度-多少个设备</param>
                /// <returns>数据读取结果 是否成功</returns>
                public bool ReceiveData(ref short[] rData, short id, short address, short len)
                {
                    try
                    {
                        short m = Convert.ToInt16(new Random().Next(2, 20));
                        rData = null;
         
                        byte[] bs = Receive(m, id, address, len);
                        byte[] b = TrimModbus(bs, m, id, len);
         
                        if (b==null) { return false; }
         
                        List<short> data = new List<short>(255);
                        for (int i = 0; i < b.Length-1; i++)
                        {
                           if (!Convert.ToBoolean(i & 1))
                           {
                                byte[] temp = new byte[] { b[i+1], b[i] };
                                data.Add(BitConverter.ToInt16(temp, 0));
                           }
                        }
                        rData = data.ToArray();
         
                        return true;
                    }
                    catch (Exception e) {
                        LogHelper.WriteLog("返回Modbus数据错误"+ e.Message);
                        return false;
                    }
                }
    
    这个其实更多的是处理数据异常,LogHelper与前面一样,核心好像还不在了,就是那个Receive方法。
    
                /// <summary>
                /// 读取 Modbus
                ///00 00 00 00 00 0d  01  03  0A 14 00  14 00  14 00  14 00  14 00
                /// </summary>
                /// <param name="m">标示</param>
                /// <param name="id">设备码</param>
                /// <param name="address">开始地址</param>
                /// <param name="len">设备数量</param>
                /// <returns></returns>
                private byte[] Receive(short m, short id, short address, short len)
                {
                    try
                    {
                        if (tcpClient == null || !tcpClient.Connected) { return null; }
         
                        byte[] data = GetSrcData(m, id, address, len);
                        
                        //00 00 00 00 00 06 01 03 00 00 00 05
                        tcpClient.Client.Send(data, data.Length, SocketFlags.None);
         
                        int size = len * 2 + 9;
         
                        byte[] rData = new byte[size];
         
                        tcpClient.Client.Receive(rData, size, SocketFlags.None);
         
                        //string t1 = TranBytes(rData);
         
                        return rData;
         
                    }catch(SocketException e){
                        if (e.ErrorCode != 10004)
                        {
                            LogHelper.WriteLog(e.Message);
                        }
         
                        if (tcpClient != null) {
                            tcpClient.Close();
                            tcpClient = null;
                        }
         
                        return null;
                    }
                }
                #endregion
    
    上面的代码可以说是Modbus协议核心,其实就是SOCKET发送数据和接受数据,发送是告诉主机需要取那些的数据。接受就是把主机返回来的数据接受过来。
    
        //发送
                //00 00 00 00 00 06 01 03 00 00 00 05
                /// <summary>
                /// 发送字节数
                /// </summary>
                /// <param name="m"></param>
                /// <param name="len"></param>
                /// <param name="id"></param>
                /// <param name="address"></param>
                /// <returns></returns>
                private byte[] GetSrcData(short m, short id, short add, short len)
                {
                    List<byte> data = new List<byte>(255);
         
                    data.AddRange(ValueHelper.Instance.GetBytes(m));                     //             00 01
                    data.AddRange(new byte[] { 0x00, 0x00 });                            //             00 00
                    data.AddRange(ValueHelper.Instance.GetBytes(Convert.ToInt16(6)));    //字节数       00 06
                    data.Add(Convert.ToByte(id));                                        //路由码       01
                    data.Add(Convert.ToByte(3));                                         //功能码 3-读  03
                    data.AddRange(ValueHelper.Instance.GetBytes(add));                   //开始地址     00 00
                    data.AddRange(ValueHelper.Instance.GetBytes(len));                   //设备数量     00 05
                    return data.ToArray();
                }
    
     好,到这里基本上搞定了。其实很多逻辑都在代码中,说简单的就是某个ID设备,从哪个地址开始,读几个设备的值,这里需要注意是short 不要用32位的int去替换,结果会不一样的。仔细看看估计大家都能明白,也没有什么神秘的东西。
    
    哦,对了还ValueHelper代码
    
        using System;
        using System.Collections.Generic;
        using System.Text;
         
        namespace Modbus {
            public class ValueHelper
            {
                #region 大小端判断
         
                public static bool LittleEndian = false;
         
                static ValueHelper()
                {
                    unsafe
                    {
                        int tester = 1;
                        LittleEndian = (*(byte*)(&tester)) == (byte)1;
                    }
                }
                #endregion
         
                #region Factory
                public static ValueHelper _Instance = null;
                internal static ValueHelper Instance
                {
                    get
                    {
                        if (_Instance == null)
                        {
                            _Instance = LittleEndian ? new LittleEndianValueHelper() : new ValueHelper();
                            //_Instance = new ValueHelper();
                        }
                        return _Instance;
                    }
                }
                #endregion
         
                protected ValueHelper()
                {
         
                }
         
                public virtual Byte[] GetBytes(short value)
                {
                    return BitConverter.GetBytes(value);
                }
         
                public virtual Byte[] GetBytes(int value)
                {
                    return BitConverter.GetBytes(value);
                }
         
                public virtual Byte[] GetBytes(float value)
                {
                    return BitConverter.GetBytes(value);
                }
         
                public virtual Byte[] GetBytes(double value)
                {
                    return BitConverter.GetBytes(value);
                }
         
                public virtual short GetShort(byte[] data)
                {
                    return BitConverter.ToInt16(data, 0);
                }
         
                public virtual int GetInt(byte[] data)
                {
                    return BitConverter.ToInt32(data, 0);
                }
         
                public virtual float GetFloat(byte[] data)
                {
                    return BitConverter.ToSingle(data, 0);
                }
         
                public virtual double GetDouble(byte[] data)
                {
                    return BitConverter.ToDouble(data, 0);
                }
            }
         
            internal class LittleEndianValueHelper : ValueHelper
            {
                public override Byte[] GetBytes(short value)
                {
                    return this.Reverse(BitConverter.GetBytes(value));
                }
         
                public override Byte[] GetBytes(int value)
                {
                    return this.Reverse(BitConverter.GetBytes(value));
                }
         
                public override Byte[] GetBytes(float value)
                {
                    return this.Reverse(BitConverter.GetBytes(value));
                }
         
                public override Byte[] GetBytes(double value)
                {
                    return this.Reverse(BitConverter.GetBytes(value));
                }
         
                public virtual short GetShort(byte[] data)
                {
                    return BitConverter.ToInt16(this.Reverse(data), 0);
                }
         
                public virtual int GetInt(byte[] data)
                {
                    return BitConverter.ToInt32(this.Reverse(data), 0);
                }
         
                public virtual float GetFloat(byte[] data)
                {
                    return BitConverter.ToSingle(this.Reverse(data), 0);
                }
         
                public virtual double GetDouble(byte[] data)
                {
                    return BitConverter.ToDouble(this.Reverse(data), 0);
                }
         
                private Byte[] Reverse(Byte[] data)
                {
                    Array.Reverse(data);
                    return data;
                }
            }
        }
    
    不好意思,有个方法给忘记了
         private byte[] TrimModbus(byte[] d, short m, short id, short len)
                {
                    int size = Convert.ToInt32(len) * 2;
                    int dLen = size + 9;
         
                    if (d == null || d.Length != dLen || m != Convert.ToInt16(d[1]) || id != Convert.ToInt16(d[6]))
                    {
                        return null;
                    }
                    byte[] n = new byte[size];
                    Array.Copy(d, 9, n, 0, size);
                    return n;
                }
    
    所有代码都贴出来了,但是如果实在想运行的,也是需要简单整理的。
    
    展开全文
  • 使用NModBus组件读取modbus设备上的参数,温度和湿度,仅供新手使用,建议使用最新版vs打开运行。
  • 我现在需要设计一款app,可以读取我的PLC里的寄存器值。 目前我可以通过button 链接到port,并且读取到寄存器数值。但是软件与PLC只链接一会就自动断开了。请问怎么可以实现一直接通,并且循环读取寄存器的值呢—— ...
  • C#编程之C# Modbus 数据读取 使用NModBus4库 http://m.zhizuobiao.com/net/net-18091700173/ 2018-09-17 来自 03142 摘要:本文主要向大家介绍了C#编程之C# Modbus 数据读取 使用NModBus4库,通过具体的内容向...

    C#编程之C# Modbus 数据读取 使用NModBus4库

    http://m.zhizuobiao.com/net/net-18091700173/

    2018-09-17 来自 03142

    摘要:本文主要向大家介绍了C#编程之C# Modbus 数据读取 使用NModBus4库,通过具体的内容向大家展示,希望对大家学习C#编程有所帮助。

    本文主要向大家介绍了C#编程之C#  Modbus 数据读取  使用NModBus4库,通过具体的内容向大家展示,希望对大家学习C#编程有所帮助。

    方法名    作用    所需参数    返回值    对应功能码    

    ReadCoils    读取DO的状态    从站地址(8位)    bool[]    1    

    byte slaveAddress    

    起始地址(16位)    

     

    ushort startAddress    

    读取数量(16位)    

    ushort numberOfPoints    

    ReadInputs    读取DI的状态    从站地址(8位)    bool[]    2    

    byte slaveAddress    

    起始地址(16位)    

     

    ushort startAddress    

    读取数量(16位)    

    ushort numberOfPoints    

    ReadHoldingRegisters    读取AO的值    从站地址(8位)    ushort[]    3    

    byte slaveAddress    

    起始地址(16位)     

    ushort startAddress    

    读取数量(16位)    

    ushort numberOfPoints    

    ReadInputRegisters    读取AI的值    从站地址(8 位)    ushort[]    4    

    byte slaveAddress    

    起始地址(16位)    

     

    ushort startAddress    

    读取数量(16位)    

    ushort numberOfPoints    

    WriteSingleCoil    写入值到DO    从站地址(8位)    无返回值    5    

    byte slaveAddress    

    线圈地址(16位)    

    ushort coilAddress    

    写入值(布尔型)    

    bool value    

    WriteSingleRegister    写入值到AO    从站地址(8位)    无返回值    6    

    byte slaveAddress    

    寄存器地址(16位)    

    ushort registerAddress    

    写入值(16位)    

    ushort value    

    WriteMultipleCoils    写多线圈寄存器    从站地址(8位)    无返回值    15    

    byte slaveAddress    

    起始地址(16位)    

    ushort startAddress    

    写入值(布尔型数组)    

    bool[] data    

    WriteMultipleRegisters    写多个保持寄存器    从站地址(8位)    无返回值    16    

    byte slaveAddress    

     

    起始地址(16位)    

    ushort startAddress,    

    寄存器值(16位整型数组)    

    ushort[] data    

    ReadWriteMultipleRegisters    读写多个保持寄存器    从站地址(8位)    ushort[]    23    

    byte slaveAddress    

    读起始地址(16位)    

    ushort startReadAddress    

     

    读取数量(16位)    

    ushort numberOfPointsToRead,    

    写入起始地址(16位)    

    ushort startWriteAddress,    

    写入值(16位整型数组)    

    ushort[] writeData    


    modbus通讯协议NET库
        这样的开源库很多,我这边用的库是github的开源实现类库:NModBus4,github地址:https://github.com/NModbus4/NModbus4
     
              我用Modbus Slave模拟一个从机
                
               设置数据
                
     
               NModbus4的读取从机代码示例
               
     1             IPAddress address = new IPAddress(new byte[] { 127, 0, 0, 1 });
     2             using (TcpClient client = new TcpClient(address.ToString(), 502))
     3             {
     4                 client.SendTimeout = 1;
     5                 //client.op
     6                 ModbusIpMaster master = ModbusIpMaster.CreateIp(client);
     7                 //master.op
     8                 // read five input values
     9                 ushort startAddress = 0;
    10                 ushort numInputs = 10;
    11                 bool[] inputs = master.ReadCoils(1, startAddress, numInputs);
    12 
    13                 for (int i = 0; i < numInputs; i++)
    14                 {
    15                     Console.WriteLine($"Input {(startAddress + i)}={(inputs[i] ? 1 : 0)}");
    16                 }
    17 
    18             }
       这边值得注意的是主机Read的方法第一个参数是slaveId  如果不加就startAddress And numInputs   NModbus就会默认 slaveId是0  一直异常( d(╯﹏╰)b 痛苦经历~~)
     
       
       以上数据是 刚才设置的DO 状态
       在演示一个读取AI的值
         
         
     
         代码没差多少就是方法ReadInputRegisters不一样  . 以下是示例代码
     1 IPAddress address = new IPAddress(new byte[] { 127, 0, 0, 1 });
     2             using (TcpClient client = new TcpClient(address.ToString(), 502))
     3             {
     4                 client.SendTimeout = 1;
     5                 //client.op
     6                 ModbusIpMaster master = ModbusIpMaster.CreateIp(client);
     7                 //master.op
     8                 // read five input values
     9                 ushort startAddress = 0;
    10                 ushort numInputs = 10;
    11                 ushort[] inputs = master.ReadInputRegisters(2, startAddress, numInputs);
    12 
    13                 for (int i = 0; i < numInputs; i++)
    14                 {
    15                     Console.WriteLine($"Register {(startAddress + i)}={(inputs[i])}");
    16                 }
    17 
    18             }

    展开全文
  • 如题,已经实现读数,但是速度不是特别快,有没有超快速的读取方法?
  • 如图,我设定读取线圈的值为1011001011,把他在c#里面作为发送包发送读取到的结果为77和3,77对应二进制为01001101,3为00000011. 而77的二进制值与设定值前八位正好相反,请问是怎么回事?[img=...
  • 串口通信理论与实例: 读取串口 C#实例代码 串口调试软件 RS232/RS485 上下位机通信原理 Modbus通信编程规范(中文) CRC校验
  • C#读取串口数据封装, RS485、232 MODBUS通讯协议,亲测可用
  • 本程序能够自动读取温度数据,采用C#实现,对刚接触串口通讯的童鞋具有重要的意义。
  • 这是一款基于C#的简单实用的数据测试工具的后台代码文件
  • C# Modbus 数据读取 使用NModBus4库

    千次阅读 2019-09-24 00:52:01
    ModBus通讯协议 方法名 作用 所需参数 返回值 对应功能码 ReadCoils 读取DO的状态 从站地址(8位) byte slaveAddress 起始地址(16位) ushort startAddress...
  • C#编成Modbus TCP连接PLC寄存器读取、写入,完整分享源代码,有需要的人可以下载
  • C# ModBus Tcp客户端读取数据 完整Demo

    千次阅读 2019-10-04 19:47:07
    简单介绍:  项目上需要与多家公司做接口对接。我们提供接口的有,其他公司提供的接口也有。所有的接口全部对接完了,遇到一个非常棘手的问题,需要... Modbus是一种串行通信协议,是Modicon公司(现在的施耐德电...
  • C#编成Modbus TCP连接PLC寄存器读取、写入,完整分享源代码,有需要的人可以下载亲测好用,挺不错的资源,大家快来下载吧!挺有用的!需要的话可以来下载哦!
  • 输入参数P1,P2代表PLC中浮点数储存的两个寄存器获取的数据 public static float GetFloat(ushort P1, ushort P2) { int intSign, intSignRest, intExponent, intExponentRest; float faResult, faDigit;...
  • C# modbus TCPIO

    千次阅读 2016-08-10 00:13:45
    C#如何读取Modbus数据,Modbus很多人可能一点都不知道,也正常,隔行如隔山嘛。Modbus在自动化行业就不一样,属于路人皆知的东西,很多设备、程序都与Modbus息息相关。  Modbus这个东西,本人也是个二把刀,只有...
  • 为了拓展自己的知识,最近开始接触使用C#语言进行窗口编程,并最终编写一个工业控制程序通过Modbus通讯读写PLC的梯形图程序,但路漫漫其修远兮,再加上自己边学边练,进度不会很快啦!不过写一点就测试一点,其中的...
  • C#串口通信modbus协议

    2020-06-12 16:09:42
    用于Modbus和串口基于rs485的通讯协议的Demo,主要包括读取线圈/寄存器,写入单个线圈/寄存器,写入多个线圈/寄存器功能,所有功能均已测试过,内附使用截图。
  • C#ModBus Tcp 报文解析

    千次阅读 2019-05-10 21:26:00
    上一篇博客已经完成 C#ModBus Tcp Master的实现 本篇主要对不同的功能码所发出的报文进行解析(包括请求报文及响应报文) 读操作 功能码 0x01 读一组线圈 读取站号为1 从地址12开始的10个线圈 测试结果 上一篇...
  • C# modbus浮点数处理

    2014-05-05 15:30:13
    文档里x1 x2 为读取到浮点数的2个16位寄存器整型数据,返回值就是所需要的浮点数
  • Modbus源码c#

    2019-03-07 16:14:30
    Modbus 通讯dll源码,可以链接Modbus设备读取寄存器
  • c#与485MODBUS串口通信源代码,通过串口读取设备数据,c#的源代码,比如读取PLC数据(AD采集的或设置的),可以控制PLC(支持MODBUS)动作,485通信可以达到500M(稳定通信),也可和单片机通信,我资源里有关于8051...
  • C# ModbusRTU通信寄存器数据读写

    千次阅读 2020-07-13 11:13:52
    先了解ModbusRTU的通信协议。 功能码: 代码 名称 作用 01 读取线圈状态 取得一组逻辑线圈的当前状态(ON/OFF) 02 读取输入状态...
  • modbus tcp源码(C#)

    2018-07-14 02:11:21
    modbus tcp 源码(C#),使用C#语言实现Modbus/tcp通信,实现上位机对下位机的读取

空空如也

空空如也

1 2 3
收藏数 57
精华内容 22
关键字:

c#读取modbus

c# 订阅