Files
2026-04-04 17:25:15 +08:00

321 lines
12 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Modbus.Net.Modbus;
using AddressUnit = Modbus.Net.AddressUnit<string, int, int>;
namespace Modbus.Net.Tests
{
/// <summary>
/// Modbus 协议测试类
/// 测试 Modbus TCP/RTU/ASCII 三种协议的读写功能
/// </summary>
[TestClass]
public class ModbusTest
{
// Modbus TCP 机器实例
private BaseMachine<string, string>? _modbusTcpMachine;
// Modbus RTU 机器实例
private BaseMachine<string, string>? _modbusRtuMachine;
// Modbus ASCII 机器实例
private BaseMachine<string, string>? _modbusAsciiMachine;
// 测试机器 IP 地址
private string _machineIp = "10.10.18.251";
// 测试串口 1
private string _machineCom = "COM1";
// 测试串口 2
private string _machineCom2 = "COM3";
/// <summary>
/// 测试初始化方法
/// 在每个测试方法执行前运行
/// </summary>
[TestInitialize]
public void Init()
{
// 创建 Modbus TCP 机器实例
_modbusTcpMachine = new ModbusMachine<string, string>("1", "", ModbusType.Tcp, _machineIp, null, true, 2, 0, Endian.BigEndianLsb);
// 创建 Modbus RTU 机器实例
_modbusRtuMachine = new ModbusMachine<string, string>("2", "", ModbusType.Rtu, _machineCom, null, true, 2, 0, Endian.BigEndianLsb);
// 创建 Modbus ASCII 机器实例
_modbusAsciiMachine = new ModbusMachine<string, string>("3", "", ModbusType.Ascii, _machineCom2, null, true, 2, 0, Endian.BigEndianLsb);
}
/// <summary>
/// 测试单个线圈读写
/// 验证 Modbus TCP/RTU/ASCII 三种协议的线圈0X 区)读写功能
/// </summary>
[TestMethod]
public async Task ModbusCoilSingle()
{
Random r = new Random();
// 定义地址单元
var addresses = new List<AddressUnit>
{
new AddressUnit
{
Id = "0",
Area = "0X",
Address = 1,
SubAddress = 0,
CommunicationTag = "A1",
DataType = typeof(bool)
}
};
// 生成随机值0 或 1
var dic1 = new Dictionary<string, double>()
{
{
"0X 1.0", r.Next(0, 2)
}
};
// 设置三种协议的地址列表
_modbusTcpMachine!.GetAddresses = addresses;
_modbusAsciiMachine!.GetAddresses = addresses;
_modbusRtuMachine!.GetAddresses = addresses;
// 分别通过三种协议写入数据
await _modbusTcpMachine.SetDatasAsync(MachineDataType.Address, dic1);
await _modbusAsciiMachine.SetDatasAsync(MachineDataType.Address, dic1);
await _modbusRtuMachine.SetDatasAsync(MachineDataType.Address, dic1);
// 分别通过三种协议读取数据
var ans = await _modbusTcpMachine.GetDatasAsync(MachineDataType.Address);
var ans2 = await _modbusRtuMachine.GetDatasAsync(MachineDataType.Address);
var ans3 = await _modbusAsciiMachine.GetDatasAsync(MachineDataType.Address);
// 验证三种协议读取的值与写入的值一致
Assert.AreEqual(ans.Datas?["0X 1.0"].DeviceValue, dic1["0X 1.0"]);
Assert.AreEqual(ans2.Datas?["0X 1.0"].DeviceValue, dic1["0X 1.0"]);
Assert.AreEqual(ans3.Datas?["0X 1.0"].DeviceValue, dic1["0X 1.0"]);
}
/// <summary>
/// 测试单个离散输入读取
/// 验证 Modbus TCP/RTU/ASCII 三种协议的离散输入1X 区)读取功能
/// 离散输入为只读
/// </summary>
[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;
_modbusRtuMachine!.GetAddresses = addresses;
_modbusAsciiMachine!.GetAddresses = addresses;
// 分别通过三种协议读取数据
var ans = await _modbusTcpMachine.GetDatasAsync(MachineDataType.Address);
var ans2 = await _modbusRtuMachine.GetDatasAsync(MachineDataType.Address);
var ans3 = await _modbusAsciiMachine.GetDatasAsync(MachineDataType.Address);
// 验证三种协议读取的值都为 0默认值
Assert.AreEqual(ans.Datas?["1X 1.0"].DeviceValue, 0);
Assert.AreEqual(ans2.Datas?["1X 1.0"].DeviceValue, 0);
Assert.AreEqual(ans3.Datas?["1X 1.0"].DeviceValue, 0);
}
/// <summary>
/// 测试单个输入寄存器读取
/// 验证 Modbus TCP/RTU/ASCII 三种协议的输入寄存器3X 区)读取功能
/// 输入寄存器为只读
/// </summary>
[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;
_modbusRtuMachine!.GetAddresses = addresses;
_modbusAsciiMachine!.GetAddresses = addresses;
// 分别通过三种协议读取数据
var ans = await _modbusTcpMachine.GetDatasAsync(MachineDataType.Address);
var ans2 = await _modbusRtuMachine.GetDatasAsync(MachineDataType.Address);
var ans3 = await _modbusAsciiMachine.GetDatasAsync(MachineDataType.Address);
// 验证三种协议读取的值都为 0默认值
Assert.AreEqual(ans.Datas?["3X 1.0"].DeviceValue, 0);
Assert.AreEqual(ans2.Datas?["3X 1.0"].DeviceValue, 0);
Assert.AreEqual(ans3.Datas?["3X 1.0"].DeviceValue, 0);
}
/// <summary>
/// 测试单个保持寄存器读写
/// 验证 Modbus TCP/RTU/ASCII 三种协议的保持寄存器4X 区)读写功能
/// </summary>
[TestMethod]
public async Task ModbusRegSingle()
{
Random r = new Random();
// 定义地址单元
var addresses = new List<AddressUnit>
{
new AddressUnit
{
Id = "0",
Area = "4X",
Address = 1,
SubAddress = 0,
CommunicationTag = "A1",
DataType = typeof(ushort)
}
};
// 生成随机值0 到 UInt16.MaxValue
var dic1 = new Dictionary<string, double>()
{
{
"4X 1", r.Next(0, UInt16.MaxValue)
}
};
// 设置三种协议的地址列表
_modbusTcpMachine!.GetAddresses = addresses;
_modbusAsciiMachine!.GetAddresses = addresses;
_modbusRtuMachine!.GetAddresses = addresses;
// 分别通过三种协议写入数据
await _modbusTcpMachine.SetDatasAsync(MachineDataType.Address, dic1);
await _modbusAsciiMachine.SetDatasAsync(MachineDataType.Address, dic1);
await _modbusRtuMachine.SetDatasAsync(MachineDataType.Address, dic1);
// 分别通过三种协议读取数据
var ans = await _modbusTcpMachine.GetDatasAsync(MachineDataType.Address);
var ans2 = await _modbusRtuMachine.GetDatasAsync(MachineDataType.Address);
var ans3 = await _modbusAsciiMachine.GetDatasAsync(MachineDataType.Address);
// 验证三种协议读取的值与写入的值一致
Assert.AreEqual(ans.Datas?["4X 1.0"].DeviceValue, dic1["4X 1"]);
Assert.AreEqual(ans2.Datas?["4X 1.0"].DeviceValue, dic1["4X 1"]);
Assert.AreEqual(ans3.Datas?["4X 1.0"].DeviceValue, dic1["4X 1"]);
}
/// <summary>
/// 测试多个保持寄存器读写
/// 验证 Modbus TCP/RTU/ASCII 三种协议的多个保持寄存器4X 区)批量读写功能
/// </summary>
[TestMethod]
public async Task ModbusRegMultiple()
{
Random r = new Random();
// 定义多个地址单元
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)
}
};
// 生成随机值
var dic1 = new Dictionary<string, double>()
{
{ "4X 2", r.Next(0, UInt16.MaxValue) },
{ "4X 3", r.Next(0, UInt16.MaxValue) },
{ "4X 4", r.Next(0, UInt16.MaxValue) },
{ "4X 5", r.Next(0, UInt16.MaxValue) }
};
// 设置三种协议的地址列表
_modbusTcpMachine!.GetAddresses = addresses;
_modbusAsciiMachine!.GetAddresses = addresses;
_modbusRtuMachine!.GetAddresses = addresses;
// 分别通过三种协议写入数据
await _modbusTcpMachine.SetDatasAsync(MachineDataType.Address, dic1);
await _modbusAsciiMachine.SetDatasAsync(MachineDataType.Address, dic1);
await _modbusRtuMachine.SetDatasAsync(MachineDataType.Address, dic1);
// 分别通过三种协议读取数据
var ans = await _modbusTcpMachine.GetDatasAsync(MachineDataType.Address);
var ans2 = await _modbusRtuMachine.GetDatasAsync(MachineDataType.Address);
var ans3 = await _modbusAsciiMachine.GetDatasAsync(MachineDataType.Address);
// 验证三种协议读取的所有值与写入的值一致
Assert.AreEqual(ans.Datas?["4X 2.0"].DeviceValue, dic1["4X 2"]);
Assert.AreEqual(ans.Datas?["4X 3.0"].DeviceValue, dic1["4X 3"]);
Assert.AreEqual(ans.Datas?["4X 4.0"].DeviceValue, dic1["4X 4"]);
Assert.AreEqual(ans.Datas?["4X 5.0"].DeviceValue, dic1["4X 5"]);
Assert.AreEqual(ans2.Datas?["4X 2.0"].DeviceValue, dic1["4X 2"]);
Assert.AreEqual(ans2.Datas?["4X 3.0"].DeviceValue, dic1["4X 3"]);
Assert.AreEqual(ans2.Datas?["4X 4.0"].DeviceValue, dic1["4X 4"]);
Assert.AreEqual(ans2.Datas?["4X 5.0"].DeviceValue, dic1["4X 5"]);
Assert.AreEqual(ans3.Datas?["4X 2.0"].DeviceValue, dic1["4X 2"]);
Assert.AreEqual(ans3.Datas?["4X 3.0"].DeviceValue, dic1["4X 3"]);
Assert.AreEqual(ans3.Datas?["4X 4.0"].DeviceValue, dic1["4X 4"]);
Assert.AreEqual(ans3.Datas?["4X 5.0"].DeviceValue, dic1["4X 5"]);
}
}
}