2017-02-14 update 1 bug fix.

This commit is contained in:
parallelbgls
2017-02-14 11:31:36 +08:00
parent 0d19567038
commit 7e0fa1cf59
10 changed files with 469 additions and 424 deletions

View File

@@ -119,7 +119,7 @@ namespace Modbus.Net.Modbus
{ {
for (var i = 0; i < dataValue.Length; i++) for (var i = 0; i < dataValue.Length; i++)
{ {
dataValue[i] = BigEndianValueHelper.Instance.ReverseByte(dataValue[i]); dataValue[i] = dataValue[i];
} }
} }
return new ReadDataModbusOutputStruct(slaveAddress, functionCode, dataCount, dataValue); return new ReadDataModbusOutputStruct(slaveAddress, functionCode, dataCount, dataValue);
@@ -193,7 +193,7 @@ namespace Modbus.Net.Modbus
{ {
for (var i = 0; i < dataValue.Length; i++) for (var i = 0; i < dataValue.Length; i++)
{ {
dataValue[i] = BigEndianValueHelper.Instance.ReverseByte(dataValue[i]); dataValue[i] = dataValue[i];
} }
} }
var formattingBytes = Format(r_message.SlaveAddress, r_message.FunctionCode, var formattingBytes = Format(r_message.SlaveAddress, r_message.FunctionCode,

View File

@@ -16,7 +16,7 @@ Modbus is a serial communications protocol originally published by Modicon (now
##<a name="address"></a> Address Mapping ##<a name="address"></a> Address Mapping
Modbus has four types of address: Coil, Discrete Input, Holding Register and Input Register. Modbus has four types of address: Coil, Discrete Input, Input Register and Holding Register.
Modbus has two address description method: standard and extend. Modbus has two address description method: standard and extend.
@@ -26,8 +26,8 @@ Type | Standard | Extend |
---------------- | ----------- | ------------- | ---------------- | ----------- | ------------- |
Coil | 00001-09999 | 000001-065536 | Coil | 00001-09999 | 000001-065536 |
Discrete Input | 10001-19999 | 100001-165536 | Discrete Input | 10001-19999 | 100001-165536 |
Holding Register | 30001-39999 | 300001-365536 | Input Register | 30001-39999 | 300001-365536 |
Input Register | 40001-49999 | 400001-465536 | Holding Register | 40001-49999 | 400001-465536 |
Standard and Extend address description are all supported in Modbus.Net.Modbus. The only difference is don't write too large number in address. Standard and Extend address description are all supported in Modbus.Net.Modbus. The only difference is don't write too large number in address.
@@ -67,7 +67,7 @@ The number of SubAddress is from 0 to 15.
Caution: Modbus.Net.Modbus SubAddress has a giant difference towards standard Modbus. Caution: Modbus.Net.Modbus SubAddress has a giant difference towards standard Modbus.
Bit position from standard modbus is from last to first. But Modbus.Net is from first to last. Bit position from Modbus.Net is one less than standard modbus.
Standard Modbus Standard Modbus
@@ -77,4 +77,4 @@ Standard Modbus
Modbus.Net.Modbus Modbus.Net.Modbus
1 0 1 1 1 0 0 0 1 0 0 0 0 1 1 0 1 0 1 1 1 0 0 0 1 0 0 0 0 1 1 0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

View File

@@ -98,7 +98,7 @@ List<AddressUnit> addressUnits = new List<AddressUnit>
new AddressUnit() {Id = "1", Area = "V", Address = 3, CommunicationTag = "D2", DataType = typeof (float), Zoom = 1} new AddressUnit() {Id = "1", Area = "V", Address = 3, CommunicationTag = "D2", DataType = typeof (float), Zoom = 1}
}; };
TaskManager task = new TaskManager(10, 300, true); TaskManager task = new TaskManager(10, 300, true);
task.AddMachine(new SiemensMachine(SiemensType.Tcp, "192.168.3.11",SiemensMachineModel.S7_300, addressUnits, task.AddMachine(new SiemensMachine(SiemensType.Tcp, "192.168.3.11", SiemensMachineModel.S7_300, addressUnits,
true, 2, 0)); true, 2, 0));
task.ReturnValues += (returnValues) => task.ReturnValues += (returnValues) =>
{ {
@@ -373,17 +373,17 @@ public class ModbusTcpProtocal : ModbusProtocal
``` ```
"abstract" keyword is optional because if user can use this protocal don't write abstract. "abstract" keyword is optional because if user can use this protocal don't write abstract.
Second: Extend ProtocalUnit, InputStruct and OutputStruct. Second: Extend ProtocalUnit, IInputStruct and IOutputStruct.
```C# ```C#
public class ReadDataModbusProtocal : ProtocalUnit public class ReadDataModbusProtocal : ProtocalUnit
{ {
public override byte[] Format(InputStruct message) public override byte[] Format(IInputStruct message)
{ {
var r_message = (ReadDataModbusInputStruct)message; var r_message = (ReadDataModbusInputStruct)message;
return Format(r_message.SlaveAddress, r_message.FunctionCode, r_message.StartAddress, r_message.GetCount); return Format(r_message.SlaveAddress, r_message.FunctionCode, r_message.StartAddress, r_message.GetCount);
} }
public override OutputStruct Unformat(byte[] messageBytes, ref int pos) public override IOutputStruct Unformat(byte[] messageBytes, ref int pos)
{ {
byte slaveAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); byte slaveAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
byte functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); byte functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
@@ -394,8 +394,14 @@ public class ReadDataModbusProtocal : ProtocalUnit
} }
} }
``` ```
There are two types of ProtocalUnit: ProtocalUnit and SpecialProtocalUnit. There is another interface called ISpecialProtocalUnit.
If you see the implementation, you will find that there are no differences between ProtocalUnit and SpecialProtocalUnit. But actually there is a difference between them: SpecialProtocalUnit will not call ProtocalLinkerBytesExtend. If you don't want some protocals to call the ProtocalLinkerBytesExtend, extend those protocals from SpecialProtocalUnit. If you add ISpecialProtocalUnit to ProtocalUnit, then the protocal will not run BytesExtend and BytesDecact.
```C#
internal class CreateReferenceSiemensProtocal : ProtocalUnit, ISpecialProtocalUnit
{
...
}
```
2.Implement Protocal based ProtocalLinker. (ModbusTcpProtocalLinker) 2.Implement Protocal based ProtocalLinker. (ModbusTcpProtocalLinker)
ProtocalLinker connect the Protocal to the BaseConnector, so that byte array can be sended using some specific way like Ethenet. ProtocalLinker connect the Protocal to the BaseConnector, so that byte array can be sended using some specific way like Ethenet.

View File

@@ -399,7 +399,7 @@ namespace Modbus.Net
var temp = data[pos]; var temp = data[pos];
for (var i = 0; i < 8; i++) for (var i = 0; i < 8; i++)
{ {
t[i] = temp%2 > 0; t[7 - i] = temp % 2 > 0;
temp /= 2; temp /= 2;
} }
pos += 1; pos += 1;
@@ -442,7 +442,17 @@ namespace Modbus.Net
/// <returns></returns> /// <returns></returns>
public virtual bool GetBit(byte[] number, ref int pos, ref int subPos) public virtual bool GetBit(byte[] number, ref int pos, ref int subPos)
{ {
return GetBit(number[pos], ref pos, ref subPos); if (subPos < 0 && subPos > 7) throw new IndexOutOfRangeException();
var tspos = subPos;
var tpos = pos;
var bit = GetBit(number[pos], ref tpos, ref tspos);
subPos += 1;
if (subPos > 7)
{
pos++;
subPos = 0;
}
return bit;
} }
/// <summary> /// <summary>
@@ -827,14 +837,14 @@ namespace Modbus.Net
var creation = 0; var creation = 0;
if (setBit) if (setBit)
{ {
for (var i = 7; i >= 0; i--) for (var i = 0; i <= 7; i++)
{ {
creation *= 2; creation *= 2;
if (i == subPos) creation++; if (i == subPos) creation++;
} }
return (byte) (number | creation); return (byte) (number | creation);
} }
for (var i = 7; i >= 0; i--) for (var i = 0; i <= 7; i++)
{ {
creation *= 2; creation *= 2;
if (i != subPos) creation++; if (i != subPos) creation++;
@@ -1006,29 +1016,13 @@ namespace Modbus.Net
public override bool GetBit(byte[] number, ref int pos, ref int subPos) public override bool GetBit(byte[] number, ref int pos, ref int subPos)
{ {
if (subPos < 0 && subPos > 7) throw new IndexOutOfRangeException(); return GetBit(number[pos], ref pos, ref subPos);
var tspos = 7 - subPos;
var tpos = pos;
var bit = GetBit(number[pos], ref tpos, ref tspos);
subPos += 1;
if (subPos > 7)
{
pos++;
subPos = 0;
}
return bit;
} }
public override bool[] GetBits(byte[] data, ref int pos) public override bool[] GetBits(byte[] data, ref int pos)
{ {
var t = new bool[8]; var t = base.GetBits(data, ref pos);
var temp = data[pos]; Array.Reverse(t);
for (var i = 0; i < 8; i++)
{
t[7 - i] = temp%2 > 0;
temp /= 2;
}
pos += 1;
return t; return t;
} }

View File

@@ -1,53 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Modbus.Net.Tests
{
public sealed class AddressMaker
{
public TestAreas TestAreas { get; set; }
public TestAddresses TestAddresses { get; set; }
private AddressFormater AddressFormater { get; set; }
private AddressTranslator AddressTranslator { get; set; }
public List<AddressUnit> MakeAddresses(string areaKey, string addressKey, bool isRead)
{
var combinedAddress = new List<string>();
foreach (var area in TestAreas[areaKey])
{
foreach (var address in TestAddresses[addressKey])
{
for (double currentAddress = address.Item1, i = 0;
i < address.Item2;
currentAddress +=
ValueHelper.Instance.ByteLength[address.Item3.FullName]/
AddressTranslator.GetAreaByteLength(area), i++)
{
combinedAddress.Add(AddressFormater.FormatAddress(area, (int) currentAddress, (int)
((currentAddress - (int) currentAddress)/
(ValueHelper.Instance.ByteLength[address.Item3.FullName]/
AddressTranslator.GetAreaByteLength(area)))));
}
}
}
return combinedAddress.Select(p =>
{
var translateAns = AddressTranslator.AddressTranslate(p, isRead);
return new AddressUnit()
{
Area = translateAns.AreaString,
Address = translateAns.Address,
SubAddress = translateAns.SubAddress,
Id = p,
CommunicationTag = p
};
}).ToList();
}
}
}

View File

@@ -1,164 +1,15 @@
using System; using System;
using System.Collections; using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Modbus.Net.Tests namespace Modbus.Net.Tests
{ {
public sealed class TestAddresses [TestClass]
public class BaseTest
{ {
private Dictionary<string, Tuple<double, int, Type>[]> Addresses { get; } /*[TestMethod]
public void TestMethod1()
public Tuple<double, int, Type>[] this[string index]
{ {
get { return Addresses[index]; }
set
{
if (!Addresses.ContainsKey(index))
{
Addresses.Add(index, value);
}
else
{
Addresses[index] = value;
}
}
} }
*/
public TestAddresses(Dictionary<string, Tuple<double, int, Type>[]> addresses)
{
Addresses = addresses.ToDictionary(address=>address.Key, address=>address.Value);
}
public IEnumerable<string> Keys => Addresses.Keys.AsEnumerable();
public IEnumerable<Tuple<double, int, Type>[]> Values => Addresses.Values.AsEnumerable();
}
public sealed class TestAreas
{
private Dictionary<string, string[]> Areas { get; }
public string[] this[string index]
{
get { return Areas[index]; }
set
{
if (!Areas.ContainsKey(index))
{
Areas.Add(index, value);
}
else
{
Areas[index] = value;
}
}
}
public TestAreas(Dictionary<string, string[]> addresses)
{
Areas = addresses.ToDictionary(address => address.Key, address => address.Value);
}
public IEnumerable<string> Keys => Areas.Keys.AsEnumerable();
public IEnumerable<string[]> Values => Areas.Values.AsEnumerable();
}
public sealed class BaseTest
{
public static TestAreas TestAreasModbus => new TestAreas(new Dictionary<string, string[]>
{
{
"Coil",new []{"0X", "1X"}
},
{
"Register", new [] {"3X", "4X"}
}
});
public static TestAddresses TestAddresses => new TestAddresses(new Dictionary<string, Tuple<double, int, Type>[]>
{
{
"Coil.Single.Min", new []
{
new Tuple<double, int, Type>(0, 1, typeof(bool))
}
},
{
"Coil.Single.Normal", new[]
{
new Tuple<double, int, Type>(100, 1, typeof(bool))
}
},
{
"Coil.Single.MaxOverFlow", new[]
{
new Tuple<double, int, Type>(100000, 1, typeof(bool))
}
},
{
"Coil.Multi.Normal", new[]
{
new Tuple<double, int, Type>(0, 30, typeof(bool))
}
},
{
"Register.Single.Short", new[]
{
new Tuple<double, int, Type>(0, 1, typeof(ushort))
}
},
{
"Register.Continus.Short", new[]
{
new Tuple<double, int, Type>(0, 10, typeof(ushort))
}
},
{
"Register.Continus.Byte", new[]
{
new Tuple<double, int, Type>(0, 10, typeof(byte))
}
},
{
"Register.Continus.Int", new[]
{
new Tuple<double, int, Type>(0, 10, typeof(uint))
}
},
{
"Register.Continus.Bit", new []
{
new Tuple<double, int, Type>(0.5, 8, typeof(bool))
}
},
{
"Register.Duplicate.Short", new []
{
new Tuple<double, int, Type>(0, 10, typeof(ushort)),
new Tuple<double, int, Type>(15, 25, typeof(ushort)),
new Tuple<double, int, Type>(50, 20, typeof(ushort))
}
},
{
"Register.Cross.Short", new []
{
new Tuple<double, int, Type>(0, 10, typeof(ushort)),
new Tuple<double, int, Type>(5, 10, typeof(ushort)),
new Tuple<double, int, Type>(10, 10, typeof(ushort))
}
},
{
"Register.Duplicate.Multi", new []
{
new Tuple<double, int, Type>(0, 10, typeof(byte)),
new Tuple<double, int, Type>(20, 10, typeof(byte)),
new Tuple<double, int, Type>(30, 16, typeof(bool))
}
},
});
} }
} }

View File

@@ -1,177 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Modbus.Net.Modbus;
namespace Modbus.Net.Tests
{
[TestClass]
public class CommunicationTest
{
protected AddressMaker AddressMaker = new AddressMaker()
{
TestAreas = BaseTest.TestAreasModbus,
TestAddresses = BaseTest.TestAddresses
};
protected BaseMachine Machine = new ModbusMachine(ModbusType.Tcp, "192.168.3.12", null, true, 2, 0);
[TestMethod]
public async Task CoilSingle()
{
var addresses = AddressMaker.MakeAddresses("Coil", "Coil.Single.Normal", false);
Machine.AddressCombiner = new AddressCombinerNumericJump(20, Machine.AddressTranslator);
Machine.GetAddresses = addresses;
var ans = await Machine.SetDatasAsync(MachineSetDataType.Address, new Dictionary<string, double>()
{
{
"0X 100", 1
},
{
"1X 100", 1
}
});
var addresses2 = AddressMaker.MakeAddresses("Coil", "Coil.Signle.Normal", true);
Machine.AddressCombiner = new AddressCombinerNumericJump(20, Machine.AddressTranslator);
Machine.GetAddresses = addresses2;
var ans2 = await Machine.GetDatasAsync(MachineGetDataType.Address);
Assert.AreEqual(ans2["0X 100"], 1);
Assert.AreEqual(ans2["1X 100"], 1);
}
[TestMethod]
public async Task CoilMuiltiRead()
{
var addresses = AddressMaker.MakeAddresses("Coil", "Coil.Multi.Normal", false);
Machine.AddressCombiner = new AddressCombinerNumericJump(20, Machine.AddressTranslator);
Machine.GetAddresses = addresses;
var ans = await Machine.SetDatasAsync(MachineSetDataType.Address, new Dictionary<string, double>()
{
{
"0X 3", 1
},
{
"0X 4", 1
},
{
"0X 16", 1
},
{
"0X 22", 1
},
{
"1X 3", 1
},
{
"1X 4", 1
},
{
"1X 16", 1
},
{
"1X 22", 1
}
});
var addresses2 = AddressMaker.MakeAddresses("Coil", "Coil.Multi.Normal", true);
Machine.AddressCombiner = new AddressCombinerNumericJump(20, Machine.AddressTranslator);
Machine.GetAddresses = addresses;
var ans2 = await Machine.GetDatasAsync(MachineGetDataType.Address);
Assert.AreEqual(ans2["0X 3"], 1);
Assert.AreEqual(ans2["0X 4"], 1);
Assert.AreEqual(ans2["0X 16"], 1);
Assert.AreEqual(ans2["0X 22"], 1);
Assert.AreEqual(ans2["0X 7"], 0);
Assert.AreEqual(ans2["0X 29"], 0);
Assert.AreEqual(ans2["1X 3"], 1);
Assert.AreEqual(ans2["1X 4"], 1);
Assert.AreEqual(ans2["1X 16"], 1);
Assert.AreEqual(ans2["1X 22"], 1);
Assert.AreEqual(ans2["1X 7"], 0);
Assert.AreEqual(ans2["1X 29"], 0);
}
[TestMethod]
public async Task RegisterSingleRead()
{
var addresses = AddressMaker.MakeAddresses("Register", "Register.Single.Short", false);
Machine.AddressCombiner = new AddressCombinerNumericJump(20, Machine.AddressTranslator);
Machine.GetAddresses = addresses;
var ans = await Machine.SetDatasAsync(MachineSetDataType.Address, new Dictionary<string, double>()
{
{
"3X 0", 32767
},
{
"4X 0", 32767
}
});
var addresses2 = AddressMaker.MakeAddresses("Register", "Register.Single.Short", true);
Machine.AddressCombiner = new AddressCombinerNumericJump(20, Machine.AddressTranslator);
Machine.GetAddresses = addresses;
var ans2 = await Machine.GetDatasAsync(MachineGetDataType.Address);
Assert.AreEqual(ans2["3X 0"], 32767);
Assert.AreEqual(ans2["4X 0"], 32767);
}
[TestMethod]
public async Task RegistertMultiRead()
{
var addresses = AddressMaker.MakeAddresses("Register", "Register.Duplicate.Short", false);
Machine.AddressCombiner = new AddressCombinerNumericJump(20, Machine.AddressTranslator);
Machine.GetAddresses = addresses;
var ans = await Machine.SetDatasAsync(MachineSetDataType.Address, new Dictionary<string, double>()
{
{
"3X 4", 17
},
{
"3X 7", 20
},
{
"3X 17", 5255
},
{
"3X 18", 3019
},
{
"3X 55", 192
},
{
"4X 4", 18
},
{
"4X 7", 21
},
{
"4X 17", 5256
},
{
"4X 18", 3020
},
{
"4X 55", 193
}
});
var addresses2 = AddressMaker.MakeAddresses("Register", "Register.Duplicate.Short", true);
Machine.AddressCombiner = new AddressCombinerNumericJump(20, Machine.AddressTranslator);
Machine.GetAddresses = addresses;
var ans2 = await Machine.GetDatasAsync(MachineGetDataType.Address);
Assert.AreEqual(ans2["3X 4"], 17);
Assert.AreEqual(ans2["3X 7"], 20);
Assert.AreEqual(ans2["3X 17"], 5255);
Assert.AreEqual(ans2["3X 18"], 3019);
Assert.AreEqual(ans2["3X 55"], 192);
Assert.AreEqual(ans2["4X 4"], 18);
Assert.AreEqual(ans2["4X 7"], 21);
Assert.AreEqual(ans2["4X 17"], 5256);
Assert.AreEqual(ans2["4X 18"], 3020);
Assert.AreEqual(ans2["4X 55"], 193);
}
}
}

View File

@@ -52,10 +52,10 @@
</Otherwise> </Otherwise>
</Choose> </Choose>
<ItemGroup> <ItemGroup>
<Compile Include="AddressMaker.cs" />
<Compile Include="BaseTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="CommunicationTest.cs" /> <Compile Include="ModbusTest.cs" />
<Compile Include="SiemensTest.cs" />
<Compile Include="BaseTest.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\Modbus.Net\Modbus.Net.Modbus\Modbus.Net.Modbus.csproj"> <ProjectReference Include="..\..\Modbus.Net\Modbus.Net.Modbus\Modbus.Net.Modbus.csproj">

View File

@@ -0,0 +1,208 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Modbus.Net.Modbus;
namespace Modbus.Net.Tests
{
[TestClass]
public class ModbusTest
{
private BaseMachine _modbusTcpMachine;
[TestInitialize]
public void Init()
{
_modbusTcpMachine = new ModbusMachine(ModbusType.Tcp, "192.168.3.10", null, true, 2, 0);
}
[TestMethod]
public async Task ModbusCoilSingle()
{
var addresses = new List<AddressUnit>
{
new AddressUnit
{
Id = "0",
Area = "0X",
Address = 1,
SubAddress = 0,
CommunicationTag = "A1",
DataType = typeof(bool)
}
};
_modbusTcpMachine.GetAddresses = addresses;
await _modbusTcpMachine.SetDatasAsync(MachineSetDataType.Address, new Dictionary<string, double>()
{
{
"0X 1.0", 1
}
});
var ans = await _modbusTcpMachine.GetDatasAsync(MachineGetDataType.Address);
Assert.AreEqual(ans["0X 1.0"].PlcValue, 1);
}
[TestMethod]
public async Task ModbusDInputSingle()
{
var addresses = new List<AddressUnit>
{
new AddressUnit
{
Id = "0",
Area = "1X",
Address = 1,
SubAddress = 0,
CommunicationTag = "A1",
DataType = typeof(bool)
}
};
_modbusTcpMachine.GetAddresses = addresses;
var ans = await _modbusTcpMachine.GetDatasAsync(MachineGetDataType.Address);
Assert.AreEqual(ans["1X 1.0"].PlcValue, 0);
}
[TestMethod]
public async Task ModbusIRegSingle()
{
var addresses = new List<AddressUnit>
{
new AddressUnit
{
Id = "0",
Area = "3X",
Address = 1,
SubAddress = 0,
CommunicationTag = "A1",
DataType = typeof(ushort)
}
};
_modbusTcpMachine.GetAddresses = addresses;
var ans = await _modbusTcpMachine.GetDatasAsync(MachineGetDataType.Address);
Assert.AreEqual(ans["3X 1.0"].PlcValue, 0);
}
[TestMethod]
public async Task ModbusRegSingle()
{
var addresses = new List<AddressUnit>
{
new AddressUnit
{
Id = "0",
Area = "4X",
Address = 1,
SubAddress = 0,
CommunicationTag = "A1",
DataType = typeof(ushort)
}
};
_modbusTcpMachine.GetAddresses = addresses;
await _modbusTcpMachine.SetDatasAsync(MachineSetDataType.Address, new Dictionary<string, double>()
{
{
"4X 1", 31125
}
});
var ans = await _modbusTcpMachine.GetDatasAsync(MachineGetDataType.Address);
Assert.AreEqual(ans["4X 1.0"].PlcValue, 31125);
}
[TestMethod]
public async Task ModbusRegMultiple()
{
var addresses = new List<AddressUnit>
{
new AddressUnit
{
Id = "0",
Area = "4X",
Address = 2,
SubAddress = 0,
CommunicationTag = "A1",
DataType = typeof(ushort)
},
new AddressUnit
{
Id = "1",
Area = "4X",
Address = 3,
SubAddress = 0,
CommunicationTag = "A2",
DataType = typeof(ushort)
},
new AddressUnit
{
Id = "2",
Area = "4X",
Address = 4,
SubAddress = 0,
CommunicationTag = "A3",
DataType = typeof(ushort)
},
new AddressUnit
{
Id = "3",
Area = "4X",
Address = 5,
SubAddress = 0,
CommunicationTag = "A4",
DataType = typeof(ushort)
},
new AddressUnit
{
Id = "4",
Area = "4X",
Address = 6,
SubAddress = 0,
CommunicationTag = "A5",
DataType = typeof(uint)
},
new AddressUnit
{
Id = "5",
Area = "4X",
Address = 8,
SubAddress = 0,
CommunicationTag = "A6",
DataType = typeof(uint)
}
};
_modbusTcpMachine.GetAddresses = addresses;
await _modbusTcpMachine.SetDatasAsync(MachineSetDataType.CommunicationTag, new Dictionary<string, double>()
{
{
"A1", 70
},
{
"A2", 71
},
{
"A3", 72
},
{
"A4", 73
},
{
"A5", 717870
},
{
"A6", 717871
},
});
var ans = await _modbusTcpMachine.GetDatasAsync(MachineGetDataType.CommunicationTag);
Assert.AreEqual(ans["A1"].PlcValue, 70);
Assert.AreEqual(ans["A2"].PlcValue, 71);
Assert.AreEqual(ans["A3"].PlcValue, 72);
Assert.AreEqual(ans["A4"].PlcValue, 73);
Assert.AreEqual(ans["A5"].PlcValue, 717870);
Assert.AreEqual(ans["A6"].PlcValue, 717871);
}
}
}

View File

@@ -0,0 +1,216 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Modbus.Net.Modbus;
using Modbus.Net.Siemens;
namespace Modbus.Net.Tests
{
[TestClass]
public class SiemensTest
{
private BaseMachine _siemensTcpMachine;
[TestInitialize]
public void Init()
{
_siemensTcpMachine = new SiemensMachine(SiemensType.Tcp, "192.168.3.10", SiemensMachineModel.S7_1200, null, true, 2, 0);
}
[TestMethod]
public async Task SiemensCoilSingle()
{
var addresses = new List<AddressUnit>
{
new AddressUnit
{
Id = "0",
Area = "Q",
Address = 0,
SubAddress = 0,
CommunicationTag = "A1",
DataType = typeof(bool)
}
};
_siemensTcpMachine.GetAddresses = addresses;
await _siemensTcpMachine.SetDatasAsync(MachineSetDataType.Address, new Dictionary<string, double>()
{
{
"Q 0.0", 1
}
});
var ans = await _siemensTcpMachine.GetDatasAsync(MachineGetDataType.Address);
Assert.AreEqual(ans["Q 0.0"].PlcValue, 1);
}
[TestMethod]
public async Task SiemensDInputSingle()
{
var addresses = new List<AddressUnit>
{
new AddressUnit
{
Id = "0",
Area = "I",
Address = 0,
SubAddress = 0,
CommunicationTag = "A1",
DataType = typeof(bool)
}
};
_siemensTcpMachine.GetAddresses = addresses;
var ans = await _siemensTcpMachine.GetDatasAsync(MachineGetDataType.Address);
Assert.AreEqual(ans["I 0.0"].PlcValue, 0);
}
[TestMethod]
public async Task SiemensMSingle()
{
var addresses = new List<AddressUnit>
{
new AddressUnit
{
Id = "0",
Area = "M",
Address = 0,
SubAddress = 0,
CommunicationTag = "A1",
DataType = typeof(ushort)
}
};
_siemensTcpMachine.GetAddresses = addresses;
await _siemensTcpMachine.SetDatasAsync(MachineSetDataType.Address, new Dictionary<string, double>()
{
{
"M 0", 31125
}
});
var ans = await _siemensTcpMachine.GetDatasAsync(MachineGetDataType.Address);
Assert.AreEqual(ans["M 0.0"].PlcValue, 31125);
}
[TestMethod]
public async Task SiemensDbSingle()
{
var addresses = new List<AddressUnit>
{
new AddressUnit
{
Id = "0",
Area = "DB2",
Address = 0,
SubAddress = 0,
CommunicationTag = "A1",
DataType = typeof(ushort)
}
};
_siemensTcpMachine.GetAddresses = addresses;
await _siemensTcpMachine.SetDatasAsync(MachineSetDataType.Address, new Dictionary<string, double>()
{
{
"DB2 0.0", 31125
}
});
var ans = await _siemensTcpMachine.GetDatasAsync(MachineGetDataType.Address);
Assert.AreEqual(ans["DB2 0.0"].PlcValue, 31125);
}
[TestMethod]
public async Task SiemensDbMultiple()
{
var addresses = new List<AddressUnit>
{
new AddressUnit
{
Id = "0",
Area = "DB2",
Address = 2,
SubAddress = 0,
CommunicationTag = "A1",
DataType = typeof(ushort)
},
new AddressUnit
{
Id = "1",
Area = "DB2",
Address = 4,
SubAddress = 0,
CommunicationTag = "A2",
DataType = typeof(ushort)
},
new AddressUnit
{
Id = "2",
Area = "DB2",
Address = 6,
SubAddress = 0,
CommunicationTag = "A3",
DataType = typeof(ushort)
},
new AddressUnit
{
Id = "3",
Area = "DB2",
Address = 8,
SubAddress = 0,
CommunicationTag = "A4",
DataType = typeof(ushort)
},
new AddressUnit
{
Id = "4",
Area = "DB2",
Address = 10,
SubAddress = 0,
CommunicationTag = "A5",
DataType = typeof(uint)
},
new AddressUnit
{
Id = "5",
Area = "DB2",
Address = 14,
SubAddress = 0,
CommunicationTag = "A6",
DataType = typeof(uint)
}
};
_siemensTcpMachine.GetAddresses = addresses;
await _siemensTcpMachine.SetDatasAsync(MachineSetDataType.CommunicationTag, new Dictionary<string, double>()
{
{
"A1", 70
},
{
"A2", 71
},
{
"A3", 72
},
{
"A4", 73
},
{
"A5", 717870
},
{
"A6", 717871
},
});
var ans = await _siemensTcpMachine.GetDatasAsync(MachineGetDataType.CommunicationTag);
Assert.AreEqual(ans["A1"].PlcValue, 70);
Assert.AreEqual(ans["A2"].PlcValue, 71);
Assert.AreEqual(ans["A3"].PlcValue, 72);
Assert.AreEqual(ans["A4"].PlcValue, 73);
Assert.AreEqual(ans["A5"].PlcValue, 717870);
Assert.AreEqual(ans["A6"].PlcValue, 717871);
}
}
}