Skip to content

Commit 588337f

Browse files
committed
fix modbus driver
1 parent 7c132d7 commit 588337f

File tree

3 files changed

+56
-58
lines changed

3 files changed

+56
-58
lines changed

SCADA/Program/ModbusDriver/ModbusRTUDriver.cs

Lines changed: 47 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
using System;
1+
using DataService;
2+
using System;
23
using System.Collections.Generic;
34
using System.ComponentModel;
45
using System.IO;
56
using System.IO.Ports;
67
using System.Text;
7-
using System.Timers;
8-
using DataService;
98

109
namespace ModbusDriver
1110
{
@@ -111,8 +110,8 @@ public ModbusRTUReader(IDataServer server, short id, string name, string port =
111110
_serialPort.DataBits = 8;
112111
_serialPort.Parity = Parity.Even;
113112
_serialPort.StopBits = StopBits.One;
114-
if (!string.IsNullOrEmpty(spare1)) byte.TryParse(spare1, out _slaveId);
115113
}
114+
116115
private SerialPort _serialPort;
117116

118117
/*
@@ -125,10 +124,10 @@ public ModbusRTUReader(IDataServer server, short id, string name, string port =
125124
   Long:代表有符号的64位整数,范围从-9223372036854775808 ~ 9223372036854775808
126125
   Ulong:代表无符号的64位整数,范围从0 ~ 18446744073709551615。
127126
*/
128-
private byte[] CreateReadHeader(int startAddress, ushort length, byte function)
127+
private byte[] CreateReadHeader(int id, int startAddress, ushort length, byte function)
129128
{
130129
byte[] data = new byte[8];
131-
data[0] = _slaveId; // Slave id high byte 从站地址
130+
data[0] = (byte)id; // Slave id high byte 从站地址
132131
data[1] = function; // Message size
133132
byte[] _adr = BitConverter.GetBytes((short)startAddress);//以字节数组的形式返回指定的 16 位无符号整数值。
134133
//apply on small endian, TODO:support big endian
@@ -145,10 +144,10 @@ private byte[] CreateReadHeader(int startAddress, ushort length, byte function)
145144
}
146145

147146
#region 写单个线圈或单个离散输出 功能码:0x05
148-
public byte[] WriteSingleCoils(int startAddress, bool OnOff)
147+
public byte[] WriteSingleCoils(int id, int startAddress, bool OnOff)
149148
{
150149
byte[] data = new byte[8];
151-
data[0] = _slaveId; // Slave id high byte
150+
data[0] = (byte)id; // Slave id high byte
152151
data[1] = Modbus.fctWriteSingleCoil; // Function code
153152
byte[] _adr = BitConverter.GetBytes((short)startAddress);
154153
data[2] = _adr[1]; // Start address
@@ -162,11 +161,11 @@ public byte[] WriteSingleCoils(int startAddress, bool OnOff)
162161
#endregion
163162

164163
#region 写多个线圈 功能码:0x0F 15
165-
public byte[] WriteMultipleCoils(int startAddress, ushort numBits, byte[] values)
164+
public byte[] WriteMultipleCoils(int id, int startAddress, ushort numBits, byte[] values)
166165
{
167166
int len = values.Length;
168167
byte[] data = new byte[len + 9];
169-
data[0] = _slaveId; // Slave id high byte 从站地址高八位
168+
data[0] = (byte)id; // Slave id high byte 从站地址高八位
170169
data[1] = Modbus.fctWriteMultipleCoils; // Function code 功能码
171170
byte[] _adr = BitConverter.GetBytes((short)startAddress);
172171
data[2] = _adr[1]; // Start address 开始地址高八位
@@ -184,10 +183,10 @@ public byte[] WriteMultipleCoils(int startAddress, ushort numBits, byte[] values
184183
#endregion
185184

186185
#region 写单个保持寄存器 功能码:0x06
187-
public byte[] WriteSingleRegister(int startAddress, byte[] values)
186+
public byte[] WriteSingleRegister(int id, int startAddress, byte[] values)
188187
{
189188
byte[] data = new byte[8];
190-
data[0] = _slaveId; // Slave id high byte 从站地址高八位
189+
data[0] = (byte)id; // Slave id high byte 从站地址高八位
191190
data[1] = Modbus.fctWriteSingleRegister; // Function code 功能码
192191
byte[] _adr = BitConverter.GetBytes((short)startAddress);
193192
data[2] = _adr[1]; // Start address 开始地址高八位
@@ -202,12 +201,12 @@ public byte[] WriteSingleRegister(int startAddress, byte[] values)
202201
#endregion
203202

204203
#region 写多个保持寄存器 功能码:0x10 16
205-
public byte[] WriteMultipleRegister(int startAddress, byte[] values)
204+
public byte[] WriteMultipleRegister(int id, int startAddress, byte[] values)
206205
{
207206
int len = values.Length;
208207
if (len % 2 > 0) len++;
209208
byte[] data = new byte[len + 9];
210-
data[0] = _slaveId; // Slave id high byte 从站地址
209+
data[0] = (byte)id; // Slave id high byte 从站地址
211210
data[1] = Modbus.fctWriteMultipleRegister; // Function code 功能码
212211
byte[] _adr = BitConverter.GetBytes((short)startAddress);
213212
data[2] = _adr[1]; // Start address 开始地址高八位
@@ -237,47 +236,47 @@ public int PDU
237236
get { return 0xFD; } //0xFD 十进制为253
238237
}
239238

240-
byte _slaveId;//设备ID 单元号 字节号
241-
/// <summary>
242-
/// 设备ID 单元号 字节号
243-
/// </summary>
244-
public byte SlaveId
245-
{
246-
get { return _slaveId; }
247-
set { _slaveId = value; }
248-
}
249-
250239
public DeviceAddress GetDeviceAddress(string address)
251240
{
252241
DeviceAddress dv = DeviceAddress.Empty;
253242
if (string.IsNullOrEmpty(address))
254243
return dv;
244+
var sindex = address.IndexOf(':');
245+
if (sindex > 0)
246+
{
247+
int slaveId;
248+
if (int.TryParse(address.Substring(0, sindex), out slaveId))
249+
dv.Area = slaveId;
250+
address = address.Substring(sindex + 1);
251+
}
255252
switch (address[0])
256253
{
257254
case '0':
258255
{
259-
dv.Area = Modbus.fctReadCoil;
256+
dv.DBNumber = Modbus.fctReadCoil;
260257
int st;
261258
int.TryParse(address, out st);
262259
dv.Bit = (byte)(st % 16);
263260
st /= 16;
264261
dv.Start = st;
262+
dv.Bit--;
265263
}
266264
break;
267265
case '1':
268266
{
269-
dv.Area = Modbus.fctReadDiscreteInputs;
267+
dv.DBNumber = Modbus.fctReadDiscreteInputs;
270268
int st;
271269
int.TryParse(address.Substring(1), out st);
272270
dv.Bit = (byte)(st % 16);
273271
st /= 16;
274272
dv.Start = st;
273+
dv.Bit--;
275274
}
276275
break;
277276
case '4':
278277
{
279278
int index = address.IndexOf('.');
280-
dv.Area = Modbus.fctReadHoldingRegister;
279+
dv.DBNumber = Modbus.fctReadHoldingRegister;
281280
if (index > 0)
282281
{
283282
dv.Start = int.Parse(address.Substring(1, index - 1));
@@ -286,12 +285,14 @@ public DeviceAddress GetDeviceAddress(string address)
286285
else
287286
dv.Start = int.Parse(address.Substring(1));
288287
dv.Start--;
288+
dv.Bit--;
289+
dv.ByteOrder = ByteOrder.Network;
289290
}
290291
break;
291292
case '3':
292293
{
293294
int index = address.IndexOf('.');
294-
dv.Area = Modbus.fctReadInputRegister;
295+
dv.DBNumber = Modbus.fctReadInputRegister;
295296
if (index > 0)
296297
{
297298
dv.Start = int.Parse(address.Substring(1, index - 1));
@@ -300,10 +301,11 @@ public DeviceAddress GetDeviceAddress(string address)
300301
else
301302
dv.Start = int.Parse(address.Substring(1));
302303
dv.Start--;
304+
dv.Bit--;
305+
dv.ByteOrder = ByteOrder.Network;
303306
}
304307
break;
305308
}
306-
dv.Bit--;
307309
return dv;
308310
}
309311

@@ -317,11 +319,11 @@ public string GetAddress(DeviceAddress address)
317319
object _async = new object();
318320
public byte[] ReadBytes(DeviceAddress address, ushort size)
319321
{
320-
int area = address.Area;
322+
var func = (byte)address.DBNumber;
321323
try
322324
{
323-
byte[] header = area == Modbus.fctReadCoil ? CreateReadHeader(address.Start * 16, (ushort)(16 * size), (byte)area) :
324-
CreateReadHeader(address.Start, size, (byte)area);
325+
byte[] header = func < 3 ? CreateReadHeader(address.Area, address.Start * 16, (ushort)(16 * size), func) :
326+
CreateReadHeader(address.Area, address.Start, size, func);
325327
_serialPort.Write(header, 0, header.Length);
326328
byte[] frameBytes = new byte[size * 2 + 5];
327329
byte[] data = new byte[size * 2];
@@ -330,7 +332,7 @@ public byte[] ReadBytes(DeviceAddress address, ushort size)
330332
{
331333
while (numBytesRead != frameBytes.Length)
332334
numBytesRead += _serialPort.Read(frameBytes, numBytesRead, frameBytes.Length - numBytesRead);
333-
if (frameBytes[0] == _slaveId && Utility.CheckSumCRC(frameBytes))
335+
if (frameBytes[0] == func && Utility.CheckSumCRC(frameBytes))
334336
{
335337
Array.Copy(frameBytes, 3, data, 0, data.Length);
336338
return data;
@@ -348,14 +350,14 @@ public byte[] ReadBytes(DeviceAddress address, ushort size)
348350

349351
public ItemData<int> ReadInt32(DeviceAddress address)
350352
{
351-
byte[] bit = ReadBytes(address, 4);
353+
byte[] bit = ReadBytes(address, 2);
352354
return bit == null ? new ItemData<int>(0, 0, QUALITIES.QUALITY_BAD) :
353355
new ItemData<int>(BitConverter.ToInt32(bit, 0), 0, QUALITIES.QUALITY_GOOD);
354356
}
355357

356358
public ItemData<uint> ReadUInt32(DeviceAddress address)
357359
{
358-
byte[] bit = ReadBytes(address, 4);
360+
byte[] bit = ReadBytes(address, 2);
359361
return bit == null ? new ItemData<uint>(0, 0, QUALITIES.QUALITY_BAD) :
360362
new ItemData<uint>(BitConverter.ToUInt32(bit, 0), 0, QUALITIES.QUALITY_GOOD);
361363
}
@@ -409,7 +411,7 @@ public ItemData<object> ReadValue(DeviceAddress address)
409411

410412
public int WriteBytes(DeviceAddress address, byte[] bit)
411413
{
412-
var data = WriteMultipleRegister(address.Start, bit);
414+
var data = WriteMultipleRegister(address.Area, address.Start, bit);
413415
_serialPort.Write(data, 0, data.Length);
414416
_serialPort.ReadByte();
415417
var chr = _serialPort.ReadByte();
@@ -418,7 +420,7 @@ public int WriteBytes(DeviceAddress address, byte[] bit)
418420

419421
public int WriteBit(DeviceAddress address, bool bit)
420422
{
421-
var data = WriteSingleCoils(address.Start + address.Bit, bit);
423+
var data = WriteSingleCoils(address.Area, address.Start + address.Bit, bit);
422424
_serialPort.Write(data, 0, data.Length);
423425
_serialPort.ReadByte();
424426
var chr = _serialPort.ReadByte();
@@ -427,7 +429,7 @@ public int WriteBit(DeviceAddress address, bool bit)
427429

428430
public int WriteBits(DeviceAddress address, byte bits)
429431
{
430-
var data = WriteSingleRegister(address.Start, new byte[] { bits });
432+
var data = WriteSingleRegister(address.Area, address.Start, new byte[] { bits });
431433
_serialPort.Write(data, 0, data.Length);
432434
_serialPort.ReadByte();
433435
var chr = _serialPort.ReadByte();
@@ -436,23 +438,23 @@ public int WriteBits(DeviceAddress address, byte bits)
436438

437439
public int WriteInt16(DeviceAddress address, short value)
438440
{
439-
var data = WriteSingleRegister(address.Start, BitConverter.GetBytes(value));
441+
var data = WriteSingleRegister(address.Area, address.Start, BitConverter.GetBytes(value));
440442
_serialPort.Write(data, 0, data.Length);
441443
var chr = _serialPort.ReadByte();
442444
return (chr & 0x80) > 0 ? -1 : 0;
443445
}
444446

445447
public int WriteUInt16(DeviceAddress address, ushort value)
446448
{
447-
var data = WriteSingleRegister(address.Start, BitConverter.GetBytes(value));
449+
var data = WriteSingleRegister(address.Area, address.Start, BitConverter.GetBytes(value));
448450
_serialPort.Write(data, 0, data.Length);
449451
var chr = _serialPort.ReadByte();
450452
return (chr & 0x80) > 0 ? -1 : 0;
451453
}
452454

453455
public int WriteUInt32(DeviceAddress address, uint value)
454456
{
455-
var data = WriteMultipleRegister(address.Start, BitConverter.GetBytes(value));
457+
var data = WriteMultipleRegister(address.Area, address.Start, BitConverter.GetBytes(value));
456458
_serialPort.Write(data, 0, data.Length);
457459
_serialPort.ReadByte();
458460
var chr = _serialPort.ReadByte();
@@ -461,7 +463,7 @@ public int WriteUInt32(DeviceAddress address, uint value)
461463

462464
public int WriteInt32(DeviceAddress address, int value)
463465
{
464-
var data = WriteMultipleRegister(address.Start, BitConverter.GetBytes(value));
466+
var data = WriteMultipleRegister(address.Area, address.Start, BitConverter.GetBytes(value));
465467
_serialPort.Write(data, 0, data.Length);
466468
_serialPort.ReadByte();
467469
var chr = _serialPort.ReadByte();
@@ -470,7 +472,7 @@ public int WriteInt32(DeviceAddress address, int value)
470472

471473
public int WriteFloat(DeviceAddress address, float value)
472474
{
473-
var data = WriteMultipleRegister(address.Start, BitConverter.GetBytes(value));
475+
var data = WriteMultipleRegister(address.Area, address.Start, BitConverter.GetBytes(value));
474476
_serialPort.Write(data, 0, data.Length);
475477
_serialPort.ReadByte();
476478
var chr = _serialPort.ReadByte();
@@ -479,11 +481,11 @@ public int WriteFloat(DeviceAddress address, float value)
479481

480482
public int WriteString(DeviceAddress address, string str)
481483
{
482-
var data = WriteMultipleRegister(address.Start, Encoding.ASCII.GetBytes(str));
484+
var data = WriteMultipleRegister(address.Area, address.Start, Encoding.ASCII.GetBytes(str));
483485
_serialPort.Write(data, 0, data.Length);
484486
_serialPort.ReadByte();
485487
var chr = _serialPort.ReadByte();
486-
return chr == _slaveId ? -1 : 0;
488+
return chr == address.DBNumber ? -1 : 0;
487489
}
488490

489491
public int WriteValue(DeviceAddress address, object value)

SCADA/Program/ModbusDriver/ModbusTCPDriver.cs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,14 @@ public DeviceAddress GetDeviceAddress(string address)
3232
DeviceAddress dv = DeviceAddress.Empty;
3333
if (string.IsNullOrEmpty(address))
3434
return dv;
35-
dv.Area = _slaveId;
35+
var sindex = address.IndexOf(':');
36+
if (sindex > 0)
37+
{
38+
int slaveId;
39+
if (int.TryParse(address.Substring(0, sindex), out slaveId))
40+
dv.Area = slaveId;
41+
address = address.Substring(sindex + 1);
42+
}
3643
switch (address[0])
3744
{
3845
case '0':
@@ -145,16 +152,6 @@ public int TimeOut
145152
set { _timeout = value; }
146153
}
147154

148-
byte _slaveId;//设备ID 单元号 字节号
149-
/// <summary>
150-
/// 设备ID 单元号 字节号
151-
/// </summary>
152-
public byte SlaveId
153-
{
154-
get { return _slaveId; }
155-
set { _slaveId = value; }
156-
}
157-
158155
List<IGroup> _grps = new List<IGroup>(20);
159156
public IEnumerable<IGroup> Groups
160157
{
@@ -167,14 +164,13 @@ public IDataServer Parent
167164
get { return _server; }
168165
}
169166

170-
public ModbusTCPReader(IDataServer server, short id, string name, string ip, int timeOut = 500, string spare1 = "0", string spare2 = null)
167+
public ModbusTCPReader(IDataServer server, short id, string name, string ip, int timeOut = 500, string spare1 = null, string spare2 = null)
171168
{
172169
_id = id;
173170
_name = name;
174171
_server = server;
175172
_ip = ip;
176173
_timeout = timeOut;
177-
if (!string.IsNullOrEmpty(spare1)) byte.TryParse(spare1, out _slaveId);
178174
}
179175

180176
public bool Connect()

SCADA/dll/ModbusDriver.dll

-512 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)