C#使用NModbus4读写Modbus数据

26 篇文章 6 订阅

   Modbus是一个免费的协议,协议设计简单,有很多成熟的库支持。比如C#版本的NModubs4就很好,入门简单,使用方便。

首先,在工程中使用NuGet添加NModbus4的包。

在使用文件中,添加引用。不同的接口模式,引用对象不同,Modbus Slave TCP模型需要以下几项:

using System.Net;
using System.Net.Sockets;

using Modbus.Data;
using Modbus.Device;

初始化大概有几个步骤:创建TCP Listener对象、创建ModbusTcpSalve对象、启动侦听服务。

  TcpListener listener = new TcpListener(IPAddress.Parse("0.0.0.0"), 502);
  listener.Start();
  ModbusTcpSlave modbusSlave = ModbusTcpSlave.CreateTcp(1, listener);
  //创建寄存器存储对象
  modbusSlave.DataStore = DataStoreFactory.CreateDefaultDataStore();

Modbus有个DataStore对象,用来存储数据,对应的状态的地址如下:

//01 Coil Status, Addr: 00001
ModbusDataCollection<bool> coilDiscretes = modbusSlave.DataStore.InputDiscretes;

//02 Input Status, Addr: 10001
ModbusDataCollection<bool> inputDiscretes = modbusSlave.DataStore.CoilDiscretes;

//03 Holding Register, Addr: 40001
ModbusDataCollection<ushort> holdingRegisters = modbusSlave.DataStore.HoldingRegisters;

//04 Input Register, Addr: 30001
ModbusDataCollection<ushort> InputRegisters = modbusSlave.DataStore.InputRegisters;

定义之后,就可以直接通过这些对象读写数据了。

NModbus4库已经封装了对于TCP访问数据的封装,服务端只需要维护数据更新即可。

受Modbus协议限制,HoldingRegisters和InputRegisters每个地址仅16位2个字节长度。当实际数据值超过2个字节时,需要占用多个地址空间。比如int32,float都需要4个字节,两个地址。这些数据怎么存放,高低位怎么对齐,就产生了所谓的ABCD、CDAB等转换,这个Master与Slave一致就可以。

Int32等类型数据更新时,需要同时对多个存储地址进行更新,而master可能还在高速并发读数据,需要注意使用一个同步锁,避免数据更新一半就被读取,产生数据不一致问题。

        //将float类型分解成两个ushort类型
        public void SetValue32(ModbusDataCollection<ushort>data,int offset, float value)
        {
            lock (modbusSlave.DataStore.SyncRoot)
            {
                data[offset] = BitConverter.ToUInt16(BitConverter.GetBytes(value), 0); 
                data[offset + 1] = BitConverter.ToUInt16(BitConverter.GetBytes(value), 2); 
            }
        }
        //将int32类型分解成两个ushort类型
        public void SetValue32(ModbusDataCollection<ushort> data, int offset, Int32 value)
        {
            lock (modbusSlave.DataStore.SyncRoot)
            {
                data[offset] = BitConverter.ToUInt16(BitConverter.GetBytes(value), 0);
                data[offset + 1] = BitConverter.ToUInt16(BitConverter.GetBytes(value), 2);
            }
        }

Modbus对于字符串,并没有明确约定。推进使用Unicode编码,首先是与OPC的默认字符串编码格式一致,其次的每个中英文都占用一个地址2个字节,方便计算长度。

        public void SetValueString(ModbusDataCollection<ushort> data, int offset, string value)
        {
            const int maxStringLen = 20;
            lock (modbusSlave.DataStore.SyncRoot)
            {

                byte[] dst = new byte[appConfigModbus.StringLen * 2];
                byte[] bb = Encoding.Unicode.GetBytes(value);
                for (int i = 0; i < bb.Length && i < dst.Length; i++)
                {
                    dst[i] = bb[i];
                }
                for (int i = 0; i < maxStringLen; i += 2)
                {
                    data[offset + i / 2] = BitConverter.ToUInt16(dst, i);
                }
            }
        }

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
nmodbus4是一个C#Modbus通讯库,用于在Windows Forms应用程序中实现Modbus协议的通信。下面是一个简单的示例,演示如何使用nmodbus4实现服务端寄存器。 首先,需要在项目中安装nmodbus4库。可以使用NuGet包管理器或手动下载和安装库。 接下来,在代码中引用nmodbus4库: ``` using Modbus.Data; using Modbus.Device; using Modbus.Utility; using System.IO.Ports; using System.Threading; ``` 然后,创建一个Modbus服务端并打开通信端口: ``` TcpListener slaveTcpListener = new TcpListener(IPAddress.Any, 502); slaveTcpListener.Start(); TcpClient client = slaveTcpListener.AcceptTcpClient(); ModbusSlave slave = ModbusTcpSlave.CreateTcp(1, client); slave.Listen(); ``` 这段代码创建了一个TCP监听器,等待客户端连接。一旦连接成功,就创建一个Modbus从设备,并开始监听客户端请求。 现在,可以使用以下代码来寄存器: ``` ushort[] registers = new ushort[10]; registers[0] = 1234; registers[1] = 5678; //入寄存器 slave.DataStore.HoldingRegisters.WriteRange(0, registers); //取寄存器 ushort[] readRegisters = slave.DataStore.HoldingRegisters.ReadRange(0, 2); ``` 这段代码将一个长度为10的ushort数组Modbus服务端的保持寄存器(HoldingRegisters),然后再取前两个寄存器的值。 完整的代码示例: ``` using Modbus.Data; using Modbus.Device; using Modbus.Utility; using System.IO.Ports; using System.Threading; namespace ModbusServer { class Program { static void Main(string[] args) { TcpListener slaveTcpListener = new TcpListener(IPAddress.Any, 502); slaveTcpListener.Start(); TcpClient client = slaveTcpListener.AcceptTcpClient(); ModbusSlave slave = ModbusTcpSlave.CreateTcp(1, client); slave.Listen(); ushort[] registers = new ushort[10]; registers[0] = 1234; registers[1] = 5678; //入寄存器 slave.DataStore.HoldingRegisters.WriteRange(0, registers); //取寄存器 ushort[] readRegisters = slave.DataStore.HoldingRegisters.ReadRange(0, 2); Console.WriteLine("Register values: {0}, {1}", readRegisters[0], readRegisters[1]); slaveTcpListener.Stop(); } } } ``` 这个示例演示了如何使用nmodbus4库实现Modbus服务端寄存器。当客户端连接到服务端时,可以在保持寄存器中数据,并从中数据

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值