2016-01-29 update 1

This commit is contained in:
parallelbgls
2016-01-29 12:52:19 +08:00
parent 4106be8690
commit 1bfaa71e2e
97 changed files with 15352 additions and 12239 deletions

View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ModBus.Net.Modbus
{
public class AddressFormaterNA200H : AddressFormater
{
public override string FormatAddress(string area, int address)
{
return area + " " + address;
}
}
public class AddressFormaterModbus : AddressFormater
{
public override string FormatAddress(string area, int address)
{
return area + " " + address;
}
}
}

View File

@@ -0,0 +1,108 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ModBus.Net.Modbus
{
/// <summary>
/// NA200H数据单元翻译器
/// </summary>
public class AddressTranslatorNA200H : AddressTranslator
{
protected Dictionary<string, int> TransDictionary;
protected Dictionary<string, int> ReadFunctionCodeDictionary;
protected Dictionary<string, int> WriteFunctionCodeDictionary;
public AddressTranslatorNA200H()
{
TransDictionary = new Dictionary<string, int>
{
{"Q", 0},
{"M", 10000},
{"N", 30000},
{"I", 0},
{"S", 10000},
{"IW", 0},
{"SW", 5000},
{"MW", 0},
{"QW", 20000},
{"NW", 21000},
};
ReadFunctionCodeDictionary = new Dictionary<string, int>
{
{"Q", (int)ModbusProtocalReadDataFunctionCode.ReadCoilStatus},
{"M", (int)ModbusProtocalReadDataFunctionCode.ReadCoilStatus},
{"N", (int)ModbusProtocalReadDataFunctionCode.ReadCoilStatus},
{"I", (int)ModbusProtocalReadDataFunctionCode.ReadInputStatus},
{"S", (int)ModbusProtocalReadDataFunctionCode.ReadInputStatus},
{"IW", (int)ModbusProtocalReadDataFunctionCode.ReadInputRegister},
{"SW", (int)ModbusProtocalReadDataFunctionCode.ReadInputRegister},
{"MW", (int)ModbusProtocalReadDataFunctionCode.ReadHoldRegister},
{"NW", (int)ModbusProtocalReadDataFunctionCode.ReadHoldRegister},
{"QW", (int)ModbusProtocalReadDataFunctionCode.ReadHoldRegister},
};
WriteFunctionCodeDictionary = new Dictionary<string, int>
{
{"Q", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiCoil},
{"M", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiCoil},
{"N", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiCoil},
{"MW", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiRegister},
{"NW", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiRegister},
{"QW", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiRegister},
};
}
public override KeyValuePair<int, int> AddressTranslate(string address, bool isRead)
{
address = address.ToUpper();
string[] splitString = address.Split(' ');
string head = splitString[0];
string tail = splitString[1];
return isRead
? new KeyValuePair<int, int>(TransDictionary[head] + int.Parse(tail) - 1,
ReadFunctionCodeDictionary[head])
: new KeyValuePair<int, int>(TransDictionary[head] + int.Parse(tail) - 1,
WriteFunctionCodeDictionary[head]);
}
}
/// <summary>
/// Modbus数据单元翻译器
/// </summary>
public class AddressTranslatorModbus : AddressTranslator
{
protected Dictionary<string, int> ReadFunctionCodeDictionary;
protected Dictionary<string, int> WriteFunctionCodeDictionary;
public AddressTranslatorModbus()
{
ReadFunctionCodeDictionary = new Dictionary<string, int>
{
{"0X", (int)ModbusProtocalReadDataFunctionCode.ReadCoilStatus},
{"1X", (int)ModbusProtocalReadDataFunctionCode.ReadInputStatus},
{"3X", (int)ModbusProtocalReadDataFunctionCode.ReadInputRegister},
{"4X", (int)ModbusProtocalReadDataFunctionCode.ReadHoldRegister},
};
WriteFunctionCodeDictionary = new Dictionary<string, int>
{
{"0X", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiCoil},
{"4X", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiRegister},
};
}
public override KeyValuePair<int, int> AddressTranslate(string address, bool isRead)
{
address = address.ToUpper();
string[] splitString = address.Split(' ');
string head = splitString[0];
string tail = splitString[1];
return isRead
? new KeyValuePair<int, int>(int.Parse(tail) - 1,
ReadFunctionCodeDictionary[head])
: new KeyValuePair<int, int>(int.Parse(tail) - 1,
WriteFunctionCodeDictionary[head]);
}
}
}

View File

@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{FDCA72BA-6D06-4DE0-B873-C11C4AC853AD}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Modbus.Net.Modbus</RootNamespace>
<AssemblyName>Modbus.Net.Modbus</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AddressFormaterModbus.cs" />
<Compile Include="AddressTranslatorModbus.cs" />
<Compile Include="ModbusMachine.cs" />
<Compile Include="ModbusProtocal.cs" />
<Compile Include="ModbusProtocalLinkerBytesExtend.cs" />
<Compile Include="ModbusRtuProtocal.cs" />
<Compile Include="ModbusRtuProtocalLinker.cs" />
<Compile Include="ModbusTcpProtocal.cs" />
<Compile Include="ModbusTcpProtocalLinker.cs" />
<Compile Include="ModbusUtility.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ModBus.Net\ModBus.Net.csproj">
<Project>{124ebef2-8960-4447-84cf-1d683b1ef7cc}</Project>
<Name>ModBus.Net</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,21 @@
using System.Collections.Generic;
namespace ModBus.Net.Modbus
{
public class ModbusMachine : BaseMachine
{
public ModbusMachine(ModbusType connectionType, string connectionString,
IEnumerable<AddressUnit> getAddresses, bool keepConnect) : base(getAddresses, keepConnect)
{
BaseUtility = new ModbusUtility(connectionType, connectionString);
AddressFormater = new AddressFormaterModbus();
AddressCombiner = new AddressCombinerContinus();
}
public ModbusMachine(ModbusType connectionType, string connectionString,
IEnumerable<AddressUnit> getAddresses)
: this(connectionType, connectionString, getAddresses, false)
{
}
}
}

View File

@@ -0,0 +1,377 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ModBus.Net.Modbus
{
internal enum ModbusProtocalVariableFunctionCode : byte
{
ReadVariable = 20,
WriteVariable = 21,
}
/// <summary>
/// 跟时间有关的功能码
/// </summary>
public enum ModbusProtocalTimeFunctionCode : byte
{
GetSystemTime = 3,
SetSystemTime = 16,
}
/// <summary>
/// 跟读数据有关的功能码
/// </summary>
public enum ModbusProtocalReadDataFunctionCode : byte
{
ReadCoilStatus = 1,
ReadInputStatus = 2,
ReadHoldRegister = 3,
ReadInputRegister = 4,
}
/// <summary>
/// 跟写数据有关的功能码
/// </summary>
internal enum ModbusProtocalWriteDataFunctionCode : byte
{
WriteMultiCoil = 15,
WriteMultiRegister = 16,
}
public abstract class ModbusProtocal : BaseProtocal
{
public override bool Connect()
{
return ProtocalLinker.Connect();
}
public override async Task<bool> ConnectAsync()
{
return await ProtocalLinker.ConnectAsync();
}
}
#region PLC数据
public class ReadDataModbusInputStruct : InputStruct
{
public ReadDataModbusInputStruct(byte belongAddress, string startAddress, ushort getCount, AddressTranslator addressTranslator)
{
BelongAddress = belongAddress;
KeyValuePair<int, int> translateAddress = addressTranslator.AddressTranslate(startAddress, true);
FunctionCode = (byte)translateAddress.Value;
StartAddress = (ushort)translateAddress.Key;
GetCount = getCount;
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public ushort StartAddress { get; private set; }
public ushort GetCount { get; private set; }
}
public class ReadDataModbusOutputStruct : OutputStruct
{
public ReadDataModbusOutputStruct(byte belongAddress, byte functionCode,
int dataCount, byte[] dataValue)
{
BelongAddress = belongAddress;
FunctionCode = functionCode;
DataCount = dataCount;
DataValue = dataValue.Clone() as byte[];
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public int DataCount { get; private set; }
public byte[] DataValue { get; private set; }
}
public class ReadDataModbusProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (ReadDataModbusInputStruct)message;
return Format(r_message.BelongAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.GetCount);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
{
byte belongAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
byte functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
byte dataCount = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
byte[] dataValue = new byte[dataCount];
Array.Copy(messageBytes, 3, dataValue, 0, dataCount);
return new ReadDataModbusOutputStruct(belongAddress, functionCode, dataCount, dataValue);
}
}
#endregion
#region PLC数据
public class WriteDataModbusInputStruct : InputStruct
{
public WriteDataModbusInputStruct(byte belongAddress, string startAddress, object[] writeValue, AddressTranslator addressTranslator)
{
BelongAddress = belongAddress;
KeyValuePair<int, int> translateAddress = addressTranslator.AddressTranslate(startAddress, false);
FunctionCode = (byte)translateAddress.Value;
StartAddress = (ushort)translateAddress.Key;
WriteCount = (ushort)writeValue.Length;
WriteByteCount = 0;
WriteValue = writeValue;
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public ushort StartAddress { get; private set; }
public ushort WriteCount { get; private set; }
public byte WriteByteCount { get; private set; }
public object[] WriteValue { get; private set; }
}
public class WriteDataModbusOutputStruct : OutputStruct
{
public WriteDataModbusOutputStruct(byte belongAddress, byte functionCode,
ushort startAddress, ushort writeCount)
{
BelongAddress = belongAddress;
FunctionCode = functionCode;
StartAddress = startAddress;
WriteCount = writeCount;
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public ushort StartAddress { get; private set; }
public ushort WriteCount { get; private set; }
}
/// <summary>
/// 写多个寄存器状态
/// </summary>
public class WriteDataModbusProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct 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);
return formattingBytes;
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
{
byte belongAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
byte functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
ushort startAddress = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag);
ushort writeCount = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag);
return new WriteDataModbusOutputStruct(belongAddress, functionCode, startAddress,
writeCount);
}
}
#endregion
#region PLC时间
public class GetSystemTimeModbusInputStruct : InputStruct
{
public GetSystemTimeModbusInputStruct(byte belongAddress)
{
BelongAddress = belongAddress;
FunctionCode = (byte)ModbusProtocalTimeFunctionCode.GetSystemTime;
StartAddress = 30000;
GetCount = 5;
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public ushort StartAddress { get; private set; }
public ushort GetCount { get; private set; }
}
public class GetSystemTimeModbusOutputStruct : OutputStruct
{
public GetSystemTimeModbusOutputStruct(byte belongAddress, byte functionCode,
byte writeByteCount, ushort year, byte day, byte month, ushort hour, byte second, byte minute,
ushort millisecond)
{
BelongAddress = belongAddress;
FunctionCode = functionCode;
WriteByteCount = writeByteCount;
Time = new DateTime(year, month, day, hour, minute, second, millisecond);
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public byte WriteByteCount { get; private set; }
public DateTime Time { get; private set; }
}
/// <summary>
/// 读系统时间
/// </summary>
public class GetSystemTimeModbusProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (GetSystemTimeModbusInputStruct)message;
return Format(r_message.BelongAddress, r_message.FunctionCode,
r_message.StartAddress, r_message.GetCount);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
{
byte belongAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
byte functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
byte writeByteCount = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
ushort year = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag);
byte day = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
byte month = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
ushort hour = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag);
byte second = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
byte minute = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
ushort millisecond = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag);
return new GetSystemTimeModbusOutputStruct(belongAddress, functionCode, writeByteCount, year, day,
month, hour, second, minute, millisecond);
}
}
#endregion
#region PLC时间
public class SetSystemTimeModbusInputStruct : InputStruct
{
public SetSystemTimeModbusInputStruct(byte belongAddress, DateTime time)
{
BelongAddress = belongAddress;
FunctionCode = (byte)ModbusProtocalTimeFunctionCode.SetSystemTime;
StartAddress = 30000;
WriteCount = 5;
WriteByteCount = 10;
Year = (ushort)time.Year;
Day = (byte)time.Day;
Month = (byte)time.Month;
Hour = (ushort)time.Hour;
Second = (byte)time.Second;
Minute = (byte)time.Minute;
Millisecond = (ushort)time.Millisecond;
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public ushort StartAddress { get; private set; }
public ushort WriteCount { get; private set; }
public byte WriteByteCount { get; private set; }
public ushort Year { get; private set; }
public byte Day { get; private set; }
public byte Month { get; private set; }
public ushort Hour { get; private set; }
public byte Second { get; private set; }
public byte Minute { get; private set; }
public ushort Millisecond { get; private set; }
}
public class SetSystemTimeModbusOutputStruct : OutputStruct
{
public SetSystemTimeModbusOutputStruct(byte belongAddress, byte functionCode,
ushort startAddress, ushort writeCount)
{
BelongAddress = belongAddress;
FunctionCode = functionCode;
StartAddress = startAddress;
WriteCount = writeCount;
}
public byte BelongAddress { get; private set; }
public byte FunctionCode { get; private set; }
public ushort StartAddress { get; private set; }
public ushort WriteCount { get; private set; }
}
/// <summary>
/// 写系统时间
/// </summary>
public class SetSystemTimeModbusProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct 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,
r_message.Month, r_message.Hour, r_message.Second, r_message.Minute, r_message.Millisecond);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int flag)
{
byte belongAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
byte functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag);
ushort startAddress = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag);
ushort writeCount = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag);
return new SetSystemTimeModbusOutputStruct(belongAddress, functionCode, startAddress, writeCount);
}
}
#endregion
/// <summary>
/// Modbus协议错误表
/// </summary>
public class ModbusProtocalErrorException : ProtocalErrorException
{
public int ErrorMessageNumber { get; private set; }
private static readonly Dictionary<int, string> ProtocalErrorDictionary = new Dictionary<int, string>()
{
{1, "ILLEGAL_FUNCTION"},
{2, "ILLEGAL_DATA_ACCESS"},
{3, "ILLEGAL_DATA_VALUE"},
{4, "SLAVE_DEVICE_FAILURE"},
{5, "ACKNOWLWDGE"},
{6, "SLAVE_DEVICE_BUSY"},
{500, "TCP_ILLEGAL_LENGTH"},
{501, "RTU_ILLEGAL_CRC"},
};
public ModbusProtocalErrorException(int messageNumber)
: base(ProtocalErrorDictionary[messageNumber])
{
ErrorMessageNumber = messageNumber;
}
}
}

View File

@@ -0,0 +1,52 @@
using System;
namespace ModBus.Net.Modbus
{
/// <summary>
/// Tcp协议字节伸缩
/// </summary>
public class ModbusTcpProtocalLinkerBytesExtend : ProtocalLinkerBytesExtend
{
public override byte[] BytesExtend(byte[] content)
{
//Modbus/Tcp协议扩张前面加6个字节前面4个为0后面两个为协议整体内容的长度
byte[] newFormat = new byte[6 + content.Length];
int tag = 0;
ushort leng = (ushort)content.Length;
Array.Copy(BigEndianValueHelper.Instance.GetBytes(tag), 0, newFormat, 0, 4);
Array.Copy(BigEndianValueHelper.Instance.GetBytes(leng), 0, newFormat, 4, 2);
Array.Copy(content, 0, newFormat, 6, content.Length);
return newFormat;
}
public override byte[] BytesDecact(byte[] content)
{
//Modbus/Tcp协议收缩抛弃前面6个字节的内容
byte[] newContent = new byte[content.Length - 6];
Array.Copy(content, 6, newContent, 0, newContent.Length);
return newContent;
}
}
public class ModbusRtuProtocalLinkerBytesExtend : ProtocalLinkerBytesExtend
{
public override byte[] BytesExtend(byte[] content)
{
byte[] crc = new byte[2];
//Modbus/Rtu协议扩张增加CRC校验
byte[] newFormat = new byte[content.Length + 2];
Crc16.GetInstance().GetCRC(content, ref crc);
Array.Copy(content, 0, newFormat, 0, content.Length);
Array.Copy(crc, 0, newFormat, newFormat.Length - 2, crc.Length);
return newFormat;
}
public override byte[] BytesDecact(byte[] content)
{
//Modbus/Rtu协议收缩抛弃后面1个字节的内容
byte[] newContent = new byte[content.Length - 2];
Array.Copy(content, 0, newContent, 0, newContent.Length);
return newContent;
}
}
}

View File

@@ -0,0 +1,17 @@
namespace ModBus.Net.Modbus
{
/// <summary>
/// Modbus/Rtu协议
/// </summary>
public class ModbusRtuProtocal : ModbusProtocal
{
public ModbusRtuProtocal() : this(ConfigurationManager.COM)
{
}
public ModbusRtuProtocal(string com)
{
ProtocalLinker = new ModbusRtuProtocalLinker(com);
}
}
}

View File

@@ -0,0 +1,26 @@
namespace ModBus.Net.Modbus
{
class ModbusRtuProtocalLinker : ComProtocalLinker
{
public override bool CheckRight(byte[] content)
{
if (!base.CheckRight(content)) return false;
//CRC校验失败
if (!Crc16.GetInstance().CrcEfficacy(content))
{
throw new ModbusProtocalErrorException(501);
}
//Modbus协议错误
if (content[1] > 127)
{
throw new ModbusProtocalErrorException(content[2]);
}
return true;
}
public ModbusRtuProtocalLinker(string com) : base(com)
{
}
}
}

View File

@@ -0,0 +1,17 @@
namespace ModBus.Net.Modbus
{
/// <summary>
/// Modbus/Tcp协议
/// </summary>
public class ModbusTcpProtocal : ModbusProtocal
{
public ModbusTcpProtocal() : this(ConfigurationManager.IP)
{
}
public ModbusTcpProtocal(string ip)
{
ProtocalLinker = new ModbusTcpProtocalLinker(ip);
}
}
}

View File

@@ -0,0 +1,26 @@
namespace ModBus.Net.Modbus
{
public class ModbusTcpProtocalLinker : TcpProtocalLinker
{
public override bool CheckRight(byte[] content)
{
if (!base.CheckRight(content)) return false;
//长度校验失败
if (content[5] != content.Length - 6)
{
throw new ModbusProtocalErrorException(500);
}
//Modbus协议错误
if (content[7] > 127)
{
throw new ModbusProtocalErrorException(content[2]);
}
return true;
}
public ModbusTcpProtocalLinker(string ip) : base(ip, int.Parse(ConfigurationManager.ModbusPort))
{
}
}
}

View File

@@ -0,0 +1,136 @@
using System.Threading.Tasks;
namespace ModBus.Net.Modbus
{
/// <summary>
/// Modbus连接类型
/// </summary>
public enum ModbusType
{
/// <summary>
/// Rtu连接
/// </summary>
Rtu = 0,
/// <summary>
/// Tcp连接
/// </summary>
Tcp = 1,
}
public class ModbusUtility : BaseUtility
{
private ModbusType _modbusType;
public ModbusType ModbusType
{
get
{
return _modbusType;
}
set
{
_modbusType = value;
switch (_modbusType)
{
case ModbusType.Rtu:
{
Wrapper = ConnectionString == null ? new ModbusRtuProtocal() : new ModbusRtuProtocal(ConnectionString);
break;
}
case ModbusType.Tcp:
{
Wrapper = ConnectionString == null ? new ModbusTcpProtocal() : new ModbusTcpProtocal(ConnectionString);
break;
}
}
}
}
public ModbusUtility(int connectionType)
{
ConnectionString = null;
ModbusType = (ModbusType)connectionType;
AddressTranslator = new AddressTranslatorModbus();
}
public ModbusUtility(ModbusType connectionType, string connectionString)
{
ConnectionString = connectionString;
ModbusType = connectionType;
AddressTranslator = new AddressTranslatorModbus();
}
public override void SetConnectionType(int connectionType)
{
ModbusType = (ModbusType) connectionType;
}
protected override async Task<byte[]> GetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, int getByteCount)
{
try
{
var inputStruct = new ReadDataModbusInputStruct(belongAddress, startAddress,
getByteCount%2 == 0 ? (ushort) (getByteCount/2) : (ushort) (getByteCount/2 + 1), AddressTranslator);
var outputStruct = await
Wrapper.SendReceiveAsync(Wrapper[typeof (ReadDataModbusProtocal)], inputStruct) as
ReadDataModbusOutputStruct;
return outputStruct?.DataValue;
}
catch
{
return null;
}
}
public override async Task<bool> SetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, object[] setContents)
{
try
{
var inputStruct = new WriteDataModbusInputStruct(belongAddress, startAddress, setContents,
AddressTranslator);
var outputStruct = await
Wrapper.SendReceiveAsync(Wrapper[typeof (WriteDataModbusProtocal)], inputStruct) as
WriteDataModbusOutputStruct;
return outputStruct?.WriteCount == setContents.Length;
}
catch
{
return false;
}
}
/*
public override DateTime GetTime(byte belongAddress)
{
try
{
var inputStruct = new GetSystemTimeModbusInputStruct(belongAddress);
var outputStruct =
Wrapper.SendReceive(Wrapper[typeof(GetSystemTimeModbusProtocal)], inputStruct) as
GetSystemTimeModbusOutputStruct;
return outputStruct?.Time;
}
catch (Exception)
{
return DateTime.MinValue;
}
}
public override bool SetTime(byte belongAddress, DateTime setTime)
{
try
{
var inputStruct = new SetSystemTimeModbusInputStruct(belongAddress, setTime);
var outputStruct =
Wrapper.SendReceive(Wrapper[typeof(SetSystemTimeModbusProtocal)], inputStruct) as
SetSystemTimeModbusOutputStruct;
return outputStruct?.WriteCount > 0;
}
catch (Exception)
{
return false;
}
}
*/
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("Modbus.Net.Modbus")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Modbus.Net.Modbus")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
//将 ComVisible 设置为 false 将使此程序集中的类型
//对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("fdca72ba-6d06-4de0-b873-c11c4ac853ad")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”: :
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]