2017-05-16 update 1 Add multistation COM support.

This commit is contained in:
parallelbgls
2017-05-16 17:46:03 +08:00
parent 45cccd0ec6
commit 779b7d3fa4
14 changed files with 277 additions and 68 deletions

View File

@@ -15,7 +15,7 @@ namespace Modbus.Net.Modbus
public ModbusAsciiProtocal(string com, byte slaveAddress, byte masterAddress, Endian endian)
: base(slaveAddress, masterAddress, endian)
{
ProtocalLinker = new ModbusAsciiProtocalLinker(com);
ProtocalLinker = new ModbusAsciiProtocalLinker(com, slaveAddress);
}
}
}

View File

@@ -8,7 +8,7 @@ namespace Modbus.Net.Modbus
/// </summary>
public class ModbusAsciiProtocalLinker : ComProtocalLinker
{
public ModbusAsciiProtocalLinker(string com) : base(com, 9600, Parity.None, StopBits.One, 8)
public ModbusAsciiProtocalLinker(string com, int slaveAddress) : base(com, 9600, Parity.None, StopBits.One, 8, slaveAddress)
{
}

View File

@@ -15,7 +15,7 @@ namespace Modbus.Net.Modbus
public ModbusRtuProtocal(string com, byte slaveAddress, byte masterAddress, Endian endian)
: base(slaveAddress, masterAddress, endian)
{
ProtocalLinker = new ModbusRtuProtocalLinker(com);
ProtocalLinker = new ModbusRtuProtocalLinker(com, slaveAddress);
}
}
}

View File

@@ -7,7 +7,7 @@ namespace Modbus.Net.Modbus
/// </summary>
public class ModbusRtuProtocalLinker : ComProtocalLinker
{
public ModbusRtuProtocalLinker(string com) : base(com, 9600, Parity.None, StopBits.One, 8)
public ModbusRtuProtocalLinker(string com, int slaveAddress) : base(com, 9600, Parity.None, StopBits.One, 8, slaveAddress)
{
}

View File

@@ -7,7 +7,7 @@ namespace Modbus.Net.Modbus
/// </summary>
public class ModbusTcpProtocalLinker : TcpProtocalLinker
{
public ModbusTcpProtocalLinker(string ip) : base(ip, int.Parse(ConfigurationManager.AppSettings["ModbusPort"]))
public ModbusTcpProtocalLinker(string ip) : base(ip, int.Parse(ConfigurationManager.AppSettings["ModbusPort"] ?? "502"))
{
}

View File

@@ -47,7 +47,7 @@ namespace Modbus.Net.Siemens
public override async Task<bool> ConnectAsync()
{
ProtocalLinker = new SiemensPpiProtocalLinker(_com);
ProtocalLinker = new SiemensPpiProtocalLinker(_com, SlaveAddress);
var inputStruct = new ComCreateReferenceSiemensInputStruct(SlaveAddress, MasterAddress);
var outputStruct =
await await

View File

@@ -9,8 +9,8 @@ namespace Modbus.Net.Siemens
/// </summary>
public class SiemensPpiProtocalLinker : ComProtocalLinker
{
public SiemensPpiProtocalLinker(string com)
: base(com, 9600, Parity.Even, StopBits.One, 8)
public SiemensPpiProtocalLinker(string com, int slaveAddress)
: base(com, 9600, Parity.Even, StopBits.One, 8, slaveAddress)
{
}

View File

@@ -24,7 +24,7 @@ namespace Modbus.Net.Siemens
}
public SiemensTcpProtocal(byte tdpuSize, ushort tsapSrc, ushort tsapDst, ushort maxCalling, ushort maxCalled,
ushort maxPdu, string ip) : this(tdpuSize, tsapSrc, tsapDst, maxCalling, maxCalled, maxPdu, ip, 0)
ushort maxPdu, string ip) : this(tdpuSize, tsapSrc, tsapDst, maxCalling, maxCalled, maxPdu, ip, int.Parse(ConfigurationManager.AppSettings["SiemensPort"]))
{
}
@@ -85,7 +85,7 @@ namespace Modbus.Net.Siemens
public override async Task<bool> ConnectAsync()
{
_connectTryCount++;
ProtocalLinker = _port == 0 ? new SiemensTcpProtocalLinker(_ip) : new SiemensTcpProtocalLinker(_ip, _port);
ProtocalLinker = new SiemensTcpProtocalLinker(_ip, _port);
if (!await ProtocalLinker.ConnectAsync()) return false;
_connectTryCount = 0;
var inputStruct = new CreateReferenceSiemensInputStruct(_tdpuSize, _taspSrc, _tsapDst);

View File

@@ -9,7 +9,7 @@ namespace Modbus.Net.Siemens
public class SiemensTcpProtocalLinker : TcpProtocalLinker
{
public SiemensTcpProtocalLinker(string ip)
: base(ip, int.Parse(ConfigurationManager.AppSettings["SiemensPort"]))
: this(ip, int.Parse(ConfigurationManager.AppSettings["SiemensPort"] ?? "102"))
{
}

View File

@@ -1,12 +1,19 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Modbus.Net
{
public class SerialPortLock : SerialPort
{
public object Lock { get; set; } = new object();
}
/// <summary>
/// 串口通讯类
/// </summary>
@@ -14,6 +21,9 @@ namespace Modbus.Net
{
public delegate byte[] GetDate(byte[] bts);
private static Dictionary<string, SerialPortLock> Connectors { get; } = new Dictionary<string, SerialPortLock>();
private static Dictionary<string, string> Linkers { get; } = new Dictionary<string, string>();
private readonly int _baudRate;
//private GetDate mygetDate;
@@ -22,19 +32,19 @@ namespace Modbus.Net
private readonly Parity _parity;
private readonly StopBits _stopBits;
private readonly int _timeoutTime;
private readonly string _slave;
private SerialPort _serialPort1;
private bool m_disposed = true;
private bool m_disposed = false;
public ComConnector(string com, int baudRate, Parity parity, StopBits stopBits, int dataBits, int timeoutTime)
{
_com = com;
_com = com.Split(':')[0];
_timeoutTime = timeoutTime;
_baudRate = baudRate;
_parity = parity;
_stopBits = stopBits;
_dataBits = dataBits;
_slave = com.Split(':')[1];
//端口号
//读超时
@@ -42,27 +52,18 @@ namespace Modbus.Net
//奇偶校验
//停止位
//数据位
//从站号标识
}
public override string ConnectionToken => _com;
public override string ConnectionToken => _slave + ":" + _com;
private SerialPort SerialPort1
private SerialPortLock SerialPort
{
get
{
if (_serialPort1 == null)
{
_serialPort1 = new SerialPort
{
PortName = _com,
BaudRate = _baudRate,
Parity = _parity,
StopBits = _stopBits,
DataBits = _dataBits,
ReadTimeout = _timeoutTime
};
}
return _serialPort1;
if (Connectors.ContainsKey(_com))
return Connectors[_com];
return null;
}
}
@@ -71,7 +72,7 @@ namespace Modbus.Net
/// </summary>
public void Dispose()
{
Dispose(true);
Dispose(true);
//.NET Framework 类库
// GC..::.SuppressFinalize 方法
//请求系统不要调用指定对象的终结器。
@@ -93,17 +94,17 @@ namespace Modbus.Net
Array.Clear(readBuf, 0, readBuf.Length);
int nReadLen, nBytelen;
if (SerialPort1.IsOpen == false)
if (SerialPort.IsOpen == false)
return -1;
nBytelen = 0;
SerialPort1.ReadTimeout = HowTime;
SerialPort.ReadTimeout = HowTime;
try
{
while (SerialPort1.BytesToRead > 0)
while (SerialPort.BytesToRead > 0)
{
readBuf[nBytelen] = (byte) SerialPort1.ReadByte();
readBuf[nBytelen] = (byte) SerialPort.ReadByte();
var bTmp = new byte[bufRoom];
Array.Clear(bTmp, 0, bTmp.Length);
@@ -139,16 +140,16 @@ namespace Modbus.Net
sbyte nBytelen;
//long nByteRead;
if (SerialPort1.IsOpen == false)
if (SerialPort.IsOpen == false)
return 0;
nBytelen = 0;
SerialPort1.ReadTimeout = ByteTime;
SerialPort.ReadTimeout = ByteTime;
while (nBytelen < ReadRoom - 1 && SerialPort1.BytesToRead > 0)
while (nBytelen < ReadRoom - 1 && SerialPort.BytesToRead > 0)
{
try
{
ReadBuf[nBytelen] = (byte) SerialPort1.ReadByte();
ReadBuf[nBytelen] = (byte) SerialPort.ReadByte();
nBytelen++; // add one
}
catch (Exception ex)
@@ -251,18 +252,23 @@ namespace Modbus.Net
// Release managed resources
}
// Release unmanaged resources
if (_serialPort1 != null)
if (SerialPort != null)
{
try
if (Linkers.Values.Count(p => p == _com) <= 1)
{
_serialPort1.Close();
try
{
SerialPort.Close();
}
catch (Exception)
{
//ignore
}
SerialPort.Dispose();
Connectors[_com] = null;
Connectors.Remove(_com);
}
catch (Exception)
{
//ignore
}
_serialPort1.Dispose();
_serialPort1 = null;
Linkers.Remove(_slave);
}
m_disposed = true;
}
@@ -283,12 +289,11 @@ namespace Modbus.Net
{
get
{
if (_serialPort1 != null && !SerialPort1.IsOpen)
if (SerialPort != null && !SerialPort.IsOpen)
{
_serialPort1.Dispose();
_serialPort1 = null;
SerialPort.Dispose();
}
return _serialPort1 != null && _serialPort1.IsOpen;
return SerialPort != null && SerialPort.IsOpen && Linkers.ContainsKey(_slave);
}
}
@@ -296,7 +301,23 @@ namespace Modbus.Net
{
try
{
SerialPort1.Open();
if (!Connectors.ContainsKey(_com))
{
Connectors.Add(_com, new SerialPortLock
{
PortName = _com,
BaudRate = _baudRate,
Parity = _parity,
StopBits = _stopBits,
DataBits = _dataBits,
ReadTimeout = _timeoutTime
});
}
if (!Linkers.ContainsKey(_slave))
{
Linkers.Add(_slave, _com);
}
SerialPort.Open();
return true;
}
catch (Exception e)
@@ -312,7 +333,7 @@ namespace Modbus.Net
public override bool Disconnect()
{
if (SerialPort1 != null)
if (Linkers.ContainsKey(_slave) && Connectors.ContainsKey(_com))
{
try
{
@@ -343,19 +364,22 @@ namespace Modbus.Net
{
try
{
if (!SerialPort1.IsOpen)
if (!SerialPort.IsOpen)
{
try
{
SerialPort1.Open();
SerialPort.Open();
}
catch (Exception)
{
Dispose();
SerialPort1.Open();
SerialPort.Open();
}
}
SerialPort1.Write(sendbytes, 0, sendbytes.Length);
lock (SerialPort.Lock)
{
SerialPort.Write(sendbytes, 0, sendbytes.Length);
}
return ReadMsg();
}
catch
@@ -374,7 +398,22 @@ namespace Modbus.Net
{
try
{
SerialPort1.Write(sendbytes, 0, sendbytes.Length);
if (!SerialPort.IsOpen)
{
try
{
SerialPort.Open();
}
catch (Exception)
{
Dispose();
SerialPort.Open();
}
}
lock (SerialPort.Lock)
{
SerialPort.Write(sendbytes, 0, sendbytes.Length);
}
return true;
}
catch (Exception)
@@ -397,9 +436,9 @@ namespace Modbus.Net
{
try
{
if (!SerialPort1.IsOpen)
if (!SerialPort.IsOpen)
{
SerialPort1.Open();
SerialPort.Open();
}
byte[] data;

View File

@@ -15,8 +15,8 @@ namespace Modbus.Net
/// <param name="parity">校验位</param>
/// <param name="stopBits">停止位</param>
/// <param name="dataBits">数据位</param>
protected ComProtocalLinker(int baudRate, Parity parity, StopBits stopBits, int dataBits)
: this(ConfigurationManager.AppSettings["COM"], baudRate, parity, stopBits, dataBits)
protected ComProtocalLinker(int baudRate, Parity parity, StopBits stopBits, int dataBits, int slaveAddress)
: this(ConfigurationManager.AppSettings["COM"], baudRate, parity, stopBits, dataBits, slaveAddress)
{
}
@@ -28,10 +28,27 @@ namespace Modbus.Net
/// <param name="parity">校验位</param>
/// <param name="stopBits">停止位</param>
/// <param name="dataBits">数据位</param>
protected ComProtocalLinker(string com, int baudRate, Parity parity, StopBits stopBits, int dataBits)
protected ComProtocalLinker(string com, int baudRate, Parity parity, StopBits stopBits, int dataBits,
int slaveAddress)
: this(
com, baudRate, parity, stopBits, dataBits,
int.Parse(ConfigurationManager.AppSettings["ComConnectionTimeout"] ?? "3000"), slaveAddress)
{
//初始化连对象
BaseConnector = new ComConnector(com, baudRate, parity, stopBits, dataBits, int.Parse(ConfigurationManager.AppSettings["ComConnectionTimeout"]));
}
/// <summary>
/// 构造器
/// </summary>
/// <param name="com">串口端口号</param>
/// <param name="baudRate">波特率</param>
/// <param name="parity">校验位</param>
/// <param name="stopBits">停止位</param>
/// <param name="dataBits">数据位</param>
/// <param name="connectionTimeout">超时时间</param>
protected ComProtocalLinker(string com, int baudRate, Parity parity, StopBits stopBits, int dataBits,
int connectionTimeout, int slaveAddress)
{
BaseConnector = new ComConnector(com + ":" + slaveAddress, baudRate, parity, stopBits, dataBits, connectionTimeout);
}
}
}

View File

@@ -12,7 +12,8 @@ namespace Modbus.Net
/// <summary>
/// 构造器
/// </summary>
protected TcpProtocalLinker() : this(ConfigurationManager.AppSettings["IP"], int.Parse(ConfigurationManager.AppSettings["ModbusPort"]))
protected TcpProtocalLinker(int port)
: this(ConfigurationManager.AppSettings["IP"], port)
{
}
@@ -22,9 +23,20 @@ namespace Modbus.Net
/// <param name="ip">Ip地址</param>
/// <param name="port">端口</param>
protected TcpProtocalLinker(string ip, int port)
: this(ip, port, int.Parse(ConfigurationManager.AppSettings["IPConnectionTimeout"] ?? "5000"))
{
}
/// <summary>
/// 构造器
/// </summary>
/// <param name="ip">Ip地址</param>
/// <param name="port">端口</param>
/// <param name="connectionTimeout">超时时间</param>
protected TcpProtocalLinker(string ip, int port, int connectionTimeout)
{
//初始化连接对象
BaseConnector = new TcpConnector(ip, port, int.Parse(ConfigurationManager.AppSettings["IPConnectionTimeout"]));
BaseConnector = new TcpConnector(ip, port, connectionTimeout);
}
}
}