ModBus通讯协议
方法名
作用
所需参数
返回值
对应功能码
ReadCoils
读取DO的状态
从站地址(8位)
byte slaveAddress
起始地址(16位)
ushort startAddress
读取数量(16位)
ushort numberOfPoints
bool[]
01
ReadInputs
读取DI的状态
从站地址(8位)
byte slaveAddress
起始地址(16位)
ushort startAddress
读取数量(16位)
ushort numberOfPoints
bool[]
02
ReadHoldingRegisters
读取AO的值
从站地址(8位)
byte slaveAddress
起始地址(16位)
ushort startAddress
读取数量(16位)
ushort numberOfPoints
ushort[]
03
ReadInputRegisters
读取AI的值
从站地址(8 位)
byte slaveAddress
起始地址(16位)
ushort startAddress
读取数量(16位)
ushort numberOfPoints
ushort[]
04
WriteSingleCoil
写入值到DO
从站地址(8位)
byte slaveAddress
线圈地址(16位)
ushort coilAddress
写入值(布尔型)
bool value
无返回值
05
WriteSingleRegister
写入值到AO
从站地址(8位)
byte slaveAddress
寄存器地址(16位)
ushort registerAddress
写入值(16位)
ushort value
无返回值
06
WriteMultipleCoils
写多线圈寄存器
从站地址(8位)
byte slaveAddress
起始地址(16位)
ushort startAddress
写入值(布尔型数组)
bool[] data
无返回值
15
WriteMultipleRegisters
写多个保持寄存器
从站地址(8位)
byte slaveAddress
起始地址(16位)
ushort startAddress,
寄存器值(16位整型数组)
ushort[] data
无返回值
16
ReadWriteMultipleRegisters
读写多个保持寄存器
从站地址(8位)
byte slaveAddress
读起始地址(16位)
ushort startReadAddress
读取数量(16位)
ushort numberOfPointsToRead,
写入起始地址(16位)
ushort startWriteAddress,
写入值(16位整型数组)
ushort[] writeData
ushort[]
23
Modbus Slave
这个是安装包ModbusSlaveSetup64Bit 注册码:5455415451475662
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 }