@@ -0,0 +1,45 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace ModbusDemo.Device | |||
{ | |||
public interface IStreamResource : IDisposable | |||
{ | |||
int InfiniteTimeout { get; } | |||
/// <summary> | |||
/// Gets or sets the number of milliseconds before a timeout occurs when a read operation does not finish. | |||
/// </summary> | |||
int ReadTimeout { get; set; } | |||
/// <summary> | |||
/// Gets or sets the number of milliseconds before a timeout occurs when a write operation does not finish. | |||
/// </summary> | |||
int WriteTimeout { get; set; } | |||
/// <summary> | |||
/// Purges the receive buffer. | |||
/// </summary> | |||
void DiscardInBuffer(); | |||
/// <summary> | |||
/// Reads a number of bytes from the input buffer and writes those bytes into a byte array at the specified offset. | |||
/// </summary> | |||
/// <param name="buffer">The byte array to write the input to.</param> | |||
/// <param name="offset">The offset in the buffer array to begin writing.</param> | |||
/// <param name="count">The number of bytes to read.</param> | |||
/// <returns>The number of bytes read.</returns> | |||
int Read(byte[] buffer, int offset, int count); | |||
/// <summary> | |||
/// Writes a specified number of bytes to the port from an output buffer, starting at the specified offset. | |||
/// </summary> | |||
/// <param name="buffer">The byte array that contains the data to write to the port.</param> | |||
/// <param name="offset">The offset in the buffer array to begin writing.</param> | |||
/// <param name="count">The number of bytes to write.</param> | |||
void Write(byte[] buffer, int offset, int count); | |||
} | |||
} |
@@ -17,11 +17,14 @@ namespace ModbusDemo.Device | |||
private SerialPort _serialPort; | |||
//用于操作数据库 | |||
private ModbusDbContext _modbusDbContext; | |||
//TODO,修改 | |||
private SerialPortAdapter _portAdapter; | |||
public ModbusRTU(SerialPort serialPort, ModbusDbContext modbusDbContext) | |||
{ | |||
_serialPort = serialPort; | |||
_modbusDbContext = modbusDbContext; | |||
_portAdapter = new SerialPortAdapter(serialPort); | |||
} | |||
/// <summary> | |||
/// 用来发送读写线圈的指令 | |||
@@ -94,15 +97,24 @@ namespace ModbusDemo.Device | |||
} | |||
} | |||
//将操作失败的指令,插入数据库 | |||
string RequestStr = ByteArrayToString(sendByte); | |||
try | |||
{ | |||
//将操作失败的指令,插入数据库 | |||
string RequestStr = ByteArrayToString(sendByte); | |||
ModbusLog m = new ModbusLog(); | |||
m.OperationType = "读线圈"; | |||
m.ResponseData = ""; | |||
m.RequestData = RequestStr; | |||
_modbusDbContext.Add(m); | |||
_modbusDbContext.SaveChanges(); | |||
} | |||
catch (Exception) | |||
{ | |||
ModbusLog m = new ModbusLog(); | |||
m.OperationType = "读线圈"; | |||
m.ResponseData = ""; | |||
m.RequestData = RequestStr; | |||
_modbusDbContext.Add(m); | |||
_modbusDbContext.SaveChanges(); | |||
MessageBox.Show("0x15:数据库插入错误"); | |||
} | |||
return resultValue; | |||
} | |||
@@ -115,15 +127,24 @@ namespace ModbusDemo.Device | |||
/// <returns></returns> | |||
public bool[] ParseCoilresponse(byte[] sendByte, byte[] response, ushort numberOfPoints) | |||
{ | |||
//将操作的指令,插入数据库 | |||
string RequestStr = ByteArrayToString(sendByte); | |||
string responseStr = ByteArrayToString(response); | |||
ModbusLog m = new ModbusLog(); | |||
m.OperationType = "读线圈"; | |||
m.ResponseData = responseStr; | |||
m.RequestData = RequestStr; | |||
_modbusDbContext.Add(m); | |||
_modbusDbContext.SaveChanges(); | |||
try | |||
{ | |||
//将操作的指令,插入数据库 | |||
string RequestStr = ByteArrayToString(sendByte); | |||
string responseStr = ByteArrayToString(response); | |||
ModbusLog m = new ModbusLog(); | |||
m.OperationType = "读线圈"; | |||
m.ResponseData = responseStr; | |||
m.RequestData = RequestStr; | |||
_modbusDbContext.Add(m); | |||
_modbusDbContext.SaveChanges(); | |||
} | |||
catch (Exception) | |||
{ | |||
MessageBox.Show("0x15:数据库插入错误"); | |||
} | |||
//判断发送回来的数据是否正确 | |||
@@ -255,21 +276,29 @@ namespace ModbusDemo.Device | |||
} | |||
} | |||
//将操作的指令,插入数据库 | |||
string RequestStr = ByteArrayToString(sendByte); | |||
string responseStr = ByteArrayToString(response); | |||
ModbusLog m = new ModbusLog(); | |||
m.OperationType = "写线圈"; | |||
m.ResponseData = responseStr; | |||
m.RequestData = RequestStr; | |||
_modbusDbContext.Add(m); | |||
_modbusDbContext.SaveChanges(); | |||
//判断发送回来的数据是否正确 | |||
if (CheckData.CheckResponse(response)) | |||
try | |||
{ | |||
//将操作的指令,插入数据库 | |||
string RequestStr = ByteArrayToString(sendByte); | |||
string responseStr = ByteArrayToString(response); | |||
ModbusLog m = new ModbusLog(); | |||
m.OperationType = "写线圈"; | |||
m.ResponseData = responseStr; | |||
m.RequestData = RequestStr; | |||
_modbusDbContext.Add(m); | |||
_modbusDbContext.SaveChanges(); | |||
} | |||
catch (Exception) | |||
{ | |||
MessageBox.Show("0x15:数据库插入错误"); | |||
} | |||
//判断发送回来的数据是否正确 | |||
CheckData.CheckResponse(response); | |||
} | |||
/// <summary> | |||
@@ -347,12 +376,21 @@ namespace ModbusDemo.Device | |||
//将操作失败的指令,插入数据库 | |||
string RequestStr = ByteArrayToString(sendByte); | |||
ModbusLog m = new ModbusLog(); | |||
m.OperationType = "读寄存器"; | |||
m.ResponseData = ""; | |||
m.RequestData = RequestStr; | |||
_modbusDbContext.Add(m); | |||
_modbusDbContext.SaveChanges(); | |||
try | |||
{ | |||
ModbusLog m = new ModbusLog(); | |||
m.OperationType = "读寄存器"; | |||
m.ResponseData = ""; | |||
m.RequestData = RequestStr; | |||
_modbusDbContext.Add(m); | |||
_modbusDbContext.SaveChanges(); | |||
} | |||
catch (Exception) | |||
{ | |||
MessageBox.Show("0x15:数据库插入错误"); | |||
} | |||
return resultValue; | |||
@@ -367,15 +405,24 @@ namespace ModbusDemo.Device | |||
/// <returns></returns> | |||
public ushort[] ParseRegistersresponse(byte[] sendByte, byte[] response, ushort numberOfPoints) | |||
{ | |||
//将操作的指令,插入数据库 | |||
string RequestStr = ByteArrayToString(sendByte); | |||
string responseStr = ByteArrayToString(response); | |||
ModbusLog m = new ModbusLog(); | |||
m.OperationType = "读寄存器"; | |||
m.ResponseData = responseStr; | |||
m.RequestData = responseStr; | |||
_modbusDbContext.Add(m); | |||
_modbusDbContext.SaveChanges(); | |||
try | |||
{ | |||
//将操作的指令,插入数据库 | |||
string RequestStr = ByteArrayToString(sendByte); | |||
string responseStr = ByteArrayToString(response); | |||
ModbusLog m = new ModbusLog(); | |||
m.OperationType = "读寄存器"; | |||
m.ResponseData = responseStr; | |||
m.RequestData = RequestStr; | |||
_modbusDbContext.Add(m); | |||
_modbusDbContext.SaveChanges(); | |||
} | |||
catch (Exception) | |||
{ | |||
MessageBox.Show("0x15:数据库插入错误"); | |||
} | |||
//判断发送回来的数据是否正确 | |||
if (CheckData.CheckResponse(response)) | |||
@@ -479,16 +526,25 @@ namespace ModbusDemo.Device | |||
attempt++; | |||
} | |||
} | |||
try | |||
{ | |||
//将操作的指令,插入数据库 | |||
string RequestStr = ByteArrayToString(sendByte); | |||
string responseStr = ByteArrayToString(response); | |||
ModbusLog m = new ModbusLog(); | |||
m.OperationType = "写寄存器"; | |||
m.ResponseData = responseStr; | |||
m.RequestData = RequestStr; | |||
_modbusDbContext.Add(m); | |||
_modbusDbContext.SaveChanges(); | |||
} | |||
catch (Exception) | |||
{ | |||
//将操作的指令,插入数据库 | |||
string RequestStr = ByteArrayToString(sendByte); | |||
string responseStr = ByteArrayToString(response); | |||
ModbusLog m = new ModbusLog(); | |||
m.OperationType = "写寄存器"; | |||
m.ResponseData = responseStr; | |||
m.RequestData = RequestStr; | |||
_modbusDbContext.Add(m); | |||
_modbusDbContext.SaveChanges(); | |||
MessageBox.Show("0x15:数据库插入错误"); | |||
} | |||
//判断发送回来的数据是否正确 | |||
CheckData.CheckResponse(response); | |||
@@ -506,7 +562,7 @@ namespace ModbusDemo.Device | |||
if (byteArray == null || byteArray.Length == 0) | |||
return string.Empty; | |||
System.Text.StringBuilder sb = new System.Text.StringBuilder(); | |||
StringBuilder sb = new StringBuilder(); | |||
// 处理第一个元素(无前导空格) | |||
sb.Append(byteArray[0].ToString("X2")); | |||
@@ -0,0 +1,71 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Diagnostics; | |||
using System.IO.Ports; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace ModbusDemo.Device | |||
{ | |||
public class SerialPortAdapter:IStreamResource | |||
{ | |||
private string NewLine = Environment.NewLine; | |||
private SerialPort _serialPort; | |||
public SerialPortAdapter(SerialPort serialPort) | |||
{ | |||
Debug.Assert(serialPort != null, "Argument serialPort cannot be null."); | |||
_serialPort = serialPort; | |||
_serialPort.NewLine = NewLine; | |||
} | |||
public int InfiniteTimeout | |||
{ | |||
get { return SerialPort.InfiniteTimeout; } | |||
} | |||
public int ReadTimeout | |||
{ | |||
get { return _serialPort.ReadTimeout; } | |||
set { _serialPort.ReadTimeout = value; } | |||
} | |||
public int WriteTimeout | |||
{ | |||
get { return _serialPort.WriteTimeout; } | |||
set { _serialPort.WriteTimeout = value; } | |||
} | |||
public void DiscardInBuffer() | |||
{ | |||
_serialPort.DiscardInBuffer(); | |||
} | |||
public int Read(byte[] buffer, int offset, int count) | |||
{ | |||
return _serialPort.Read(buffer, offset, count); | |||
} | |||
public void Write(byte[] buffer, int offset, int count) | |||
{ | |||
_serialPort.Write(buffer, offset, count); | |||
} | |||
public void Dispose() | |||
{ | |||
Dispose(true); | |||
GC.SuppressFinalize(this); | |||
} | |||
protected virtual void Dispose(bool disposing) | |||
{ | |||
if (disposing) | |||
{ | |||
_serialPort?.Dispose(); | |||
_serialPort = null; | |||
} | |||
} | |||
} | |||
} |
@@ -6,8 +6,15 @@ | |||
<Nullable>disable</Nullable> | |||
<ImplicitUsings>enable</ImplicitUsings> | |||
<UseWPF>true</UseWPF> | |||
<ApplicationIcon>ModbusRTU_64x64.ico</ApplicationIcon> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<Content Include="ModbusRTU_64x64.ico"> | |||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||
</Content> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<PackageReference Include="MaterialDesignThemes" Version="5.2.1" /> | |||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.27" /> | |||
@@ -24,4 +31,8 @@ | |||
</None> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Folder Include="bin\Debug\net8.0-windows\" /> | |||
</ItemGroup> | |||
</Project> |
@@ -7,6 +7,9 @@ using System.Threading.Tasks; | |||
namespace ModbusDemo.Model | |||
{ | |||
/// <summary> | |||
/// 操作数据库的上下文 | |||
/// </summary> | |||
public class ModbusDbContext:DbContext | |||
{ | |||
protected ModbusDbContext() | |||
@@ -7,6 +7,9 @@ using System.Threading.Tasks; | |||
namespace ModbusDemo.Model | |||
{ | |||
/// <summary> | |||
/// 表的映射 | |||
/// </summary> | |||
public class ModbusLog | |||
{ | |||
//数据库主键 | |||
@@ -17,6 +20,7 @@ namespace ModbusDemo.Model | |||
//请求的字节信息 | |||
public string RequestData { get; set; } | |||
//返回的字节信息 | |||
public string ResponseData { get; set; } | |||
//操作的时间 | |||
@@ -9,7 +9,11 @@ namespace ModbusDemo.Uitls | |||
{ | |||
public static class CheckData | |||
{ | |||
/// <summary> | |||
/// 检测返回的数据格式是否正确 | |||
/// </summary> | |||
/// <param name="response"></param> | |||
/// <returns></returns> | |||
public static bool CheckResponse(byte[] response) | |||
{ | |||
if (response.Length == 0) | |||
@@ -88,8 +88,8 @@ | |||
Grid.Column="4" | |||
Width="80" | |||
Height="40" | |||
IsEnabled="{Binding IsEnable}" | |||
materialDesign:ButtonAssist.CornerRadius="20" | |||
IsEnabled="{Binding IsEnable}" | |||
Command="{Binding ReadCoilCmm}" | |||
Content="读取" | |||
Style="{StaticResource MaterialDesignRaisedDarkButton}"> | |||
@@ -154,16 +154,16 @@ | |||
<DataGrid ItemsSource="{Binding ModbusLogList}" AutoGenerateColumns="False" IsReadOnly="True" ColumnWidth="*"> | |||
<DataGrid.Columns> | |||
<!-- 操作类型列 --> | |||
<DataGridTextColumn Header="操作类型" Binding="{Binding OperationType}" Width="100" /> | |||
<DataGridTextColumn Width="100" Header="操作类型" Binding="{Binding OperationType}" /> | |||
<!-- 请求数据列 --> | |||
<DataGridTextColumn Header="请求数据" Binding="{Binding RequestData}" /> | |||
<DataGridTextColumn Header="请求数据" Binding="{Binding RequestData}" /> | |||
<!-- 响应数据列 --> | |||
<DataGridTextColumn Header="响应数据" Binding="{Binding ResponseData}" /> | |||
<!-- 操作时间列 --> | |||
<DataGridTextColumn Header="操作时间" Binding="{Binding Time, StringFormat='yyyy-MM-dd HH:mm:ss'}" Width="200"/> | |||
<DataGridTextColumn Width="200" Header="操作时间" Binding="{Binding Time, StringFormat='yyyy-MM-dd HH:mm:ss'}" /> | |||
</DataGrid.Columns> | |||
</DataGrid> | |||
</Grid> | |||
@@ -88,8 +88,8 @@ | |||
Grid.Column="4" | |||
Width="80" | |||
Height="40" | |||
IsEnabled="{Binding IsEnable}" | |||
materialDesign:ButtonAssist.CornerRadius="20" | |||
IsEnabled="{Binding IsEnable}" | |||
Command="{Binding ReadRegisterCmm}" | |||
Content="读取" | |||
Style="{StaticResource MaterialDesignRaisedDarkButton}"> | |||
@@ -142,8 +142,8 @@ | |||
Grid.Column="4" | |||
Width="80" | |||
Height="40" | |||
IsEnabled="{Binding IsEnable}" | |||
materialDesign:ButtonAssist.CornerRadius="20" | |||
IsEnabled="{Binding IsEnable}" | |||
Command="{Binding WriteRegisterCmm}" | |||
Content="写入" | |||
Style="{StaticResource MaterialDesignRaisedDarkButton}"> | |||
@@ -1,4 +1,6 @@ | |||
using Modbus.Device; | |||
using ModbusDemo.Model; | |||
using ModbusDemo.Uitls; | |||
using Prism.Commands; | |||
using Prism.Mvvm; | |||
using System; | |||
@@ -51,11 +53,12 @@ namespace ModbusDemo.VIewModel | |||
ReadOddRegisterCmm = new DelegateCommand(ReadOddRegister); | |||
_serialPort = serialPort; | |||
} | |||
/// <summary> | |||
/// 读1000个寄存器 | |||
/// </summary> | |||
private void ReadOddRegister() | |||
{ | |||
// 创建 Modbus RTU 主站 | |||
IModbusSerialMaster master = ModbusSerialMaster.CreateRtu(_serialPort); | |||
byte slaveId = 1; | |||
ushort totalRegisters = 1000; | |||
@@ -80,7 +83,7 @@ namespace ModbusDemo.VIewModel | |||
} | |||
catch (Exception ex) | |||
{ | |||
Console.WriteLine($"线程 {chunkIndex} 读取寄存器时出错: {ex.Message}"); | |||
MessageBox.Show($"线程 {chunkIndex} 读取寄存器时出错: {ex.Message}"); | |||
} | |||
}); | |||
} | |||
@@ -102,6 +105,150 @@ namespace ModbusDemo.VIewModel | |||
ReadResult = result.ToString(); | |||
} | |||
private void ReadOddRegister2() | |||
{ | |||
byte slaveId = 1; | |||
ushort totalRegisters = 1000; | |||
ushort chunkSize = 100; | |||
int numChunks = (int)Math.Ceiling((double)totalRegisters / chunkSize); | |||
ushort[] allRegisters = new ushort[totalRegisters]; | |||
Task[] tasks = new Task[numChunks]; | |||
DateTime startTime = DateTime.Now; | |||
for (int i = 0; i < numChunks; i++) | |||
{ | |||
ushort startAddress = (ushort)(10300 + i * chunkSize); | |||
ushort currentChunkSize = 100; | |||
int chunkIndex = i; | |||
tasks[i] = Task.Run(() => | |||
{ | |||
ushort[] registers = ReadRegisters(slaveId, startAddress, currentChunkSize); | |||
Array.Copy(registers, 0, allRegisters, chunkIndex * chunkSize, currentChunkSize); | |||
}); | |||
} | |||
// 等待所有任务完成 | |||
Task.WaitAll(tasks); | |||
Time = (int)(DateTime.Now - startTime).TotalMilliseconds; | |||
StringBuilder result = new StringBuilder(); | |||
int count = 0; | |||
for (int i = 1; i < totalRegisters; i += 2) | |||
{ | |||
result.Append(allRegisters[i].ToString() + " "); | |||
count++; | |||
if (count % 50 == 0) | |||
{ | |||
result.AppendLine(); | |||
} | |||
} | |||
ReadResult = result.ToString(); | |||
} | |||
public ushort[] ReadRegisters(byte slaveAddress, ushort startAddress, ushort numberOfPoints) | |||
{ | |||
object _lock = new object(); | |||
ushort[] resultValue = null; | |||
if (!_serialPort.IsOpen) | |||
{ | |||
MessageBox.Show("串口没有链接,请先链接"); | |||
return resultValue; | |||
} | |||
List<byte> sendByteList = new List<byte>(); | |||
//设置从站地址 | |||
sendByteList.Add(slaveAddress); | |||
//设置功能码 | |||
sendByteList.Add(0x03); | |||
//设置起始地址的高位和低位 | |||
sendByteList.Add(BitConverter.GetBytes(startAddress)[1]); | |||
sendByteList.Add(BitConverter.GetBytes(startAddress)[0]); | |||
//设置读取几个线圈的高位和低位 | |||
sendByteList.Add(BitConverter.GetBytes(numberOfPoints)[1]); | |||
sendByteList.Add(BitConverter.GetBytes(numberOfPoints)[0]); | |||
//获取CRC校验码 | |||
byte[] getCRC = sendByteList.ToArray(); | |||
byte[] resultCRC = CRCUitl.CalculateCRC(getCRC, getCRC.Length); | |||
sendByteList.Add(resultCRC[0]); | |||
sendByteList.Add(resultCRC[1]); | |||
byte[] sendByte = sendByteList.ToArray(); | |||
int maxRetries = 3; // 最大重试次数 | |||
int attempt = 0; | |||
List<byte> responseData = new List<byte>(); | |||
byte[] response = null; | |||
_serialPort.Write(sendByte, 0, sendByte.Length); | |||
while (attempt < maxRetries) | |||
{ | |||
try | |||
{ | |||
lock (_lock) | |||
{ | |||
//使用时间去轮询查询数据 | |||
DateTime startTime = DateTime.Now; | |||
while ((DateTime.Now - startTime).TotalMilliseconds < _serialPort.ReadTimeout) | |||
{ | |||
int bytesToRead = _serialPort.BytesToRead; | |||
if (bytesToRead > 0) | |||
{ | |||
byte[] buffer = new byte[bytesToRead]; | |||
int bytesRead = _serialPort.Read(buffer, 0, bytesToRead); | |||
responseData.AddRange(buffer.Take(bytesRead)); | |||
} | |||
//延迟20毫秒,节约cpu资源 | |||
Task.Delay(20); | |||
} | |||
response = responseData.ToArray(); | |||
if (response[0] == 0x00) | |||
{ | |||
continue; | |||
} | |||
resultValue = ParseRegistersresponse(sendByte, response, numberOfPoints); | |||
return resultValue; | |||
} | |||
} | |||
catch (Exception) | |||
{ | |||
attempt++; | |||
} | |||
} | |||
return resultValue; | |||
} | |||
public ushort[] ParseRegistersresponse(byte[] sendByte, byte[] response, ushort numberOfPoints) | |||
{ | |||
//判断发送回来的数据是否正确 | |||
if (CheckData.CheckResponse(response)) | |||
{ | |||
ushort[] registers = new ushort[numberOfPoints]; | |||
for (int i = 0; i < numberOfPoints; i++) | |||
{ | |||
int pos = 3 + i * 2; | |||
// 大端序转换 (高位在前) | |||
registers[i] = (ushort)((response[pos] << 8) | response[pos + 1]); | |||
} | |||
return registers; | |||
} | |||
else | |||
{ | |||
return null; | |||
} | |||
} | |||
} | |||
} |
@@ -50,6 +50,8 @@ namespace ModbusDemo.VIewModel | |||
+ ",数据位:" + _serialPort.DataBits + ",校验位:" + _serialPort.Parity + ",停止位:" + _serialPort.StopBits; | |||
} | |||
} | |||
#region 读取定义 | |||
@@ -66,7 +66,7 @@ namespace ModbusDemo.VIewModel | |||
LeftMenusList.Add(new MenusInfo() { Icon = "AllInclusive", MenuName = "线圈操作", ViewName = "CoilUC" }); | |||
LeftMenusList.Add(new MenusInfo() { Icon = "BlurCircular", MenuName = "寄存器操作", ViewName = "RegisterUC" }); | |||
LeftMenusList.Add(new MenusInfo() { Icon = "Settings", MenuName = "串口设置", ViewName = "SettingsUC" }); | |||
LeftMenusList.Add(new MenusInfo() { Icon = "Settings", MenuName = "附加功能", ViewName = "AttachUC" }); | |||
LeftMenusList.Add(new MenusInfo() { Icon = "AddCircle", MenuName = "附加功能", ViewName = "AttachUC" }); | |||
} | |||
public void DefultNaigation() | |||
@@ -29,7 +29,7 @@ namespace ModbusTest | |||
_serialport.StopBits = StopBits.One; | |||
_serialport.ReadTimeout = 500; | |||
_serialport.WriteTimeout = 500; | |||
_serialport.Open(); | |||
_serialport.Open(); | |||
_mockDbContext = new Mock<ModbusDbContext>(); | |||
_modbusRtu = new ModbusRTU(_serialport, _mockDbContext.Object); | |||
} | |||
@@ -47,7 +47,6 @@ namespace ModbusTest | |||
{ | |||
var result = _modbusRtu.ReadCoil(1, 300, 5); | |||
// 创建包含5个true的预期数组 | |||
var expected = new bool[5]; | |||
Array.Fill(expected, false); | |||
CollectionAssert.AreEqual(expected, result); | |||
@@ -57,21 +56,23 @@ namespace ModbusTest | |||
public void ReadCoil2() | |||
{ | |||
var result = _modbusRtu.ReadCoil(1, 305, 5); | |||
// 创建包含5个flase的预期数组 | |||
var expected = new bool[5]; | |||
Array.Fill(expected, true); | |||
CollectionAssert.AreEqual(expected, result); | |||
} | |||
/// <summary> | |||
/// 测试写入线圈 | |||
/// </summary> | |||
[Test] | |||
public void WriteCoil1() | |||
{ | |||
var data = new bool[5]; | |||
Array.Fill(data, true); | |||
_modbusRtu.WriteCoil(1, 310, data); | |||
// 创建包含5个true的预期数组 | |||
var expected = _modbusRtu.ReadCoil(1, 310, 5); | |||
CollectionAssert.AreEqual(data, expected); | |||
@@ -85,13 +86,15 @@ namespace ModbusTest | |||
var data = new bool[5]; | |||
Array.Fill(data, false); | |||
_modbusRtu.WriteCoil(1, 315, data); | |||
// 创建包含5个flase的预期数组 | |||
var expected = _modbusRtu.ReadCoil(1, 315, 5); | |||
CollectionAssert.AreEqual(data, expected); | |||
} | |||
/// <summary> | |||
/// 测试读取寄存器 | |||
/// </summary> | |||
[Test] | |||
public void ReadRegister1() | |||
{ | |||
@@ -108,13 +111,15 @@ namespace ModbusTest | |||
{ | |||
ushort[] data = new ushort[5]; | |||
Array.Fill(data, (ushort)1); | |||
var expected = _modbusRtu.ReadRegisters(1, 305, 5); | |||
CollectionAssert.AreEqual(data, expected); | |||
} | |||
/// <summary> | |||
/// 测试写入寄存器 | |||
/// </summary> | |||
[Test] | |||
public void WriteRegister1() | |||
{ | |||
@@ -137,5 +142,59 @@ namespace ModbusTest | |||
var expected = _modbusRtu.ReadRegisters(1, 315, 5); | |||
CollectionAssert.AreEqual(data, expected); | |||
} | |||
/// <summary> | |||
/// 解析线圈的返回值 | |||
/// </summary> | |||
[Test] | |||
public void ParseCoilresponse1() | |||
{ | |||
var data = new bool[5]; | |||
Array.Fill(data, true); | |||
byte[] response = new byte[] { 0x01, 0x01, 0x01, 0x7f, 0x10, 0x68 }; | |||
bool[] bools = _modbusRtu.ParseCoilresponse(new byte[] { }, response, 5); | |||
CollectionAssert.AreEqual(data, bools); | |||
} | |||
[Test] | |||
public void ParseCoilresponse2() | |||
{ | |||
var data = new bool[5]; | |||
Array.Fill(data, false); | |||
byte[] response = new byte[] { 0x01, 0x01, 0x01, 0x00, 0x51, 0x88 }; | |||
bool[] result = _modbusRtu.ParseCoilresponse(new byte[] { }, response, 5); | |||
CollectionAssert.AreEqual(data, result); | |||
} | |||
/// <summary> | |||
/// 解析寄存器的返回值 | |||
/// </summary> | |||
[Test] | |||
public void ParseRegistersresponse1() | |||
{ | |||
ushort[] data = new ushort[5]; | |||
Array.Fill(data, (ushort)1); | |||
byte[] response = new byte[] {0x01, 0x03, 0x0a, 0x00, 0x01, 0x00, 0x01, 0x00, | |||
0x01, 0x00, 0x01, 0x00, 0x01, 0x94, 0x26 }; | |||
ushort[] result = _modbusRtu.ParseRegistersresponse(new byte[] {},response, 5); | |||
CollectionAssert.AreEqual(data, result); | |||
} | |||
[Test] | |||
public void ParseRegistersresponse2() | |||
{ | |||
ushort[] data = new ushort[2]; | |||
Array.Fill(data, (ushort)10); | |||
byte[] response = new byte[] {0x01, 0x03, 0x04, 0x00,0x0a, 0x00, 0x0a, 0x5a, 0x36 }; | |||
ushort[] result = _modbusRtu.ParseRegistersresponse(new byte[] { }, response, 2); | |||
CollectionAssert.AreEqual(data, result); | |||
} | |||
} | |||
} |