C#中的通信-NModbus4

NModbus4介绍

NModbus4是一个用于Modbus通信的开源库,它提供了一套简单易用的API来实现Modbus协议的通信。Modbus是一种应用层协议,主要用于工业自动化领域的电子设备之间的通信。它支持多种通信方式,包括RTU(二进制模式)、ASCII和TCP/IP。

演示如何使用NModbus4库来创建一个Modbus Master,连接到一个Modbus Slave,并读取保持寄存器的值:

using System;
using NModbus;
​
class ModbusDemo
{
    static void Main(string[] args)
    {
        // 创建一个Modbus Master,假设使用TCP/IP通信
        var master = new ModbusSerialMaster("localhost", 502);
​
        // 连接到Modbus Slave,Slave的地址是1
        master.Connect();
        Console.WriteLine("Connected to Modbus Slave at address 1.");
​
        // 读取保持寄存器的值,从地址0开始,读取10个寄存器
        int[] registers = master.ReadHoldingRegisters(1, 0, 10);
        Console.WriteLine("Read 10 holding registers:");
        foreach (var register in registers)
        {
            Console.WriteLine(register);
        }
​
        // 断开连接
        master.Disconnect();
        Console.WriteLine("Disconnected from Modbus Slave.");
    }
}

Rtu

// RTU  
SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
serialPort.Open();
ModbusMaster master = ModbusSerialMaster.CreateRtu(serialPort);
​
 起始地址    “40001”      "I0.0"    "DB1.DBW100"
ushort[] values = master.ReadHoldingRegisters(1, 0, 2);

ModbusRTU 读保持型寄存器报文处理

if (flag == 1)
  {
      List<byte> bytes = new List<byte>();
      bytes.Add(0x01);// 从站地址
      bytes.Add(0x03);// 功能码:读保持型寄存器
      ushort addr = 4;
      // BitConverter      /256    %256
      bytes.Add((byte)(addr / 256));// BitConverter.GetBytes(addr)[1];
      bytes.Add((byte)(addr % 256));// BitConverter.GetBytes(addr)[0];
      ushort len = 2;//寄存器数量 
      bytes.Add((byte)(len / 256));
      bytes.Add((byte)(len % 256));
​
      bytes = CRC16(bytes);// Modbus
​
      // 发送  串口
      SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
      serialPort.Open();
      // 协议的发送间隔时间    传输时间
      // 发送
      serialPort.Write(bytes.ToArray(), 0, bytes.Count);//   事件 C#处理从站逻辑使用    延迟
      // 响应
      byte[] data = new byte[len * 2 + 5];// 正常    异常
      serialPort.Read(data, 0, data.Length);// 串口Read不卡线程    网口Scoket卡线程  事件
      // 自动匹配字节  类型
      for (int i = 3; i < data.Length - 2; i += 4)
      {
          // 封装库的需要注意字节序  
          byte[] vb = new byte[4]
          {
              data[i + 2],//D
              data[i+3 ],//C
              data[i ],//B
              data[i+1]//A
          };
          float v = BitConverter.ToSingle(vb);
          Console.WriteLine(v);
      }
​
      // short 123
      // 64+32+16+8+2+1
      // 0111 1011  0000 0000   
}
​
static List<byte> CRC16(List<byte> value, ushort poly = 0xA001, ushort crcInit = 0xFFFF)
{
    if (value == null || !value.Any())
        throw new ArgumentException("");
​
    //运算
    ushort crc = crcInit;
    for (int i = 0; i < value.Count; i++)
    {
        crc = (ushort)(crc ^ (value[i]));
        for (int j = 0; j < 8; j++)
        {
            crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ poly) : (ushort)(crc >> 1);
        }
    }
    byte hi = (byte)((crc & 0xFF00) >> 8);  //高位置
    byte lo = (byte)(crc & 0x00FF);         //低位置
​
    List<byte> buffer = new List<byte>();
    buffer.AddRange(value);
    buffer.Add(lo);
    buffer.Add(hi);
    return buffer;
}

ModbusRTU 写保持型寄存器报文处理

if (flag == 2)
 {
     List<byte> bytes = new List<byte>();
     bytes.Add(0x01);// 从站地址
     bytes.Add(0x06);// 功能码:读保持型寄存器
     ushort addr = 3;
     // BitConverter      /256    %256
     bytes.Add((byte)(addr / 256));// BitConverter.GetBytes(addr)[1];
     bytes.Add((byte)(addr % 256));// BitConverter.GetBytes(addr)[0];
     ushort value = 100;//寄存器数量 
     bytes.Add((byte)(value / 256));// 高位
     bytes.Add((byte)(value % 256));// 低位
​
     bytes = CRC16(bytes);// Modbus
​
     SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
     serialPort.Open();
     serialPort.Write(bytes.ToArray(), 0, bytes.Count);
 }
static List<byte> CRC16(List<byte> value, ushort poly = 0xA001, ushort crcInit = 0xFFFF)
{
    if (value == null || !value.Any())
        throw new ArgumentException("");
​
    //运算
    ushort crc = crcInit;
    for (int i = 0; i < value.Count; i++)
    {
        crc = (ushort)(crc ^ (value[i]));
        for (int j = 0; j < 8; j++)
        {
            crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ poly) : (ushort)(crc >> 1);
        }
    }
    byte hi = (byte)((crc & 0xFF00) >> 8);  //高位置
    byte lo = (byte)(crc & 0x00FF);         //低位置
​
    List<byte> buffer = new List<byte>();
    buffer.AddRange(value);
    buffer.Add(lo);
    buffer.Add(hi);
    return buffer;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值