using Microsoft.VisualStudio.TestTools.UnitTesting; using Modbus.Net.Modbus; using AddressUnit = Modbus.Net.AddressUnit; namespace Modbus.Net.Tests { /// /// Modbus 协议测试类 /// 测试 Modbus TCP/RTU/ASCII 三种协议的读写功能 /// [TestClass] public class ModbusTest { // Modbus TCP 机器实例 private BaseMachine? _modbusTcpMachine; // Modbus RTU 机器实例 private BaseMachine? _modbusRtuMachine; // Modbus ASCII 机器实例 private BaseMachine? _modbusAsciiMachine; // 测试机器 IP 地址 private string _machineIp = "10.10.18.251"; // 测试串口 1 private string _machineCom = "COM1"; // 测试串口 2 private string _machineCom2 = "COM3"; /// /// 测试初始化方法 /// 在每个测试方法执行前运行 /// [TestInitialize] public void Init() { // 创建 Modbus TCP 机器实例 _modbusTcpMachine = new ModbusMachine("1", "", ModbusType.Tcp, _machineIp, null, true, 2, 0, Endian.BigEndianLsb); // 创建 Modbus RTU 机器实例 _modbusRtuMachine = new ModbusMachine("2", "", ModbusType.Rtu, _machineCom, null, true, 2, 0, Endian.BigEndianLsb); // 创建 Modbus ASCII 机器实例 _modbusAsciiMachine = new ModbusMachine("3", "", ModbusType.Ascii, _machineCom2, null, true, 2, 0, Endian.BigEndianLsb); } /// /// 测试单个线圈读写 /// 验证 Modbus TCP/RTU/ASCII 三种协议的线圈(0X 区)读写功能 /// [TestMethod] public async Task ModbusCoilSingle() { Random r = new Random(); // 定义地址单元 var addresses = new List { new AddressUnit { Id = "0", Area = "0X", Address = 1, SubAddress = 0, CommunicationTag = "A1", DataType = typeof(bool) } }; // 生成随机值(0 或 1) var dic1 = new Dictionary() { { "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"]); } /// /// 测试单个离散输入读取 /// 验证 Modbus TCP/RTU/ASCII 三种协议的离散输入(1X 区)读取功能 /// 离散输入为只读 /// [TestMethod] public async Task ModbusDInputSingle() { // 定义地址单元 var addresses = new List { 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); } /// /// 测试单个输入寄存器读取 /// 验证 Modbus TCP/RTU/ASCII 三种协议的输入寄存器(3X 区)读取功能 /// 输入寄存器为只读 /// [TestMethod] public async Task ModbusIRegSingle() { // 定义地址单元 var addresses = new List { 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); } /// /// 测试单个保持寄存器读写 /// 验证 Modbus TCP/RTU/ASCII 三种协议的保持寄存器(4X 区)读写功能 /// [TestMethod] public async Task ModbusRegSingle() { Random r = new Random(); // 定义地址单元 var addresses = new List { new AddressUnit { Id = "0", Area = "4X", Address = 1, SubAddress = 0, CommunicationTag = "A1", DataType = typeof(ushort) } }; // 生成随机值(0 到 UInt16.MaxValue) var dic1 = new Dictionary() { { "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"]); } /// /// 测试多个保持寄存器读写 /// 验证 Modbus TCP/RTU/ASCII 三种协议的多个保持寄存器(4X 区)批量读写功能 /// [TestMethod] public async Task ModbusRegMultiple() { Random r = new Random(); // 定义多个地址单元 var addresses = new List { 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() { { "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"]); } } }