Browse Source

添加功能码,并添加可以选择读写耗时时间

dev-2
永攀 张 2 weeks ago
parent
commit
85f81b9817
10 changed files with 270 additions and 93 deletions
  1. +95
    -46
      ModbusDemo/Device/ModbusRTU.cs
  2. +52
    -0
      ModbusDemo/ErrorCode/ErrorCode.cs
  3. +2
    -1
      ModbusDemo/Extension/EnumBindingSourceExtension.cs
  4. +5
    -0
      ModbusDemo/ModbusDemo.csproj
  5. +10
    -0
      ModbusDemo/Model/ErrorCode.cs
  6. +5
    -3
      ModbusDemo/Uitls/CheckData.cs
  7. +28
    -2
      ModbusDemo/VIew/SettingsUC.xaml
  8. +42
    -29
      ModbusDemo/VIewModel/AttachUCViewModel.cs
  9. +25
    -11
      ModbusDemo/VIewModel/SettingsUCViewModel.cs
  10. +6
    -1
      ModbusTest/UnitTest1.cs

+ 95
- 46
ModbusDemo/Device/ModbusRTU.cs View File

@@ -25,7 +25,7 @@ namespace ModbusDemo.Device
{ {
_serialPort = serialPort; _serialPort = serialPort;
_modbusDbContext = modbusDbContext; _modbusDbContext = modbusDbContext;
_portAdapter = new SerialPortAdapter(serialPort);
//_portAdapter = new SerialPortAdapter(serialPort);
} }
/// <summary> /// <summary>
/// 用来发送读写线圈的指令 /// 用来发送读写线圈的指令
@@ -63,11 +63,20 @@ namespace ModbusDemo.Device
int attempt = 0; int attempt = 0;
byte[] response = null; byte[] response = null;
List<byte> responseData = new List<byte>(); List<byte> responseData = new List<byte>();
_serialPort.Write(sendByte, 0, sendByte.Length);
while (attempt < maxRetries) while (attempt < maxRetries)
{ {
if (_serialPort.IsOpen)
{
// 每次重试前清空缓冲区
responseData.Clear();
// 清除输入缓冲区残留数据
_serialPort.DiscardInBuffer();
}
try try
{ {
_serialPort.Write(sendByte, 0, sendByte.Length);
//使用时间去轮询查询数据 //使用时间去轮询查询数据
DateTime startTime = DateTime.Now; DateTime startTime = DateTime.Now;
while ((DateTime.Now - startTime).TotalMilliseconds < _serialPort.ReadTimeout) while ((DateTime.Now - startTime).TotalMilliseconds < _serialPort.ReadTimeout)
@@ -80,11 +89,12 @@ namespace ModbusDemo.Device
responseData.AddRange(buffer.Take(bytesRead)); responseData.AddRange(buffer.Take(bytesRead));
} }
//延迟20毫秒,节约cpu资源 //延迟20毫秒,节约cpu资源
Task.Delay(20);
Thread.Sleep(20);
} }
response = responseData.ToArray(); response = responseData.ToArray();
if (response[0] == 0x00)
if (response.Length == 0)
{ {
attempt++;
continue; continue;
} }
resultValue = ParseCoilresponse(sendByte, response, numberOfPoints); resultValue = ParseCoilresponse(sendByte, response, numberOfPoints);
@@ -93,6 +103,10 @@ namespace ModbusDemo.Device
catch (Exception) catch (Exception)
{ {



}
finally
{
attempt++; attempt++;
} }


@@ -112,7 +126,7 @@ namespace ModbusDemo.Device
catch (Exception) catch (Exception)
{ {


MessageBox.Show("0x15:数据库插入错误");
MessageBox.Show(ErrorCode.ErrorCode.DatabaseException.ToString());
} }


return resultValue; return resultValue;
@@ -132,17 +146,17 @@ namespace ModbusDemo.Device
//将操作的指令,插入数据库 //将操作的指令,插入数据库
string RequestStr = ByteArrayToString(sendByte); string RequestStr = ByteArrayToString(sendByte);
string responseStr = ByteArrayToString(response); string responseStr = ByteArrayToString(response);
ModbusLog m = new ModbusLog();
m.OperationType = "读线圈";
m.ResponseData = responseStr;
m.RequestData = RequestStr;
_modbusDbContext.Add(m);
ModbusLog modbusLog = new ModbusLog();
modbusLog.OperationType = "读线圈";
modbusLog.ResponseData = responseStr;
modbusLog.RequestData = RequestStr;
_modbusDbContext.Add(modbusLog);
_modbusDbContext.SaveChanges(); _modbusDbContext.SaveChanges();
} }
catch (Exception) catch (Exception)
{ {


MessageBox.Show("0x15:数据库插入错误");
MessageBox.Show(ErrorCode.ErrorCode.DatabaseException.ToString());
} }




@@ -222,11 +236,19 @@ namespace ModbusDemo.Device
int attempt = 0; int attempt = 0;
byte[] response = null; byte[] response = null;
List<byte> responseData = new List<byte>(); List<byte> responseData = new List<byte>();
_serialPort.Write(sendByte, 0, sendByte.Length);
while (attempt < maxRetries) while (attempt < maxRetries)
{ {
if (_serialPort.IsOpen)
{
// 每次重试前清空缓冲区
responseData.Clear();
// 清除输入缓冲区残留数据
_serialPort.DiscardInBuffer();
}
try try
{ {
_serialPort.Write(sendByte, 0, sendByte.Length);
//使用时间去轮询查询数据 //使用时间去轮询查询数据
DateTime startTime = DateTime.Now; DateTime startTime = DateTime.Now;
while ((DateTime.Now - startTime).TotalMilliseconds < _serialPort.ReadTimeout) while ((DateTime.Now - startTime).TotalMilliseconds < _serialPort.ReadTimeout)
@@ -239,10 +261,10 @@ namespace ModbusDemo.Device
responseData.AddRange(buffer.Take(bytesRead)); responseData.AddRange(buffer.Take(bytesRead));
} }
//延迟20毫秒,节约cpu资源 //延迟20毫秒,节约cpu资源
Task.Delay(20);
Thread.Sleep(20);
} }
response = responseData.ToArray(); response = responseData.ToArray();
if (response[0] != 0x00)
if (response.Length != 0)
{ {
break; break;
} }
@@ -250,6 +272,10 @@ namespace ModbusDemo.Device
catch (Exception) catch (Exception)
{ {



}
finally
{
attempt++; attempt++;
} }


@@ -260,16 +286,16 @@ namespace ModbusDemo.Device
//将操作的指令,插入数据库 //将操作的指令,插入数据库
string RequestStr = ByteArrayToString(sendByte); string RequestStr = ByteArrayToString(sendByte);
string responseStr = ByteArrayToString(response); string responseStr = ByteArrayToString(response);
ModbusLog m = new ModbusLog();
m.OperationType = "写线圈";
m.ResponseData = responseStr;
m.RequestData = RequestStr;
_modbusDbContext.Add(m);
ModbusLog modbusLog = new ModbusLog();
modbusLog.OperationType = "写线圈";
modbusLog.ResponseData = responseStr;
modbusLog.RequestData = RequestStr;
_modbusDbContext.Add(modbusLog);
_modbusDbContext.SaveChanges(); _modbusDbContext.SaveChanges();
} }
catch (Exception) catch (Exception)
{ {
MessageBox.Show("0x15:数据库插入错误");
MessageBox.Show(ErrorCode.ErrorCode.DatabaseException.ToString());


} }
//判断发送回来的数据是否正确 //判断发送回来的数据是否正确
@@ -334,12 +360,18 @@ namespace ModbusDemo.Device
int attempt = 0; int attempt = 0;
List<byte> responseData = new List<byte>(); List<byte> responseData = new List<byte>();
byte[] response = null; byte[] response = null;
_serialPort.Write(sendByte, 0, sendByte.Length);
while (attempt < maxRetries) while (attempt < maxRetries)
{ {
if (_serialPort.IsOpen)
{
// 每次重试前清空缓冲区
responseData.Clear();
// 清除输入缓冲区残留数据
_serialPort.DiscardInBuffer();
}
try try
{ {

_serialPort.Write(sendByte, 0, sendByte.Length);
//使用时间去轮询查询数据 //使用时间去轮询查询数据
DateTime startTime = DateTime.Now; DateTime startTime = DateTime.Now;
while ((DateTime.Now - startTime).TotalMilliseconds < _serialPort.ReadTimeout) while ((DateTime.Now - startTime).TotalMilliseconds < _serialPort.ReadTimeout)
@@ -352,10 +384,10 @@ namespace ModbusDemo.Device
responseData.AddRange(buffer.Take(bytesRead)); responseData.AddRange(buffer.Take(bytesRead));
} }
//延迟20毫秒,节约cpu资源 //延迟20毫秒,节约cpu资源
Task.Delay(20);
Thread.Sleep(20);
} }
response = responseData.ToArray(); response = responseData.ToArray();
if (response[0] == 0x00)
if (response.Length == 0)
{ {
continue; continue;
} }
@@ -365,26 +397,31 @@ namespace ModbusDemo.Device
catch (Exception) catch (Exception)
{ {



}
finally
{
attempt++; attempt++;
} }


} }
//将操作失败的指令,插入数据库
string RequestStr = ByteArrayToString(sendByte);



try try
{ {
ModbusLog m = new ModbusLog();
m.OperationType = "读寄存器";
m.ResponseData = "";
m.RequestData = RequestStr;
_modbusDbContext.Add(m);
//将操作失败的指令,插入数据库
string RequestStr = ByteArrayToString(sendByte);
ModbusLog modbusLog = new ModbusLog();
modbusLog.OperationType = "读寄存器";
modbusLog.ResponseData = "";
modbusLog.RequestData = RequestStr;
_modbusDbContext.Add(modbusLog);
_modbusDbContext.SaveChanges(); _modbusDbContext.SaveChanges();
} }
catch (Exception) catch (Exception)
{ {


MessageBox.Show("0x15:数据库插入错误");
MessageBox.Show(ErrorCode.ErrorCode.DatabaseException.ToString());
} }


return resultValue; return resultValue;
@@ -406,16 +443,16 @@ namespace ModbusDemo.Device
//将操作的指令,插入数据库 //将操作的指令,插入数据库
string RequestStr = ByteArrayToString(sendByte); string RequestStr = ByteArrayToString(sendByte);
string responseStr = ByteArrayToString(response); string responseStr = ByteArrayToString(response);
ModbusLog m = new ModbusLog();
m.OperationType = "读寄存器";
m.ResponseData = responseStr;
m.RequestData = RequestStr;
_modbusDbContext.Add(m);
ModbusLog modbusLog = new ModbusLog();
modbusLog.OperationType = "读寄存器";
modbusLog.ResponseData = responseStr;
modbusLog.RequestData = RequestStr;
_modbusDbContext.Add(modbusLog);
_modbusDbContext.SaveChanges(); _modbusDbContext.SaveChanges();
} }
catch (Exception) catch (Exception)
{ {
MessageBox.Show("0x15:数据库插入错误");
MessageBox.Show(ErrorCode.ErrorCode.DatabaseException.ToString());


} }


@@ -493,11 +530,19 @@ namespace ModbusDemo.Device
int attempt = 0; int attempt = 0;
byte[] response = null; byte[] response = null;
List<byte> responseData = new List<byte>(); List<byte> responseData = new List<byte>();
_serialPort.Write(sendByte, 0, sendByte.Length);
while (attempt < maxRetries) while (attempt < maxRetries)
{ {
if (_serialPort.IsOpen)
{
// 每次重试前清空缓冲区
responseData.Clear();
// 清除输入缓冲区残留数据
_serialPort.DiscardInBuffer();
}
try try
{ {
_serialPort.Write(sendByte, 0, sendByte.Length);
//使用时间去轮询查询数据 //使用时间去轮询查询数据
DateTime startTime = DateTime.Now; DateTime startTime = DateTime.Now;
while ((DateTime.Now - startTime).TotalMilliseconds < _serialPort.ReadTimeout) while ((DateTime.Now - startTime).TotalMilliseconds < _serialPort.ReadTimeout)
@@ -510,15 +555,19 @@ namespace ModbusDemo.Device
responseData.AddRange(buffer.Take(bytesRead)); responseData.AddRange(buffer.Take(bytesRead));
} }
//延迟20毫秒,节约cpu资源 //延迟20毫秒,节约cpu资源
Task.Delay(20);
Thread.Sleep(20);
} }
response = responseData.ToArray(); response = responseData.ToArray();
if (response[0] != 0x00)
if (response.Length != 0)
{ {
break; break;
} }
} }
catch (Exception) catch (Exception)
{

}
finally
{ {
attempt++; attempt++;
} }
@@ -528,11 +577,11 @@ namespace ModbusDemo.Device
//将操作的指令,插入数据库 //将操作的指令,插入数据库
string RequestStr = ByteArrayToString(sendByte); string RequestStr = ByteArrayToString(sendByte);
string responseStr = ByteArrayToString(response); string responseStr = ByteArrayToString(response);
ModbusLog m = new ModbusLog();
m.OperationType = "写寄存器";
m.ResponseData = responseStr;
m.RequestData = RequestStr;
_modbusDbContext.Add(m);
ModbusLog modbusLog = new ModbusLog();
modbusLog.OperationType = "写寄存器";
modbusLog.ResponseData = responseStr;
modbusLog.RequestData = RequestStr;
_modbusDbContext.Add(modbusLog);
_modbusDbContext.SaveChanges(); _modbusDbContext.SaveChanges();
} }
catch (Exception) catch (Exception)


+ 52
- 0
ModbusDemo/ErrorCode/ErrorCode.cs View File

@@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ModbusDemo.ErrorCode
{
public class ErrorCode
{

// 静态列表:存储所有错误码
public static readonly List<ErrorCode> AllErrors = new List<ErrorCode>();

// 错误码值
public byte Code { get; }

// 错误描述
public string Description { get; }

// 私有构造函数,只能通过静态方法创建错误码
private ErrorCode(byte code, string description)
{
Code = code;
Description = description;

// 自动添加到错误码列表
AllErrors.Add(this);
}

// 重写 ToString 方法
public override string ToString() => $"Error 0x{Code:X2}: {Description}";

// 隐式转换为 byte
public static implicit operator byte(ErrorCode error) => error.Code;

// 根据错误码值查找错误码
public static ErrorCode FromByte(byte code) => AllErrors.FirstOrDefault(e => e.Code == code);

// 定义所有错误码
public static readonly ErrorCode FunctionCodeError = new ErrorCode(0x01, "功能码错误");
public static readonly ErrorCode DomainStartAddressError = new ErrorCode(0x02, "域数据首地址错误");
public static readonly ErrorCode DataContentError = new ErrorCode(0x03, "数据内容错误");
public static readonly ErrorCode DataTypeError = new ErrorCode(0x10, "数据类型错误");
public static readonly ErrorCode DomainDataCountError = new ErrorCode(0x11, "域数据个数错误");
public static readonly ErrorCode DataCountMismatch = new ErrorCode(0x12, "数据个数与内部区域数据个数不符");
public static readonly ErrorCode WriteOperationDenied = new ErrorCode(0x13, "不能进行写操作");
public static readonly ErrorCode CrcCheckError = new ErrorCode(0x14, "CRC校验错误");
public static readonly ErrorCode DatabaseException = new ErrorCode(0x15, "数据库异常");
}

}

+ 2
- 1
ModbusDemo/Extension/EnumBindingSourceExtension.cs View File

@@ -4,7 +4,8 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Markup; using System.Windows.Markup;

using System;
using System.Reflection;
namespace ModbusDemo.Extension namespace ModbusDemo.Extension
{ {
/// <summary> /// <summary>


+ 5
- 0
ModbusDemo/ModbusDemo.csproj View File

@@ -9,6 +9,11 @@
<ApplicationIcon>ModbusRTU_64x64.ico</ApplicationIcon> <ApplicationIcon>ModbusRTU_64x64.ico</ApplicationIcon>
</PropertyGroup> </PropertyGroup>


<ItemGroup>
<Compile Remove="ErrorCode\ErrorCodeExtensions.cs" />
<Compile Remove="ErrorCode\ErrorInfoAttribute.cs" />
</ItemGroup>

<ItemGroup> <ItemGroup>
<Content Include="ModbusRTU_64x64.ico"> <Content Include="ModbusRTU_64x64.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>


+ 10
- 0
ModbusDemo/Model/ErrorCode.cs View File

@@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ModbusDemo.Model
{
}

+ 5
- 3
ModbusDemo/Uitls/CheckData.cs View File

@@ -4,7 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using ModbusDemo.ErrorCode;
namespace ModbusDemo.Uitls namespace ModbusDemo.Uitls
{ {
public static class CheckData public static class CheckData
@@ -32,7 +32,9 @@ namespace ModbusDemo.Uitls
// 判断高4位是否等于8 // 判断高4位是否等于8
if (highNibble == 8) if (highNibble == 8)
{ {
MessageBox.Show($"数据错误:错误码为:0x{response[2]:X2}");
var error = ErrorCode.ErrorCode.FromByte(response[2]);
MessageBox.Show(error.ToString());
return false; return false;
} }
} }
@@ -40,7 +42,7 @@ namespace ModbusDemo.Uitls


if (!CRCUitl.ValidateCRC(response)) if (!CRCUitl.ValidateCRC(response))
{ {
MessageBox.Show("0x14:CRC校验错误");
MessageBox.Show(ErrorCode.ErrorCode.CrcCheckError.ToString());
return false; return false;
} }




+ 28
- 2
ModbusDemo/VIew/SettingsUC.xaml View File

@@ -31,7 +31,6 @@
<RowDefinition> <RowDefinition>
</RowDefinition> </RowDefinition>
</Grid.RowDefinitions> </Grid.RowDefinitions>

<Grid Grid.Row="1"> <Grid Grid.Row="1">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition> <ColumnDefinition>
@@ -44,7 +43,8 @@
</ColumnDefinition> </ColumnDefinition>
<ColumnDefinition> <ColumnDefinition>
</ColumnDefinition> </ColumnDefinition>

<ColumnDefinition>
</ColumnDefinition>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<!-- 这是设置串口的选择 --> <!-- 这是设置串口的选择 -->
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
@@ -131,6 +131,32 @@
</ComboBox> </ComboBox>
</StackPanel> </StackPanel>


<!-- 超时时间 -->
<StackPanel Grid.Column="5" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Margin="10,0,0,5" Text="超时时间">
</TextBlock>
<ComboBox
Width="80"
Height="30"
Margin="10,0,0,5"
HorizontalAlignment="Left"
materialDesign:HintAssist.Hint="200"
SelectedItem="{Binding TimeOut}">
<ComboBoxItem Content="20">
</ComboBoxItem>
<ComboBoxItem Content="50">
</ComboBoxItem>
<ComboBoxItem Content="100">
</ComboBoxItem>
<ComboBoxItem Content="200">
</ComboBoxItem>
<ComboBoxItem Content="300">
</ComboBoxItem>
<ComboBoxItem Content="500">
</ComboBoxItem>
</ComboBox>
</StackPanel>

</Grid> </Grid>
<!-- 两个按钮的定义 --> <!-- 两个按钮的定义 -->
<Grid Grid.Row="2"> <Grid Grid.Row="2">


+ 42
- 29
ModbusDemo/VIewModel/AttachUCViewModel.cs View File

@@ -50,7 +50,7 @@ namespace ModbusDemo.VIewModel
} }
public AttachUCViewModel(SerialPort serialPort) public AttachUCViewModel(SerialPort serialPort)
{ {
ReadOddRegisterCmm = new DelegateCommand(ReadOddRegister);
ReadOddRegisterCmm = new DelegateCommand(ReadOddRegister2);
_serialPort = serialPort; _serialPort = serialPort;
} }
/// <summary> /// <summary>
@@ -124,18 +124,18 @@ namespace ModbusDemo.VIewModel
ushort currentChunkSize = 100; ushort currentChunkSize = 100;


int chunkIndex = i; int chunkIndex = i;
tasks[i] = Task.Run(async () =>
{


ushort[] registers = await ReadRegisters(slaveId, startAddress, currentChunkSize);
ushort[] registers = ReadRegisters(slaveId, startAddress, currentChunkSize);
Array.Copy(registers, 0, allRegisters, chunkIndex * chunkSize, currentChunkSize); Array.Copy(registers, 0, allRegisters, chunkIndex * chunkSize, currentChunkSize);




});
} }


// 等待所有任务完成 // 等待所有任务完成
Task.WaitAll(tasks);
Time = (int)(DateTime.Now - startTime).TotalMilliseconds; Time = (int)(DateTime.Now - startTime).TotalMilliseconds;
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
int count = 0; int count = 0;
@@ -151,27 +151,25 @@ namespace ModbusDemo.VIewModel
ReadResult = result.ToString(); ReadResult = result.ToString();
} }



public async Task<ushort[]> ReadRegisters(byte slaveAddress, ushort startAddress, ushort numberOfPoints)
public ushort[] ReadRegisters(byte slaveAddress, ushort startAddress, ushort numberOfPoints)
{ {

ushort[] resultValue = null; ushort[] resultValue = null;
if (!_serialPort.IsOpen) if (!_serialPort.IsOpen)
{ {
MessageBox.Show("串口没有链接,请先链接"); MessageBox.Show("串口没有链接,请先链接");
return resultValue; 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]);
var sendByteList = new List<byte>(8)
{
slaveAddress, // 从站地址
0x03, // 功能码:读保持寄存器
};
// 添加起始地址(高字节在前)
sendByteList.AddRange(BitConverter.GetBytes(startAddress).Reverse());
// 添加读取点数(高字节在前)
sendByteList.AddRange(BitConverter.GetBytes(numberOfPoints).Reverse());
//获取CRC校验码 //获取CRC校验码
byte[] getCRC = sendByteList.ToArray(); byte[] getCRC = sendByteList.ToArray();
byte[] resultCRC = CRCUitl.CalculateCRC(getCRC, getCRC.Length); byte[] resultCRC = CRCUitl.CalculateCRC(getCRC, getCRC.Length);
@@ -183,14 +181,15 @@ namespace ModbusDemo.VIewModel
int attempt = 0; int attempt = 0;
List<byte> responseData = new List<byte>(); List<byte> responseData = new List<byte>();
byte[] response = null; byte[] response = null;
_serialPort.Write(sendByte, 0, sendByte.Length);
while (attempt < maxRetries) while (attempt < maxRetries)
{ {
// 每次重试前清空缓冲区
responseData.Clear();
// 清除输入缓冲区残留数据
_serialPort.DiscardInBuffer();
try try
{ {



_serialPort.Write(sendByte, 0, sendByte.Length);
//使用时间去轮询查询数据 //使用时间去轮询查询数据
DateTime startTime = DateTime.Now; DateTime startTime = DateTime.Now;
while ((DateTime.Now - startTime).TotalMilliseconds < _serialPort.ReadTimeout) while ((DateTime.Now - startTime).TotalMilliseconds < _serialPort.ReadTimeout)
@@ -203,33 +202,42 @@ namespace ModbusDemo.VIewModel
responseData.AddRange(buffer.Take(bytesRead)); responseData.AddRange(buffer.Take(bytesRead));
} }
//延迟20毫秒,节约cpu资源 //延迟20毫秒,节约cpu资源
await Task.Delay(20);
Thread.Sleep(20);
} }
response = responseData.ToArray(); response = responseData.ToArray();
if (response[0] == 0x00)
if (response.Length == 0)
{ {
continue; continue;
} }
resultValue = ParseRegistersresponse(sendByte, response, numberOfPoints); resultValue = ParseRegistersresponse(sendByte, response, numberOfPoints);
return resultValue; return resultValue;

} }
catch (Exception) catch (Exception)
{ {



}
finally
{
attempt++; attempt++;
} }


} }

return resultValue; return resultValue;






} }

/// <summary>
/// 解析读取到的操作
/// </summary>
/// <param name="sendByte"></param>
/// <param name="response"></param>
/// <param name="numberOfPoints"></param>
/// <returns></returns>
public ushort[] ParseRegistersresponse(byte[] sendByte, byte[] response, ushort numberOfPoints) public ushort[] ParseRegistersresponse(byte[] sendByte, byte[] response, ushort numberOfPoints)
{ {




//判断发送回来的数据是否正确 //判断发送回来的数据是否正确
@@ -249,7 +257,12 @@ namespace ModbusDemo.VIewModel
{ {
return null; return null;
} }




} }

} }


} }

+ 25
- 11
ModbusDemo/VIewModel/SettingsUCViewModel.cs View File

@@ -14,7 +14,7 @@ using System.Windows;


namespace ModbusDemo.VIewModel namespace ModbusDemo.VIewModel
{ {
class SettingsUCViewModel : BindableBase class SettingsUCViewModel : BindableBase
{ {
//事件聚合器 //事件聚合器
@@ -22,9 +22,9 @@ namespace ModbusDemo.VIewModel
//控制页面跳转 //控制页面跳转
private readonly IRegionManager _regionManager; private readonly IRegionManager _regionManager;
//断开连接的命令 //断开连接的命令
public DelegateCommand DisConnectionCmm { get; set; }
public DelegateCommand DisConnectionCmm { get; set; }
//链接窗口的命令 //链接窗口的命令
public DelegateCommand ConnectionCmm { get; set; }
public DelegateCommand ConnectionCmm { get; set; }


//获取串口 //获取串口
private SerialPort _serialPort; private SerialPort _serialPort;
@@ -93,9 +93,23 @@ namespace ModbusDemo.VIewModel
} }
} }


//设置读取和写入时间
private string _timeOut = "200";

public string TimeOut
{
get { return _timeOut; }
set
{
_timeOut = value;
RaisePropertyChanged();
}
}


public SettingsUCViewModel() public SettingsUCViewModel()
{ {
} }
/// <summary> /// <summary>
/// 从容器中获取创建的窗口 /// 从容器中获取创建的窗口
@@ -115,7 +129,7 @@ namespace ModbusDemo.VIewModel
if (_serialPort.IsOpen) if (_serialPort.IsOpen)
{ {
_serialPort.Close(); _serialPort.Close();
} }
MessageBox.Show("连接已经断开"); MessageBox.Show("连接已经断开");
} }
@@ -139,11 +153,11 @@ namespace ModbusDemo.VIewModel
} }
_serialPort.StopBits = this.StopBits; _serialPort.StopBits = this.StopBits;
_serialPort.DataBits = int.Parse(GetComboBoxItemValue(this.DataBits)); _serialPort.DataBits = int.Parse(GetComboBoxItemValue(this.DataBits));
//读取超时时间 //读取超时时间
_serialPort.ReadTimeout = 500;
_serialPort.ReadTimeout = int.Parse(GetComboBoxItemValue(this.TimeOut));
//写入超时时间 //写入超时时间
_serialPort.WriteTimeout = 500;
_serialPort.WriteTimeout = int.Parse(GetComboBoxItemValue(this.TimeOut));
try try
{ {
_serialPort.Open(); _serialPort.Open();
@@ -156,14 +170,14 @@ namespace ModbusDemo.VIewModel
catch (Exception) catch (Exception)
{ {


MessageBox.Show("串口已经链接或者断开,请重新检查在尝试","warning",MessageBoxButton.OK,MessageBoxImage.Warning);
MessageBox.Show("串口已经链接或者断开,请重新检查在尝试", "warning", MessageBoxButton.OK, MessageBoxImage.Warning);
} }
} }
else else
{ {
MessageBox.Show("当前串口已经连接,请先断开,再连接"); MessageBox.Show("当前串口已经连接,请先断开,再连接");
} }
} }
/// <summary> /// <summary>
/// 处理下拉框的选择信息 /// 处理下拉框的选择信息
@@ -177,7 +191,7 @@ namespace ModbusDemo.VIewModel
string cleanText = displayText.Replace("System.Windows.Controls.ComboBoxItem: ", ""); string cleanText = displayText.Replace("System.Windows.Controls.ComboBoxItem: ", "");
return cleanText; return cleanText;
} }


} }
} }

+ 6
- 1
ModbusTest/UnitTest1.cs View File

@@ -1,3 +1,5 @@
//using ModbusDemo.Enum;

namespace ModbusTest namespace ModbusTest
{ {
public class Tests public class Tests
@@ -10,7 +12,10 @@ namespace ModbusTest
[Test] [Test]
public void Test1() public void Test1()
{ {
Assert.Pass();
byte[] byteStream = new byte[] { 0x01, 0x81, 0x01, 0x10, 0x00, 0x00, 0xAB, 0x17 };
byte errorCodeByte = byteStream[2]; // 0x01
//ErrorCode errorCode = (ErrorCode)errorCodeByte; // ת»»Îª ErrorCode.FunctionCodeError
//string message = errorCode.GetMessage();
} }
} }
} }

Loading…
Cancel
Save