2014-10-16 update 1

This commit is contained in:
parallelbgls@outlook.com
2014-10-16 16:38:21 +08:00
parent 4ae44b89e2
commit 3f4fe27a5e
31 changed files with 1072 additions and 177 deletions

View File

@@ -12,16 +12,22 @@ namespace CrossLampControl.WebApi.Controllers
{
public class CrossLampController : ApiController
{
ModbusUtility _utility = new ModbusUtility((int)ModbusType.Rtu, "COM3");
BaseUtility _utility;
public CrossLampController()
{
_utility = new SimenseUtility(SimenseType.Tcp, "192.168.3.241,200");
_utility.AddressTranslator = new AddressTranslatorSimense();
}
[HttpGet]
public Lamp GetLamp()
{
Lamp light = new Lamp();
byte[] lampsbyte = _utility.GetDatas(2, ((byte)ModbusProtocalReadDataFunctionCode.ReadCoilStatus).ToString()+":0", 6);
object[] lampsbyte = _utility.GetDatas(2, 0, "Q0", new KeyValuePair<Type, int>(typeof(bool), 7));
bool[] lamps =
ValueHelper.Instance.ObjectArrayToDestinationArray<bool>(
ValueHelper.Instance.ByteArrayToObjectArray(lampsbyte,
new KeyValuePair<Type, int>(typeof (bool), 7)));
lampsbyte);
if (lamps[0])
{
light.MainLamp = LightLamp.Green.ToString();

View File

@@ -9,6 +9,12 @@ namespace ModBus.Net
/// </summary>
public abstract class AddressTranslator
{
/// <summary>
/// 地址转换
/// </summary>
/// <param name="address">地址前地址</param>
/// <param name="isRead">是否为读取,是为读取,否为写入</param>
/// <returns>Key为转换后的地址Value为辅助码</returns>
public abstract KeyValuePair<int,int> AddressTranslate(string address, bool isRead);
}
@@ -97,4 +103,54 @@ namespace ModBus.Net
throw new FormatException();
}
}
public class AddressTranslatorSimense : AddressTranslator
{
protected Dictionary<string, int> AreaCodeDictionary;
public AddressTranslatorSimense()
{
AreaCodeDictionary = new Dictionary<string, int>
{
{"S", 0x04},
{"SM", 0x05},
{"AI", 0x06},
{"AQ", 0x07},
{"C", 0x1E},
{"T", 0x1F},
{"HC", 0x20},
{"I", 0x81},
{"Q", 0x82},
{"M", 0x83},
{"DB", 0x84},
{"V", 0x184},
};
}
public override KeyValuePair<int, int> AddressTranslate(string address, bool isRead)
{
address = address.ToUpper();
if (address.Substring(0,2) == "DB")
{
var addressSplit = address.Split('.');
if (addressSplit.Length != 2) throw new FormatException();
addressSplit[0] = addressSplit[0].Substring(2);
if (addressSplit[1].Substring(0, 2) == "DB")
addressSplit[1] = addressSplit[1].Substring(2);
return new KeyValuePair<int, int>(int.Parse(addressSplit[1]), int.Parse(addressSplit[0]) * 256 + AreaCodeDictionary["DB"]);
}
int i = 0;
int t;
while (!int.TryParse(address[i].ToString(), out t) && i < address.Length)
{
i++;
}
if (i == 0 || i >= address.Length) throw new FormatException();
string head = address.Substring(0, i);
string tail = address.Substring(i);
return
new KeyValuePair<int, int>(int.Parse(tail),
AreaCodeDictionary[head]);
}
}
}

View File

@@ -8,6 +8,7 @@ namespace ModBus.Net
{
public abstract class BaseConnector
{
public abstract bool IsConnected { get; }
/// <summary>
/// 连接PLC
/// </summary>

View File

@@ -14,7 +14,7 @@ namespace ModBus.Net
/// </summary>
/// <param name="content">需要发送的数据</param>
/// <returns>数据是否正确接收</returns>
protected ProtocalLinker _protocalLinker;
public ProtocalLinker ProtocalLinker { get; protected set; }
protected BaseProtocal()
{
@@ -26,17 +26,18 @@ namespace ModBus.Net
/// </summary>
/// <param name="protocalName">协议的类的名称</param>
/// <returns></returns>
public ProtocalUnit this[string protocalName]
public ProtocalUnit this[Type type]
{
get
{
string protocalName = type.FullName;
if (Protocals.ContainsKey(protocalName))
{
return Protocals[protocalName];
}
//自动寻找存在的协议并将其加载
var protocalUnit =
Assembly.Load("ModBus.Net").CreateInstance("ModBus.Net." + protocalName) as ProtocalUnit;
Assembly.Load("ModBus.Net").CreateInstance(protocalName) as ProtocalUnit;
if (protocalUnit == null) throw new InvalidCastException("没有相应的协议内容");
Register(protocalUnit);
return Protocals[protocalName];
@@ -48,7 +49,7 @@ namespace ModBus.Net
protected void Register(ProtocalUnit linkProtocal)
{
if (linkProtocal == null) return;
Protocals.Add(linkProtocal.GetType().Name, linkProtocal);
Protocals.Add(linkProtocal.GetType().FullName, linkProtocal);
}
/// <summary>
@@ -58,8 +59,7 @@ namespace ModBus.Net
/// <returns></returns>
public virtual byte[] SendReceive(params object[] content)
{
int t;
return _protocalLinker.SendReceive(ProtocalUnit.TranslateContent(content));
return ProtocalLinker.SendReceive(ProtocalUnit.TranslateContent(content));
}
/// <summary>
@@ -71,29 +71,16 @@ namespace ModBus.Net
public virtual OutputStruct SendReceive(ProtocalUnit unit, InputStruct content)
{
int t = 0;
return unit.Unformat(_protocalLinker.SendReceive(unit.Format(content)), ref t);
//如果为特别处理协议的话,跳过协议扩展收缩
if (unit is SpecialProtocalUnit)
{
return unit.Unformat(ProtocalLinker.SendReceiveWithoutExtAndDec(unit.Format(content)), ref t);
}
else
{
return unit.Unformat(ProtocalLinker.SendReceive(unit.Format(content)), ref t);
}
}
/// <summary>
/// 仅发送数据
/// </summary>
/// <param name="unit"></param>
/// <param name="content"></param>
/// <returns></returns>
public virtual bool SendOnly(ProtocalUnit unit, params object[] content)
{
return _protocalLinker.SendOnly(unit.Format(content));
}
/// <summary>
/// 仅发送数据
/// </summary>
/// <param name="unit"></param>
/// <param name="content"></param>
/// <returns></returns>
public virtual bool SendOnly(ProtocalUnit unit, InputStruct content)
{
return _protocalLinker.SendOnly(unit.Format(content));
}
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
@@ -12,6 +13,7 @@ namespace ModBus.Net
/// 协议收发主体
/// </summary>
protected BaseProtocal Wrapper;
public virtual string ConnectionString { get; set; }
public AddressTranslator AddressTranslator { get; set; }
@@ -20,11 +22,6 @@ namespace ModBus.Net
AddressTranslator = new AddressTranslatorBase();
}
/// <summary>
/// 设置连接字符串
/// </summary>
/// <param name="connectionString">连接字符串</param>
public abstract void SetConnectionString(string connectionString);
/// <summary>
/// 设置连接类型
/// </summary>
/// <param name="connectionType">连接类型</param>
@@ -33,18 +30,43 @@ namespace ModBus.Net
/// 获取数据
/// </summary>
/// <param name="belongAddress">从站地址</param>
/// <param name="masterAddress">主站地址</param>
/// <param name="startAddress">开始地址</param>
/// <param name="getCount">接收个数</param>
/// <param name="getByteCount">获取类型和个数</param>
/// <returns>接收到的byte数据</returns>
public abstract byte[] GetDatas(byte belongAddress, string startAddress, int getCount);
protected abstract byte[] GetDatas(byte belongAddress, byte masterAddress, string startAddress, int getByteCount);
public virtual object[] GetDatas(byte belongAddress, byte masterAddress, string startAddress,
KeyValuePair<Type, int> getTypeAndCount)
{
string typeName = getTypeAndCount.Key.FullName;
double bCount = ValueHelper.Instance.ByteLength[typeName];
byte[] getBytes = GetDatas(belongAddress, masterAddress, startAddress, (int)Math.Ceiling(bCount * getTypeAndCount.Value));
return ValueHelper.Instance.ByteArrayToObjectArray(getBytes, getTypeAndCount);
}
public virtual object[] GetDatas(byte belongAddress, byte masterAddress, string startAddress,
IEnumerable<KeyValuePair<Type, int>> getTypeAndCountList)
{
int bAllCount = 0;
foreach (var getTypeAndCount in getTypeAndCountList)
{
string typeName = getTypeAndCount.Key.FullName;
double bCount = ValueHelper.Instance.ByteLength[typeName];
bAllCount += (int)Math.Ceiling(bCount*getTypeAndCount.Value);
}
byte[] getBytes = GetDatas(belongAddress, masterAddress, startAddress, bAllCount);
return ValueHelper.Instance.ByteArrayToObjectArray(getBytes, getTypeAndCountList);
}
/// <summary>
/// 设置数据
/// </summary>
/// <param name="belongAddress">从站地址</param>
/// <param name="masterAddress">主站地址</param>
/// <param name="startAddress">开始地址</param>
/// <param name="setContents">设置数据</param>
/// <returns>是否设置成功</returns>
public abstract bool SetDatas(byte belongAddress, string startAddress, object[] setContents);
public abstract bool SetDatas(byte belongAddress, byte masterAddress, string startAddress, object[] setContents);
/// <summary>
/// 获取PLC时间

View File

@@ -30,6 +30,11 @@ namespace ModBus.Net
#region
public override bool IsConnected
{
get { return serialPort1 != null && serialPort1.IsOpen; }
}
public override bool Connect()
{
if (serialPort1 != null)

View File

@@ -8,14 +8,14 @@ namespace ModBus.Net
{
public abstract class ComProtocalLinker : ProtocalLinker
{
protected ComProtocalLinker()
protected ComProtocalLinker() : this(ConfigurationManager.COM)
{
//初始化连对象
_baseConnector = new ComConnector(ConfigurationManager.COM);
}
protected ComProtocalLinker(string com)
{
//初始化连对象
_baseConnector = new ComConnector(com);
}
}

View File

@@ -77,5 +77,14 @@ namespace ModBus.Net {
return ResourceManager.GetString("IP", resourceCulture);
}
}
/// <summary>
/// 查找类似 502 的本地化字符串。
/// </summary>
internal static string Port {
get {
return ResourceManager.GetString("Port", resourceCulture);
}
}
}
}

View File

@@ -123,4 +123,7 @@
<data name="IP" xml:space="preserve">
<value>192.168.3.247</value>
</data>
<data name="Port" xml:space="preserve">
<value>502</value>
</data>
</root>

View File

@@ -65,6 +65,11 @@
<Compile Include="ModbusProtocal.cs" />
<Compile Include="ModbusTcpProtocal.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SimenseProtocal.cs" />
<Compile Include="SimenseTcpProtocal.cs" />
<Compile Include="SimenseProtocalLinkerBytesExtend.cs" />
<Compile Include="SimenseTcpProtocalLinker.cs" />
<Compile Include="SimenseUtility.cs" />
<Compile Include="TcpConnector.cs">
<SubType>Code</SubType>
</Compile>

View File

@@ -11,7 +11,7 @@ internal enum ModbusProtocalVariableFunctionCode : byte
/// <summary>
/// 跟时间有关的功能码
/// </summary>
internal enum ModbusProtocalTimeFunctionCode : byte
public enum ModbusProtocalTimeFunctionCode : byte
{
GetSystemTime = 3,
SetSystemTime = 16,
@@ -31,7 +31,7 @@ public enum ModbusProtocalReadDataFunctionCode : byte
/// <summary>
/// 跟写数据有关的功能码
/// </summary>
public enum ModbusProtocalWriteDataFunctionCode : byte
internal enum ModbusProtocalWriteDataFunctionCode : byte
{
WriteMultiCoil = 15,
WriteMultiRegister = 16,
@@ -45,9 +45,9 @@ namespace ModBus.Net
}
#region PLC数据
public class ReadDataInputStruct : InputStruct
public class ReadDataModbusInputStruct : InputStruct
{
public ReadDataInputStruct(byte belongAddress, string startAddress, ushort getCount, AddressTranslator addressTranslator)
public ReadDataModbusInputStruct(byte belongAddress, string startAddress, ushort getCount, AddressTranslator addressTranslator)
{
BelongAddress = belongAddress;
KeyValuePair<int, int> translateAddress = addressTranslator.AddressTranslate(startAddress, true);
@@ -65,9 +65,9 @@ namespace ModBus.Net
public ushort GetCount { get; private set; }
}
public class ReadDataOutputStruct : OutputStruct
public class ReadDataModbusOutputStruct : OutputStruct
{
public ReadDataOutputStruct(byte belongAddress, byte functionCode,
public ReadDataModbusOutputStruct(byte belongAddress, byte functionCode,
int dataCount, byte[] dataValue)
{
BelongAddress = belongAddress;
@@ -89,7 +89,7 @@ namespace ModBus.Net
{
public override byte[] Format(InputStruct message)
{
var r_message = (ReadDataInputStruct)message;
var r_message = (ReadDataModbusInputStruct)message;
return Format(r_message.BelongAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.GetCount);
}
@@ -101,16 +101,16 @@ namespace ModBus.Net
byte dataCount = ValueHelper.Instance.GetByte(messageBytes, ref pos);
byte[] dataValue = new byte[dataCount];
Array.Copy(messageBytes, 3, dataValue, 0, dataCount);
return new ReadDataOutputStruct(belongAddress, functionCode, dataCount, dataValue);
return new ReadDataModbusOutputStruct(belongAddress, functionCode, dataCount, dataValue);
}
}
#endregion
#region PLC数据
public class WriteDataInputStruct : InputStruct
public class WriteDataModbusInputStruct : InputStruct
{
public WriteDataInputStruct(byte belongAddress, string startAddress, object[] writeValue, AddressTranslator addressTranslator)
public WriteDataModbusInputStruct(byte belongAddress, string startAddress, object[] writeValue, AddressTranslator addressTranslator)
{
BelongAddress = belongAddress;
KeyValuePair<int, int> translateAddress = addressTranslator.AddressTranslate(startAddress, false);
@@ -118,7 +118,7 @@ namespace ModBus.Net
StartAddress = (ushort)translateAddress.Key;
WriteCount = (ushort)writeValue.Length;
WriteByteCount = 0;
WriteValue = writeValue.Clone() as object[];
WriteValue = writeValue;
}
public byte BelongAddress { get; private set; }
@@ -134,9 +134,9 @@ namespace ModBus.Net
public object[] WriteValue { get; private set; }
}
public class WriteDataOutputStruct : OutputStruct
public class WriteDataModbusOutputStruct : OutputStruct
{
public WriteDataOutputStruct(byte belongAddress, byte functionCode,
public WriteDataModbusOutputStruct(byte belongAddress, byte functionCode,
ushort startAddress, ushort writeCount)
{
BelongAddress = belongAddress;
@@ -161,7 +161,7 @@ namespace ModBus.Net
{
public override byte[] Format(InputStruct message)
{
var r_message = (WriteDataInputStruct)message;
var r_message = (WriteDataModbusInputStruct)message;
byte[] formattingBytes = Format(r_message.BelongAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.WriteCount, r_message.WriteByteCount, r_message.WriteValue);
formattingBytes[6] = (byte)(formattingBytes.Length - 7);
@@ -174,7 +174,7 @@ namespace ModBus.Net
byte functionCode = ValueHelper.Instance.GetByte(messageBytes, ref flag);
ushort startAddress = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
ushort writeCount = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
return new WriteDataOutputStruct(belongAddress, functionCode, startAddress,
return new WriteDataModbusOutputStruct(belongAddress, functionCode, startAddress,
writeCount);
}
}
@@ -182,9 +182,9 @@ namespace ModBus.Net
#endregion
#region PLC时间
public class GetSystemTimeInputStruct : InputStruct
public class GetSystemTimeModbusInputStruct : InputStruct
{
public GetSystemTimeInputStruct(byte belongAddress)
public GetSystemTimeModbusInputStruct(byte belongAddress)
{
BelongAddress = belongAddress;
FunctionCode = (byte)ModbusProtocalTimeFunctionCode.GetSystemTime;
@@ -201,9 +201,9 @@ namespace ModBus.Net
public ushort GetCount { get; private set; }
}
public class GetSystemTimeOutputStruct : OutputStruct
public class GetSystemTimeModbusOutputStruct : OutputStruct
{
public GetSystemTimeOutputStruct(byte belongAddress, byte functionCode,
public GetSystemTimeModbusOutputStruct(byte belongAddress, byte functionCode,
byte writeByteCount, ushort year, byte day, byte month, ushort hour, byte second, byte minute,
ushort millisecond)
{
@@ -229,7 +229,7 @@ namespace ModBus.Net
{
public override byte[] Format(InputStruct message)
{
var r_message = (GetSystemTimeInputStruct)message;
var r_message = (GetSystemTimeModbusInputStruct)message;
return Format(r_message.BelongAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.GetCount);
}
@@ -246,7 +246,7 @@ namespace ModBus.Net
byte second = ValueHelper.Instance.GetByte(messageBytes, ref flag);
byte minute = ValueHelper.Instance.GetByte(messageBytes, ref flag);
ushort millisecond = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
return new GetSystemTimeOutputStruct(belongAddress, functionCode, writeByteCount, year, day,
return new GetSystemTimeModbusOutputStruct(belongAddress, functionCode, writeByteCount, year, day,
month, hour, second, minute, millisecond);
}
}
@@ -254,9 +254,9 @@ namespace ModBus.Net
#endregion
#region PLC时间
public class SetSystemTimeInputStruct : InputStruct
public class SetSystemTimeModbusInputStruct : InputStruct
{
public SetSystemTimeInputStruct(byte belongAddress, DateTime time)
public SetSystemTimeModbusInputStruct(byte belongAddress, DateTime time)
{
BelongAddress = belongAddress;
FunctionCode = (byte)ModbusProtocalTimeFunctionCode.SetSystemTime;
@@ -297,9 +297,9 @@ namespace ModBus.Net
public ushort Millisecond { get; private set; }
}
public class SetSystemTimeOutputStruct : OutputStruct
public class SetSystemTimeModbusOutputStruct : OutputStruct
{
public SetSystemTimeOutputStruct(byte belongAddress, byte functionCode,
public SetSystemTimeModbusOutputStruct(byte belongAddress, byte functionCode,
ushort startAddress, ushort writeCount)
{
BelongAddress = belongAddress;
@@ -324,7 +324,7 @@ namespace ModBus.Net
{
public override byte[] Format(InputStruct message)
{
var r_message = (SetSystemTimeInputStruct)message;
var r_message = (SetSystemTimeModbusInputStruct)message;
return Format(r_message.BelongAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.WriteCount, r_message.WriteByteCount, r_message.Year,
r_message.Day,
@@ -337,7 +337,7 @@ namespace ModBus.Net
byte functionCode = ValueHelper.Instance.GetByte(messageBytes, ref flag);
ushort startAddress = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
ushort writeCount = ValueHelper.Instance.GetUShort(messageBytes, ref flag);
return new SetSystemTimeOutputStruct(belongAddress, functionCode, startAddress, writeCount);
return new SetSystemTimeModbusOutputStruct(belongAddress, functionCode, startAddress, writeCount);
}
}
#endregion

View File

@@ -11,14 +11,13 @@ namespace ModBus.Net
/// </summary>
public class ModbusRtuProtocal : ModbusProtocal
{
public ModbusRtuProtocal()
public ModbusRtuProtocal() : this(ConfigurationManager.COM)
{
_protocalLinker = new ModbusRtuProtocalLinker();
}
public ModbusRtuProtocal(string com)
{
_protocalLinker = new ModbusRtuProtocalLinker(com);
ProtocalLinker = new ModbusRtuProtocalLinker(com);
}
}
}

View File

@@ -23,11 +23,6 @@ namespace ModBus.Net
return true;
}
public ModbusRtuProtocalLinker() : this(ConfigurationManager.COM)
{
}
public ModbusRtuProtocalLinker(string com) : base(com)
{

View File

@@ -7,14 +7,13 @@ namespace ModBus.Net
/// </summary>
public class ModbusTcpProtocal : ModbusProtocal
{
public ModbusTcpProtocal()
public ModbusTcpProtocal() : this(ConfigurationManager.IP)
{
_protocalLinker = new ModbusTcpProtocalLinker();
}
public ModbusTcpProtocal(string ip)
{
_protocalLinker = new ModbusTcpProtocalLinker(ip);
ProtocalLinker = new ModbusTcpProtocalLinker(ip);
}
}
}

View File

@@ -23,12 +23,7 @@ namespace ModBus.Net
return true;
}
public ModbusTcpProtocalLinker() : this(ConfigurationManager.IP)
{
}
public ModbusTcpProtocalLinker(string ip) : base(ip)
public ModbusTcpProtocalLinker(string ip) : base(ip, 102)
{
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Forms;
/// <summary>
@@ -21,8 +22,6 @@ namespace ModBus.Net
{
public class ModbusUtility : BaseUtility
{
protected string ConnectionString { get; set; }
private ModbusType _modbusType;
public ModbusType ModbusType
@@ -56,15 +55,10 @@ namespace ModBus.Net
ModbusType = (ModbusType)connectionType;
}
public ModbusUtility(int connectionType, string connectionString)
{
ConnectionString = connectionString;
ModbusType = (ModbusType)connectionType;
}
public override void SetConnectionString(string connectionString)
public ModbusUtility(ModbusType connectionType, string connectionString)
{
ConnectionString = connectionString;
ModbusType = connectionType;
}
public override void SetConnectionType(int connectionType)
@@ -72,13 +66,13 @@ namespace ModBus.Net
ModbusType = (ModbusType) connectionType;
}
public override byte[] GetDatas(byte belongAddress, string startAddress, int getCount)
protected override byte[] GetDatas(byte belongAddress, byte materAddress, string startAddress, int getByteCount)
{
try
{
var inputStruct = new ReadDataInputStruct(belongAddress, startAddress, getCount % 2 == 0 ? (ushort)(getCount / 2) : (ushort)(getCount / 2 + 1), AddressTranslator);
var inputStruct = new ReadDataModbusInputStruct(belongAddress, startAddress, getByteCount % 2 == 0 ? (ushort)(getByteCount / 2) : (ushort)(getByteCount / 2 + 1), AddressTranslator);
var outputStruct =
Wrapper.SendReceive(Wrapper["ReadDataModbusProtocal"], inputStruct) as ReadDataOutputStruct;
Wrapper.SendReceive(Wrapper[typeof(ReadDataModbusProtocal)], inputStruct) as ReadDataModbusOutputStruct;
return outputStruct.DataValue;
}
catch
@@ -87,14 +81,14 @@ namespace ModBus.Net
}
}
public override bool SetDatas(byte belongAddress, string startAddress, object[] setContents)
public override bool SetDatas(byte belongAddress, byte materAddress, string startAddress, object[] setContents)
{
try
{
var inputStruct = new WriteDataInputStruct(belongAddress, startAddress, setContents, AddressTranslator);
var inputStruct = new WriteDataModbusInputStruct(belongAddress, startAddress, setContents, AddressTranslator);
var outputStruct =
Wrapper.SendReceive(Wrapper["WriteDataModbusProtocal"], inputStruct) as
WriteDataOutputStruct;
Wrapper.SendReceive(Wrapper[typeof(WriteDataModbusProtocal)], inputStruct) as
WriteDataModbusOutputStruct;
if (outputStruct.WriteCount != setContents.Length) return false;
return true;
}
@@ -108,10 +102,10 @@ namespace ModBus.Net
{
try
{
var inputStruct = new GetSystemTimeInputStruct(belongAddress);
var inputStruct = new GetSystemTimeModbusInputStruct(belongAddress);
var outputStruct =
Wrapper.SendReceive(Wrapper["GetSystemTimeModbusProtocal"], inputStruct) as
GetSystemTimeOutputStruct;
Wrapper.SendReceive(Wrapper[typeof(GetSystemTimeModbusProtocal)], inputStruct) as
GetSystemTimeModbusOutputStruct;
return outputStruct.Time;
}
catch (Exception)
@@ -124,10 +118,10 @@ namespace ModBus.Net
{
try
{
var inputStruct = new SetSystemTimeInputStruct(belongAddress, setTime);
var inputStruct = new SetSystemTimeModbusInputStruct(belongAddress, setTime);
var outputStruct =
Wrapper.SendReceive(Wrapper["SetSystemTimeModbusProtocal"], inputStruct) as
SetSystemTimeOutputStruct;
Wrapper.SendReceive(Wrapper[typeof(SetSystemTimeModbusProtocal)], inputStruct) as
SetSystemTimeModbusOutputStruct;
return outputStruct.WriteCount > 0;
}
catch (Exception)

View File

@@ -35,5 +35,5 @@ using System.Runtime.InteropServices;
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.1.0.1008")]
[assembly: AssemblyFileVersion("0.1.0.1008")]
[assembly: AssemblyVersion("0.2.0.1016")]
[assembly: AssemblyFileVersion("0.2.0.1016")]

View File

@@ -9,6 +9,10 @@ namespace ModBus.Net
{
protected BaseConnector _baseConnector;
public bool IsConnected
{
get { return _baseConnector.IsConnected; }
}
/// <summary>
/// 发送并接收数据
/// </summary>
@@ -16,22 +20,24 @@ namespace ModBus.Net
/// <returns>接收协议的内容</returns>
public virtual byte[] SendReceive(byte[] content)
{
//接收数据
byte[] receiveBytes = _baseConnector.SendMsg(BytesExtend(content));
//容错处理
if (!CheckRight(receiveBytes)) return null;
//返回数据
return BytesDecact(receiveBytes);
byte[] extBytes = BytesExtend(content);
byte[] receiveBytes = SendReceiveWithoutExtAndDec(extBytes);
return receiveBytes == null ? null : BytesDecact(receiveBytes);
}
/// <summary>
/// 发送数据
/// 发送并接收数据,不进行协议扩展和收缩,用于特殊协议
/// </summary>
/// <param name="content">发送协议的内容</param>
/// <returns>协议是否正确发送</returns>
public virtual bool SendOnly(byte[] content)
/// <returns>接收协议的内容</returns>
public virtual byte[] SendReceiveWithoutExtAndDec(byte[] content)
{
return _baseConnector.SendMsgWithoutReturn(BytesExtend(content));
//发送数据
byte[] receiveBytes = _baseConnector.SendMsg(content);
//容错处理
if (!CheckRight(receiveBytes)) return null;
//返回字符
return receiveBytes;
}
/// <summary>

View File

@@ -7,14 +7,6 @@ namespace ModBus.Net
{
public abstract class ProtocalUnit : IProtocalFormatting
{
//protected static AddressTranslator _addressTranslator = new AddressTranslatorBase();
public ProtocalUnit SetAddressTranslator(/*AddressTranslator addressTranslator*/)
{
//_addressTranslator = addressTranslator;
return this;
}
/// <summary>
/// 格式化,将输入结构转换为字节数组
/// </summary>
@@ -51,6 +43,11 @@ namespace ModBus.Net
}
}
public abstract class SpecialProtocalUnit : ProtocalUnit
{
}
/// <summary>
/// 输入结构
/// </summary>

View File

@@ -0,0 +1,519 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Windows.Forms;
public enum SimenseTypeCode : byte
{
Bool = 0x01,
Byte = 0x02,
Word = 0x03,
DWord = 0x04,
C = 0x1E,
T = 0x1F,
HC = 0x20,
};
public enum SimenseAccessResult : byte
{
NoError = 0xFF,
HardwareFault = 0x01,
IllegalObjectAccess = 0x03,
InvalidAddress = 0x05,
DataTypeNotSupport = 0x06,
ObjNotExistOrLengthError = 0x0A,
};
public enum SimenseDataType : byte
{
Error = 0x00,
BitAccess = 0x03,
OtherAccess = 0x04
};
namespace ModBus.Net
{
public abstract class SimenseProtocal : BaseProtocal
{
}
internal class CreateReferenceSimenseInputStruct : InputStruct
{
public CreateReferenceSimenseInputStruct(byte tdpuSize, ushort srcTsap, ushort dstTsap)
{
TdpuSize = tdpuSize;
TsapSrc = srcTsap;
TsapDst = dstTsap;
}
public byte TdpuSize;
public ushort TsapSrc;
public ushort TsapDst;
}
internal class CreateReferenceSimenseOutputStruct : OutputStruct
{
public CreateReferenceSimenseOutputStruct(byte tdpuSize, ushort srcTsap, ushort dstTsap)
{
TdpuSize = tdpuSize;
TsapSrc = srcTsap;
TsapDst = dstTsap;
}
public byte TdpuSize { get; private set; }
public ushort TsapSrc { get; private set; }
public ushort TsapDst { get; private set; }
}
internal class CreateReferenceSimenseProtocal : SpecialProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (CreateReferenceSimenseInputStruct)message;
const ushort head = 0x0300;
const ushort len = 0x0016;
const byte contentLen = 0x11;
const byte typeCode = 0xe0;
const ushort dstRef = 0x0000;
const ushort srcRef = 0x000c;
const byte reserved = 0x00;
const ushort tdpuSizeCode = 0xc001;
byte tdpuSizeContent = r_message.TdpuSize;
const ushort srcTsapCode = 0xc102;
ushort srcTsapContent = r_message.TsapSrc;
const ushort dstTsapCode = 0xc202;
ushort dstTsapContent = r_message.TsapDst;
return Format(head, len, contentLen, typeCode, dstRef, srcRef, reserved, tdpuSizeCode, tdpuSizeContent,
srcTsapCode, srcTsapContent, dstTsapCode, dstTsapContent);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
{
pos = 11;
byte tdpuSize = 0;
ushort srcTsap = 0, dstTsap = 0;
switch (messageBytes[pos])
{
case 0xc0:
{
pos += 2;
tdpuSize = ValueHelper.Instance.GetByte(messageBytes, ref pos);
break;
}
case 0xc1:
{
pos += 2;
srcTsap = ValueHelper.Instance.GetUShort(messageBytes, ref pos);
break;
}
case 0xc2:
{
pos += 2;
dstTsap = ValueHelper.Instance.GetUShort(messageBytes, ref pos);
break;
}
}
return new CreateReferenceSimenseOutputStruct(tdpuSize, srcTsap, dstTsap);
}
}
internal class EstablishAssociationSimenseInputStruct : InputStruct
{
public EstablishAssociationSimenseInputStruct(ushort pduRef, ushort maxCalling, ushort maxCalled, ushort maxPdu)
{
PduRef = pduRef;
MaxCalling = maxCalling;
MaxCalled = maxCalled;
MaxPdu = maxPdu;
}
public ushort PduRef { get; private set; }
public ushort MaxCalling { get; private set; }
public ushort MaxCalled { get; private set; }
public ushort MaxPdu { get; private set; }
}
internal class EstablishAssociationSimenseOutputStruct : OutputStruct
{
public EstablishAssociationSimenseOutputStruct(ushort pduRef, ushort maxCalling, ushort maxCalled, ushort maxPdu)
{
PduRef = pduRef;
MaxCalling = maxCalling;
MaxCalled = maxCalled;
MaxPdu = maxPdu;
}
public ushort PduRef { get; private set; }
public ushort MaxCalling { get; private set; }
public ushort MaxCalled { get; private set; }
public ushort MaxPdu { get; private set; }
}
internal class EstablishAssociationSimenseProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (EstablishAssociationSimenseInputStruct) message;
const byte protoId = 0x32;
const byte rosctr = 0x01;
const ushort redId = 0x0000;
ushort pduRef = r_message.PduRef;
const ushort parLg = 0x0008;
const ushort datLg = 0x0000;
const byte serviceId = 0xf0;
const byte reserved = 0x00;
ushort maxCalling = r_message.MaxCalling;
ushort maxCalled = r_message.MaxCalled;
ushort maxPdu = r_message.MaxPdu;
return Format(new byte[7], protoId, rosctr, redId, pduRef, parLg, datLg, serviceId, reserved, maxCalling,
maxCalled, maxPdu);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
{
pos = 4;
ushort pduRef = ValueHelper.Instance.GetUShort(messageBytes, ref pos);
pos = 14;
ushort maxCalling = ValueHelper.Instance.GetUShort(messageBytes, ref pos);
ushort maxCalled = ValueHelper.Instance.GetUShort(messageBytes, ref pos);
ushort maxPdu = ValueHelper.Instance.GetUShort(messageBytes, ref pos);
return new EstablishAssociationSimenseOutputStruct(pduRef,maxCalling,maxCalled,maxPdu);
}
}
public class ReadRequestSimenseInputStruct : InputStruct
{
public ReadRequestSimenseInputStruct(ushort pduRef, SimenseTypeCode getType, string startAddress, ushort getCount, AddressTranslator addressTranslator)
{
PduRef = pduRef;
TypeCode = (byte) getType;
var address = addressTranslator.AddressTranslate(startAddress, true);
Offset = address.Key;
int area = address.Value;
Area = (byte)(area%256);
DbBlock = Area == 0x84 ? (ushort)(area/256) : (ushort)0;
NumberOfElements = getCount;
}
public ushort PduRef { get; private set; }
public byte TypeCode { get; private set; }
public ushort NumberOfElements { get; private set; }
public ushort DbBlock { get; private set; }
public byte Area { get; private set; }
public int Offset { get; private set; }
}
public class ReadRequestSimenseOutputStruct : OutputStruct
{
public ReadRequestSimenseOutputStruct(ushort pduRef, SimenseAccessResult accessResult, SimenseDataType dataType, ushort getLength, byte[] value)
{
PduRef = pduRef;
AccessResult = accessResult;
DataType = dataType;
GetLength = getLength;
GetValue = value;
}
public ushort PduRef { get; private set; }
public SimenseAccessResult AccessResult { get; private set; }
public SimenseDataType DataType { get; private set; }
public ushort GetLength { get; private set; }
public byte[] GetValue { get; private set; }
}
public class ReadRequestSimenseProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (ReadRequestSimenseInputStruct) message;
const byte protoId = 0x32;
const byte rosctr = 0x01;
const ushort redId = 0x0000;
ushort pduRef = r_message.PduRef;
const ushort parLg = 14; // 参数字节数2+12的倍数目前仅为14
const ushort datLg = 0; // 数据字节数
const byte serviceId = 0x04;
const byte numberOfVariables = 1;
const byte variableSpec = 0x12;
const byte vAddrLg = 0x0A;
const byte syntaxId = 0x10;
byte type = r_message.TypeCode;
ushort numberOfElements = r_message.NumberOfElements;
ushort dbBlock = r_message.DbBlock;
byte area = r_message.Area;
int offsetBit = r_message.Offset*8;
byte[] offsetBitBytes = ValueHelper.Instance.GetBytes(offsetBit);
return Format(new byte[7], protoId, rosctr, redId, pduRef, parLg, datLg, serviceId, numberOfVariables
, variableSpec, vAddrLg, syntaxId, type, numberOfElements, dbBlock, area,
offsetBitBytes.Skip(1).ToArray());
}
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
{
pos = 4;
ushort pduRef = ValueHelper.Instance.GetUShort(messageBytes, ref pos);
pos = 14;
byte accessResult = ValueHelper.Instance.GetByte(messageBytes, ref pos);
byte dataType = ValueHelper.Instance.GetByte(messageBytes, ref pos);
ushort length = ValueHelper.Instance.GetUShort(messageBytes, ref pos);
int byteLength = length/8;
var values = new Byte[byteLength];
Array.Copy(messageBytes, pos, values, 0, byteLength);
return new ReadRequestSimenseOutputStruct(pduRef, (SimenseAccessResult) accessResult,
(SimenseDataType) dataType, length, values);
}
}
public class WriteRequestSimenseInputStruct : InputStruct
{
public WriteRequestSimenseInputStruct(ushort pduRef, string startAddress, object[] writeValue, AddressTranslator addressTranslator)
{
PduRef = pduRef;
var address = addressTranslator.AddressTranslate(startAddress, true);
Offset = address.Key;
int area = address.Value;
Area = (byte)(area % 256);
DbBlock = Area == 0x84 ? (ushort)(area / 256) : (ushort)0;
WriteValue = writeValue;
}
public ushort PduRef { get; private set; }
public ushort DbBlock { get; private set; }
public byte Area { get; private set; }
public int Offset { get; private set; }
public object[] WriteValue { get; private set; }
}
public class WriteRequestSimenseOutputStruct : OutputStruct
{
public WriteRequestSimenseOutputStruct(ushort pduRef, SimenseAccessResult accessResult)
{
PduRef = pduRef;
AccessResult = accessResult;
}
public ushort PduRef { get; private set; }
public SimenseAccessResult AccessResult {get; private set; }
}
public class WriteRequestSimenseProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (WriteRequestSimenseInputStruct) message;
byte[] valueBytes = ValueHelper.Instance.ObjectArrayToByteArray(r_message.WriteValue);
const byte protoId = 0x32;
const byte rosctr = 0x01;
const ushort redId = 0x0000;
ushort pduRef = r_message.PduRef;
const ushort parLg = 14; // 参数字节数2+12的倍数目前仅为14
ushort datLg = (ushort)(4+valueBytes.Length); // 数据字节数
const byte serviceId = 0x05;
const byte numberOfVariables = 1;
const byte variableSpec = 0x12;
const byte vAddrLg = 0x0A;
const byte syntaxId = 0x10;
const byte typeR = (byte)SimenseTypeCode.Byte;
ushort numberOfElements = (ushort)valueBytes.Length;
ushort dbBlock = r_message.DbBlock;
byte area = r_message.Area;
int offsetBit = r_message.Offset * 8;
byte[] offsetBitBytes = ValueHelper.Instance.GetBytes(offsetBit);
const byte reserved = 0x00;
const byte type = (byte)SimenseDataType.OtherAccess;
ushort numberOfWriteBits = (ushort)(valueBytes.Length*8);
return Format(new byte[7], protoId, rosctr, redId, pduRef, parLg, datLg, serviceId, numberOfVariables
, variableSpec, vAddrLg, syntaxId, typeR, numberOfElements, dbBlock, area,
offsetBitBytes.Skip(1).ToArray(), reserved, type, numberOfWriteBits, valueBytes);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
{
pos = 4;
ushort pduRef = ValueHelper.Instance.GetUShort(messageBytes, ref pos);
pos = 14;
byte accessResult = ValueHelper.Instance.GetByte(messageBytes, ref pos);
return new WriteRequestSimenseOutputStruct(pduRef, (SimenseAccessResult)accessResult);
}
}
public class ReadTimeSimenseInputStruct : InputStruct
{
public ReadTimeSimenseInputStruct(ushort pduRef)
{
PduRef = pduRef;
}
public ushort PduRef { get; private set; }
}
public class ReadTimeSimenseOutputStruct : OutputStruct
{
public ReadTimeSimenseOutputStruct(ushort pduRef, DateTime dateTime)
{
PduRef = pduRef;
DateTime = dateTime;
}
public ushort PduRef { get; private set; }
public DateTime DateTime { get; private set; }
}
public class ReadTimeSimenseProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (ReadTimeSimenseInputStruct) message;
const byte protoId = 0x32;
const byte rosctr = 0x07;
const ushort redId = 0x0000;
ushort pduRef = r_message.PduRef;
const ushort parLg = 8;
const ushort datLg = 4;
const byte serviceId = 0x00;
const byte noVar = 0x01;
const byte varSpc = 0x12;
const byte vAddrLg = 0x04;
const byte synId = 0x11;
const byte classP = 0x47;
const byte id1 = 0x01;
const byte id2 = 0x00;
const byte accRslt = 0x0A;
const byte dType = 0x00;
const ushort length = 0x0000;
return Format(new Byte[7], protoId, rosctr, redId, pduRef, parLg, datLg, serviceId, noVar, varSpc, vAddrLg, synId, classP,
id1, id2, accRslt, dType, length);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
{
pos = 4;
ushort pduRef = ValueHelper.Instance.GetUShort(messageBytes, ref pos);
pos = 28;
byte year1 = ValueHelper.Instance.GetByte(messageBytes, ref pos);
byte month1 = ValueHelper.Instance.GetByte(messageBytes, ref pos);
byte day1 = ValueHelper.Instance.GetByte(messageBytes, ref pos);
byte hour1 = ValueHelper.Instance.GetByte(messageBytes, ref pos);
byte minute1 = ValueHelper.Instance.GetByte(messageBytes, ref pos);
byte second1 = ValueHelper.Instance.GetByte(messageBytes, ref pos);
byte second1_10_100 = ValueHelper.Instance.GetByte(messageBytes, ref pos);
byte second1_1000_weekday = ValueHelper.Instance.GetByte(messageBytes, ref pos);
int year = year1/16*10 + year1%16;
int month = month1/16*10 + month1%16;
int day = day1/16*10 + day1%16;
int hour = hour1/16*10 + hour1%16;
int minute = minute1/16*10 + minute1%16;
int second = second1/16*10 + second1%16;
int millisecond = second1_10_100 / 16 * 100 + second1_10_100 % 16 * 10 + second1_1000_weekday / 16;
int weekday = second1_1000_weekday%16;
DateTime dateTime = new DateTime(DateTime.Now.Year/100*100 + year, month, day, hour, minute, second, millisecond);
if (dateTime > DateTime.Now.AddDays(1)) dateTime = dateTime.AddYears(-100);
if (weekday == 0) return new ReadTimeSimenseOutputStruct(pduRef, dateTime);
while (dateTime.DayOfWeek != (DayOfWeek) (weekday - 1)) dateTime = dateTime.AddYears(-100);
return new ReadTimeSimenseOutputStruct(pduRef, dateTime);
}
}
public class WriteTimeSimenseInputStruct : InputStruct
{
public WriteTimeSimenseInputStruct(ushort pduRef, DateTime dateTime)
{
PduRef = pduRef;
DateTime = dateTime;
}
public ushort PduRef { get; private set; }
public DateTime DateTime { get; private set; }
}
public class WriteTimeSimenseOutputStruct : OutputStruct
{
public WriteTimeSimenseOutputStruct(ushort pduRef, byte id2)
{
PduRef = pduRef;
Id2 = id2;
}
public ushort PduRef { get; private set; }
public byte Id2 { get; private set; }
}
public class WriteTimeSimenseProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (WriteTimeSimenseInputStruct) message;
const byte protoId = 0x32;
const byte rosctr = 0x07;
const ushort redId = 0x0000;
ushort pduRef = r_message.PduRef;
const ushort parLg = 0x0008;
const ushort datLg = 0x000e;
const byte serviceId = 0x00;
const byte noVar = 0x01;
const byte varSpc = 0x12;
const byte vAddrLg = 0x04;
const byte synId = 0x11;
const byte classP = 0x47;
const byte id1 = 0x02;
const byte id2 = 0x00;
const byte accRslt = 0xFF;
const byte dType = 0x09;
const ushort length = 0x000A;
const ushort todClockStatus = 0x0018;
byte year = (byte) (r_message.DateTime.Year%100/10*16 + r_message.DateTime.Year%10);
byte month = (byte) (r_message.DateTime.Month/10*16 + r_message.DateTime.Month%10);
byte day = (byte) (r_message.DateTime.Day/10*16 + r_message.DateTime.Day%10);
byte hour = (byte) (r_message.DateTime.Hour/10*16 + r_message.DateTime.Hour%10);
byte minute = (byte) (r_message.DateTime.Minute/10*16 + r_message.DateTime.Minute%10);
byte second = (byte) (r_message.DateTime.Second/10*16 + r_message.DateTime.Second%10);
byte dayOfWeek = (byte) (r_message.DateTime.DayOfWeek + 1);
return Format(new byte[7], protoId, rosctr, redId, pduRef, parLg, datLg, serviceId, noVar, varSpc, vAddrLg,
synId, classP, id1, id2, accRslt, dType, length, todClockStatus, year, month, day, hour, minute, second,
(byte)0, dayOfWeek);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
{
pos = 4;
ushort pduRef = ValueHelper.Instance.GetUShort(messageBytes, ref pos);
pos = 17;
byte id2 = ValueHelper.Instance.GetByte(messageBytes, ref pos);
return new WriteTimeSimenseOutputStruct(pduRef, id2);
}
}
public class SimenseProtocalErrorException : ProtocalErrorException
{
public int ErrorClass { get; private set; }
public int ErrorCode { get; private set; }
private static readonly Dictionary<int, string> ProtocalErrorDictionary = new Dictionary<int, string>()
{
{0x00, "No Error"},
{0x81, "Error in the application Id of the request"},
{0x82, "Error in the object definition"},
{0x83, "No recources available"},
{0x84, "Error in the sructure of the service request"},
{0x85, "Error in the communitcation equipment"},
{0x87, "Access Error"},
{0xD2, "OVS error"},
{0xD4, "Diagnostic error"},
{0xD6, "Protection system error"},
{0xD8, "BuB error"},
{0xEF, "Layer 2 specific error"},
};
public SimenseProtocalErrorException(int errCls, int errCod)
: base(ProtocalErrorDictionary[errCls] + " : " + errCod)
{
ErrorClass = errCls;
ErrorCode = errCod;
}
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ModBus.Net
{
public class SimenseTcpProtocalLinkerBytesExtend : ProtocalLinkerBytesExtend
{
public override byte[] BytesExtend(byte[] content)
{
Array.Copy(new byte[]{0x03,0x00,0x00,0x00,0x02,0xf0,0x80}, 0, content, 0, 7);
Array.Copy(ValueHelper.Instance.GetBytes((ushort)content.Length), 0, content, 2, 2);
return content;
}
public override byte[] BytesDecact(byte[] content)
{
byte[] newContent = new byte[content.Length - 7];
Array.Copy(content, 7, newContent, 0, newContent.Length);
return newContent;
}
}
}

View File

@@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ModBus.Net
{
public class SimenseTcpProtocal : SimenseProtocal
{
private ushort _taspSrc;
private ushort _tsapDst;
private ushort _maxCalling;
private ushort _maxCalled;
private ushort _maxPdu;
private string _ip;
private int connectTryCount;
public SimenseTcpProtocal(ushort tsapSrc, ushort tsapDst, ushort maxCalling, ushort maxCalled, ushort maxPdu) : this(tsapSrc, tsapDst, maxCalling, maxCalled, maxPdu, ConfigurationManager.IP)
{
}
public SimenseTcpProtocal(ushort tsapSrc, ushort tsapDst, ushort maxCalling, ushort maxCalled, ushort maxPdu, string ip)
{
_taspSrc = tsapSrc;
_tsapDst = tsapDst;
_maxCalling = maxCalling;
_maxCalled = maxCalled;
_maxPdu = maxPdu;
_ip = ip;
connectTryCount = 0;
Connected();
}
public override byte[] SendReceive(params object[] content)
{
while (!ProtocalLinker.IsConnected)
{
Connected();
}
return base.SendReceive(content);
}
public override OutputStruct SendReceive(ProtocalUnit unit, InputStruct content)
{
if (!ProtocalLinker.IsConnected)
{
if (connectTryCount > 10) return null;
Connected();
}
return base.SendReceive(unit, content);
}
private OutputStruct ForceSendReceive(ProtocalUnit unit, InputStruct content)
{
return base.SendReceive(unit, content);
}
protected void Connected()
{
connectTryCount++;
ProtocalLinker = new SimenseTcpProtocalLinker(_ip);
var inputStruct = new CreateReferenceSimenseInputStruct(0x1a, _taspSrc, _tsapDst);
var outputStruct =
(CreateReferenceSimenseOutputStruct) ForceSendReceive(this[typeof(CreateReferenceSimenseProtocal)], inputStruct);
if (!ProtocalLinker.IsConnected) return;
var inputStruct2 = new EstablishAssociationSimenseInputStruct(0x0101, _maxCalling, _maxCalled, _maxPdu);
var outputStruct2 = (EstablishAssociationSimenseOutputStruct)SendReceive(this[typeof(EstablishAssociationSimenseProtocal)], inputStruct2);
}
}
}

View File

@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ModBus.Net
{
public class SimenseTcpProtocalLinker : TcpProtocalLinker
{
public override bool CheckRight(byte[] content)
{
switch (content[5])
{
case 0xd0:
case 0xe0:
return true;
case 0xf0:
switch (content[8])
{
case 0x03:
if (content[17] == 0x00 && content[18] == 0x00) return true;
throw new SimenseProtocalErrorException(content[17],content[18]);
case 0x07:
if (content[27] == 0x00 && content[28] == 0x00) return true;
throw new SimenseProtocalErrorException(content[27],content[28]);
}
return true;
default:
throw new FormatException();
}
}
public SimenseTcpProtocalLinker(string ip)
: base(ip, 102)
{
}
}
}

View File

@@ -0,0 +1,120 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
public enum SimenseType
{
Ppi = 0,
Mpi = 1,
Tcp = 2
}
namespace ModBus.Net
{
public class SimenseUtility : BaseUtility
{
private string _connectionString;
public override string ConnectionString
{
get { return _connectionString; }
set
{
string[] splitStrings = value.Split(',');
switch (splitStrings[1])
{
case "200":
{
_taspSrc = 0x4d57;
_tsapDst = 0x4d57;
_maxCalling = 0x0001;
_maxCalled = 0x0001;
_maxPdu = 0x03c0;
break;
}
}
_connectionString = splitStrings[0];
}
}
private ushort _taspSrc;
private ushort _tsapDst;
private ushort _maxCalling;
private ushort _maxCalled;
private ushort _maxPdu;
private SimenseType _simenseType;
public SimenseType ConnectionType
{
get
{
return _simenseType;
}
set
{
_simenseType = value;
switch (_simenseType)
{
case SimenseType.Ppi:
{
throw new NotImplementedException();
}
case SimenseType.Mpi:
{
throw new NotImplementedException();
}
case SimenseType.Tcp:
{
Wrapper = ConnectionString == null ? new SimenseTcpProtocal(_taspSrc, _tsapDst, _maxCalling, _maxCalled, _maxPdu) : new SimenseTcpProtocal(_taspSrc, _tsapDst, _maxCalling, _maxCalled, _maxPdu, ConnectionString);
break;
}
}
}
}
public SimenseUtility(SimenseType connectionType, string connectionString)
{
ConnectionString = connectionString;
ConnectionType = connectionType;
}
public override void SetConnectionType(int connectionType)
{
ConnectionType = (SimenseType) connectionType;
}
protected override byte[] GetDatas(byte belongAddress, byte materAddress, string startAddress, int getByteCount)
{
var readRequestSimenseInputStruct = new ReadRequestSimenseInputStruct(0xd3c7, SimenseTypeCode.Byte, startAddress, (ushort)getByteCount, AddressTranslator);
var readRequestSimenseOutputStruct =
(ReadRequestSimenseOutputStruct)
Wrapper.SendReceive(Wrapper[typeof(ReadRequestSimenseProtocal)], readRequestSimenseInputStruct);
return readRequestSimenseOutputStruct.GetValue;
}
public override bool SetDatas(byte belongAddress, byte materAddress, string startAddress, object[] setContents)
{
var writeRequestSimenseInputStruct = new WriteRequestSimenseInputStruct(0xd3c8, startAddress, setContents, AddressTranslator);
var writeRequestSimenseOutputStruct =
(WriteRequestSimenseOutputStruct)
Wrapper.SendReceive(Wrapper[typeof(WriteRequestSimenseProtocal)], writeRequestSimenseInputStruct);
if (writeRequestSimenseOutputStruct.AccessResult == SimenseAccessResult.NoError)
return true;
else
return false;
}
public override DateTime GetTime(byte belongAddress)
{
throw new NotImplementedException();
}
public override bool SetTime(byte belongAddress, DateTime setTime)
{
throw new NotImplementedException();
}
}
}

View File

@@ -45,9 +45,9 @@ namespace ModBus.Net
b_AsyncReceive = isAsync;
}
public bool SocketIsConnect
public override bool IsConnected
{
get { return m_socketClient != null ? m_socketClient.Connected : false; }
get { return m_socketClient != null && m_socketClient.Connected; }
}
public void Dispose()
@@ -167,7 +167,7 @@ namespace ModBus.Net
try
{
if (!SocketIsConnect)
if (!IsConnected)
{
Connect();
}
@@ -255,7 +255,7 @@ namespace ModBus.Net
{
m_socketClient.Client.Shutdown(SocketShutdown.Both);
m_socketClient.Client.Close();
if (!SocketIsConnect)
if (!IsConnected)
{
if (SocketErrorShutdown != null)
{

View File

@@ -10,23 +10,13 @@ namespace ModBus.Net
public abstract class TcpProtocalLinker : ProtocalLinker
{
protected TcpProtocalLinker() : this(ConfigurationManager.IP)
protected TcpProtocalLinker() : this(ConfigurationManager.IP, int.Parse(ConfigurationManager.Port))
{
}
protected TcpProtocalLinker(string ip)
protected TcpProtocalLinker(string ip, int port)
{
int port;
//是否启用ConfigurationManager里的Port参数
if (ConfigurationManager.ResourceManager.GetString("Port") != null && int.TryParse(ConfigurationManager.ResourceManager.GetString("Port"),out port))
{
}
else
{
port = 502;
}
_baseConnector = new TcpConnector(ip, port, false);
}
}

View File

@@ -11,6 +11,19 @@ namespace ModBus.Net
/// </summary>
public class ValueHelper
{
public Dictionary<string, double> ByteLength = new Dictionary<string, double>()
{
{"System.Boolean", 0.125},
{"System.Byte", 1},
{"System.Int16", 2},
{"System.Int32", 4},
{"System.Int64", 8},
{"System.UInt16", 2},
{"System.UInt32", 4},
{"System.UInt64", 8},
{"System.Single", 4},
{"System.Double", 8}
};
protected static bool _littleEndian = false;

View File

@@ -12,9 +12,9 @@ namespace NA200H.UI.ConsoleApp
{
private static void Main(string[] args)
{
string ip = "192.168.3.247";
string ip = "192.168.3.241";
//先初始化一个协议转换器这里构造Modbus/Tcp协议。
BaseProtocal wrapper = new ModbusTcpProtocal(ip);
//BaseProtocal wrapper = new ModbusTcpProtocal(ip);
/*
try
@@ -53,14 +53,14 @@ namespace NA200H.UI.ConsoleApp
Console.Read();
Console.Read();*/
/*
//调用方法二:自动构造
//第一步:先生成一个输入结构体,然后向这个结构体中填写数据
AddressTranslator addressTranslator = new AddressTranslatorNA200H();
ReadDataInputStruct readCoilStatusInputStruct = new ReadDataInputStruct(0x02, "N1", 0x0a, addressTranslator);
ReadDataModbusInputStruct readCoilStatusInputStruct = new ReadDataModbusInputStruct(0x02, "N1", 0x0a, addressTranslator);
//第二步:再生成一个输出结构体,执行相应协议的发送指令,并将输出信息自动转换到输出结构体中
ReadDataOutputStruct readCoilStatusOutputStruct = (ReadDataOutputStruct)wrapper.SendReceive(wrapper["ReadDataModbusProtocal"], readCoilStatusInputStruct);
ReadDataModbusOutputStruct readCoilStatusOutputStruct = (ReadDataModbusOutputStruct)wrapper.SendReceive(wrapper[typeof(ReadDataModbusProtocal)], readCoilStatusInputStruct);
//第三步:读取这个输出结构体的信息。
bool[] array =
ValueHelper.Instance.ObjectArrayToDestinationArray<bool>(
@@ -74,8 +74,8 @@ namespace NA200H.UI.ConsoleApp
Console.Read();
Console.Read();
ReadDataInputStruct readHoldRegisterInputStruct = new ReadDataInputStruct(0x02, "NW1", 4, addressTranslator);
ReadDataOutputStruct readHoldRegisterOutputStruct = (ReadDataOutputStruct)wrapper.SendReceive(wrapper["ReadDataModbusProtocal"], readHoldRegisterInputStruct);
ReadDataModbusInputStruct readHoldRegisterInputStruct = new ReadDataModbusInputStruct(0x02, "NW1", 4, addressTranslator);
ReadDataModbusOutputStruct readHoldRegisterOutputStruct = (ReadDataModbusOutputStruct)wrapper.SendReceive(wrapper[typeof(ReadDataModbusProtocal)], readHoldRegisterInputStruct);
ushort[] array2 =
ValueHelper.Instance.ObjectArrayToDestinationArray<ushort>(
ValueHelper.Instance.ByteArrayToObjectArray(readHoldRegisterOutputStruct.DataValue,
@@ -88,35 +88,77 @@ namespace NA200H.UI.ConsoleApp
Console.Read();
Console.Read();
WriteDataInputStruct writeMultiCoilInputStruct = new WriteDataInputStruct(0x02, "Q20", new object[] { true, false, true, true, false, false, true, true, true, false }, addressTranslator);
WriteDataOutputStruct writeMultiCoilOutputStruct = (WriteDataOutputStruct)wrapper.SendReceive(wrapper["WriteDataModbusProtocal"], writeMultiCoilInputStruct);
WriteDataModbusInputStruct writeMultiCoilInputStruct = new WriteDataModbusInputStruct(0x02, "Q20", new object[] { true, false, true, true, false, false, true, true, true, false }, addressTranslator);
WriteDataModbusOutputStruct writeMultiCoilOutputStruct = (WriteDataModbusOutputStruct)wrapper.SendReceive(wrapper[typeof(WriteDataModbusProtocal)], writeMultiCoilInputStruct);
Console.WriteLine(writeMultiCoilOutputStruct.StartAddress);
Console.WriteLine(writeMultiCoilOutputStruct.WriteCount);
Console.WriteLine();
Console.Read();
Console.Read();
WriteDataInputStruct writeMultiRegisterInputStruct = new WriteDataInputStruct(0x02, "NW1", new object[] { (ushort)25, (ushort)18, (ushort)17 }, addressTranslator);
WriteDataOutputStruct writeMultiRegisterOutputStruct = (WriteDataOutputStruct)wrapper.SendReceive(wrapper["WriteDataModbusProtocal"], writeMultiRegisterInputStruct);
WriteDataModbusInputStruct writeMultiRegisterInputStruct = new WriteDataModbusInputStruct(0x02, "NW1", new object[] { (ushort)25, (ushort)18, (ushort)17 }, addressTranslator);
WriteDataModbusOutputStruct writeMultiRegisterOutputStruct = (WriteDataModbusOutputStruct)wrapper.SendReceive(wrapper[typeof(WriteDataModbusProtocal)], writeMultiRegisterInputStruct);
Console.WriteLine(writeMultiRegisterOutputStruct.StartAddress);
Console.WriteLine(writeMultiRegisterOutputStruct.WriteCount);
Console.WriteLine();
Console.Read();
Console.Read();
GetSystemTimeInputStruct getSystemTimeInputStruct = new GetSystemTimeInputStruct(0x02);
GetSystemTimeOutputStruct getSystemTimeOutputStruct = (GetSystemTimeOutputStruct)wrapper.SendReceive(wrapper["GetSystemTimeModbusProtocal"], getSystemTimeInputStruct);
GetSystemTimeModbusInputStruct getSystemTimeInputStruct = new GetSystemTimeModbusInputStruct(0x02);
GetSystemTimeModbusOutputStruct getSystemTimeOutputStruct = (GetSystemTimeModbusOutputStruct)wrapper.SendReceive(wrapper[typeof(GetSystemTimeModbusProtocal)], getSystemTimeInputStruct);
Console.WriteLine(getSystemTimeOutputStruct.Time);
Console.Read();
Console.Read();
SetSystemTimeInputStruct setSystemTimeInputStruct = new SetSystemTimeInputStruct(0x02, DateTime.Now);
SetSystemTimeOutputStruct setSystemTimeOutputStruct = (SetSystemTimeOutputStruct)wrapper.SendReceive(wrapper["SetSystemTimeModbusProtocal"], setSystemTimeInputStruct);
SetSystemTimeModbusInputStruct setSystemTimeInputStruct = new SetSystemTimeModbusInputStruct(0x02, DateTime.Now);
SetSystemTimeModbusOutputStruct setSystemTimeOutputStruct = (SetSystemTimeModbusOutputStruct)wrapper.SendReceive(wrapper[typeof(SetSystemTimeModbusProtocal)], setSystemTimeInputStruct);
Console.WriteLine(setSystemTimeOutputStruct.StartAddress);
Console.WriteLine(setSystemTimeOutputStruct.WriteCount);
Console.Read();
Console.Read();
*/
BaseProtocal wrapper = new SimenseTcpProtocal(0x4d57, 0x4d57, 0x0001, 0x0001, 0x03c0, ip);
if (!wrapper.ProtocalLinker.IsConnected) return;
AddressTranslator addressTranslator = new AddressTranslatorSimense();
var readRequestSimenseInputStruct = new ReadRequestSimenseInputStruct(0xaacc, SimenseTypeCode.Byte, "V0", 4, addressTranslator);
var readRequestSimenseOutputStruct =
(ReadRequestSimenseOutputStruct)
wrapper.SendReceive(wrapper[typeof(ReadRequestSimenseProtocal)], readRequestSimenseInputStruct);
ushort[] array =
ValueHelper.Instance.ObjectArrayToDestinationArray<ushort>(
ValueHelper.Instance.ByteArrayToObjectArray(readRequestSimenseOutputStruct.GetValue,
new KeyValuePair<Type, int>(typeof (ushort), 2)));
for (int i = 0; i < array.Length; i++)
{
Console.WriteLine(array[i]);
}
Console.Read();
Console.Read();
var writeRequestSimenseInputStruct = new WriteRequestSimenseInputStruct(0xaadd, "V100",
new object[] { (ushort)280, (ushort)12, (ushort)56, (ushort)72, (ushort)88, (ushort)525, (ushort)477, (ushort)151, (ushort)52 }, addressTranslator);
var writeRequestSimenseOutputStruct =
(WriteRequestSimenseOutputStruct)
wrapper.SendReceive(wrapper[typeof(WriteRequestSimenseProtocal)], writeRequestSimenseInputStruct);
Console.WriteLine(writeRequestSimenseOutputStruct.AccessResult.ToString());
Console.Read();
Console.Read();
var readTimeSimenseInputStruct = new ReadTimeSimenseInputStruct(0xaaee);
var readTimeSimenseOutputStruct =
(ReadTimeSimenseOutputStruct)
wrapper.SendReceive(wrapper[typeof(ReadTimeSimenseProtocal)], readTimeSimenseInputStruct);
Console.WriteLine(readTimeSimenseOutputStruct.DateTime);
Console.Read();
Console.Read();
var writeTimeSimenseInputStruct = new WriteTimeSimenseInputStruct(0xaaee, DateTime.Now);
var writeTimeSimenseOutputStruct =
(WriteTimeSimenseOutputStruct)
wrapper.SendReceive(wrapper[typeof(WriteTimeSimenseProtocal)], writeTimeSimenseInputStruct);
Console.WriteLine(writeTimeSimenseOutputStruct.Id2);
}
}
}

Binary file not shown.

View File

@@ -12,7 +12,7 @@ namespace NA200H.UI.WPF
/// </summary>
public partial class MainWindow : Window
{
private ModbusUtility utility;
private BaseUtility utility;
public MainWindow()
{
InitializeComponent();
@@ -20,14 +20,13 @@ namespace NA200H.UI.WPF
private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
{
utility = new ModbusUtility((int) ModbusType.Tcp, "192.168.3.247");
utility.AddressTranslator = new AddressTranslatorNA200H();
//byte[] getNum = utility.GetDatas(0x02, "03:10000", 8);
byte[] getNum = utility.GetDatas(0x02, "NW1", 8);
object[] getNumObjects =
ValueHelper.Instance.ByteArrayToObjectArray(getNum,
new List<KeyValuePair<Type, int>>(){{new KeyValuePair<Type, int>(typeof(ushort), 4)}});
ushort[] getNumUshorts = ValueHelper.Instance.ObjectArrayToDestinationArray<ushort>(getNumObjects);
//utility = new ModbusUtility(ModbusType.Tcp, "192.168.3.247");
//utility.AddressTranslator = new AddressTranslatorNA200H();
//object[] getNum = utility.GetDatas(0x02, 0x00, "NW1", new KeyValuePair<Type, int>(typeof(ushort), 4));
utility = new SimenseUtility(SimenseType.Tcp, "192.168.3.241,200");
utility.AddressTranslator = new AddressTranslatorSimense();
object[] getNum = utility.GetDatas(0x02, 0x00, "V1", new KeyValuePair<Type, int>(typeof(ushort), 4));
ushort[] getNumUshorts = ValueHelper.Instance.ObjectArrayToDestinationArray<ushort>(getNum);
SetValue(getNumUshorts);
}
@@ -45,14 +44,12 @@ namespace NA200H.UI.WPF
ushort.TryParse(Add1.Text, out add1);
ushort.TryParse(Add2.Text, out add2);
ushort.TryParse(Add3.Text, out add3);
//utility.SetDatas(0x02, "16:10000", new object[] {add1, add2, add3});
utility.SetDatas(0x02, "NW1", new object[] { add1, add2, add3 });
//utility.SetDatas(0x02, 0x00, "NW1", new object[] { add1, add2, add3 });
utility.SetDatas(0x02, 0x00, "V1", new object[] { add1, add2, add3 });
Thread.Sleep(100);
//byte[] getNum = utility.GetDatas(0x02, "03:10000", 8);
byte[] getNum = utility.GetDatas(0x02, "NW1", 8);
object[] getNumObjects =
ValueHelper.Instance.ByteArrayToObjectArray(getNum, new KeyValuePair<Type, int>(typeof(ushort), 4));
ushort[] getNumUshorts = ValueHelper.Instance.ObjectArrayToDestinationArray<ushort>(getNumObjects);
//object[] getNum = utility.GetDatas(0x02, 0x00, "NW1", new KeyValuePair<Type, int>(typeof(ushort), 4));
object[] getNum = utility.GetDatas(0x02, 0x00, "V1", new KeyValuePair<Type, int>(typeof(ushort), 4));
ushort[] getNumUshorts = ValueHelper.Instance.ObjectArrayToDestinationArray<ushort>(getNum);
SetValue(getNumUshorts);
}
}