Skip to content

Commit 020c839

Browse files
committed
💩
1 parent a4b1e3b commit 020c839

File tree

9 files changed

+202
-64
lines changed

9 files changed

+202
-64
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace Wu.CommTool.Modules.ModbusRtu.Enums;
2+
3+
public enum DeviceState
4+
{
5+
Offline,
6+
Online,
7+
Warning,
8+
//Error,
9+
}

Modules/Wu.CommTool.Modules.ModbusRtu/GlobalUsings.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,4 @@
4646
global using Parity = Wu.CommTool.Modules.ModbusRtu.Enums.Parity;
4747
global using Microsoft.Win32;
4848
global using System.Diagnostics;
49+
global using Wu.CommTool.Core.Extensions;

Modules/Wu.CommTool.Modules.ModbusRtu/Models/MrtuData.cs

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public partial class MrtuData : ObservableObject
88
/// <summary>
99
/// 通讯状态 1通讯正常 0通讯失败
1010
/// </summary>
11-
public bool State => UpdateTime != null && ((DateTime)UpdateTime).AddSeconds(10) > DateTime.Now;
11+
public bool State => UpdateTime is not null && ((DateTime)UpdateTime).AddSeconds(10) > DateTime.Now;
1212

1313
/// <summary>
1414
/// 名称
@@ -83,42 +83,4 @@ public partial class MrtuData : ObservableObject
8383
[ObservableProperty]
8484
private string writeValue;
8585

86-
87-
88-
///// <summary>
89-
///// 原始数据字节数组
90-
///// </summary>
91-
//[ObservableProperty]
92-
//[NotifyPropertyChangedFor(nameof(Value))]
93-
//private byte[] originBytes;
94-
95-
///// <summary>
96-
///// 根据字节数据 数据类型 获取值
97-
///// </summary>
98-
///// <param name="databytes"></param>
99-
///// <param name="dataType"></param>
100-
///// <param name="rate"></param>
101-
///// <returns></returns>
102-
//public static dynamic GetVal(byte[] databytes, DataType dataType, double rate)
103-
//{
104-
// if (databytes == null)
105-
// {
106-
// return 0;
107-
// }
108-
109-
// return dataType switch
110-
// {
111-
// DataType.uShort => Math.Round(BitConverter.ToUInt16(databytes, 0) * rate, 3),
112-
// DataType.Short => Math.Round(BitConverter.ToInt16(databytes, 0) * rate, 3),
113-
// DataType.uInt => Math.Round(BitConverter.ToUInt32(databytes, 0) * rate, 3),
114-
// DataType.Int => Math.Round(BitConverter.ToInt32(databytes, 0) * rate, 3),
115-
// DataType.uLong => Math.Round(BitConverter.ToUInt64(databytes, 0) * rate, 3),
116-
// DataType.Long => Math.Round(BitConverter.ToInt64(databytes, 0) * rate, 3),
117-
// DataType.Float => Math.Round((BitConverter.ToSingle(databytes, 0) * rate), 2),
118-
// DataType.Double => Math.Round(BitConverter.ToDouble(databytes, 0) * rate, 2),
119-
// DataType.Hex => $"0x{BitConverter.ToString(databytes.Reverse().ToArray()).Replace("-", "")}",
120-
// _ => (dynamic)0,
121-
// };
122-
//}
123-
12486
}

Modules/Wu.CommTool.Modules.ModbusRtu/Models/MrtuDevice.cs

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -231,21 +231,14 @@ public void UpdateState()
231231
{
232232
DeviceState = DeviceState.Online;
233233
}
234-
else if (onlineCount < MrtuDatas.Count)
234+
else if (onlineCount == 0)
235235
{
236-
DeviceState = DeviceState.Warning;//警告 存在通讯失败的测点
236+
DeviceState = DeviceState.Offline;
237237
}
238-
else if(onlineCount == 0)
238+
else if (onlineCount < MrtuDatas.Count)
239239
{
240-
DeviceState = DeviceState.Offline;
240+
DeviceState = DeviceState.Warning;//警告 存在通讯失败的测点
241241
}
242+
242243
}
243244
}
244-
245-
public enum DeviceState
246-
{
247-
Offline,
248-
Online,
249-
Warning,
250-
//Error,
251-
}

Modules/Wu.CommTool.Modules.ModbusRtu/Models/MrtuSerialPort.cs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public partial class MrtuSerialPort : ObservableObject, IDisposable
1010
#region 字段
1111
private readonly SerialPort serialPort = new(); //串口
1212
private readonly Task receiveHandleTask; //接收消息处理线程
13-
CancellationTokenSource receiveHandleTaskCts = new();
13+
private CancellationTokenSource receiveHandleTaskCts = new();
1414
private readonly EventWaitHandle WaitUartReceived = new AutoResetEvent(true); //接收到串口数据完成标志
1515
private readonly EventWaitHandle WaitNextOne = new AutoResetEvent(true); //等待接收完成后再发送下一条
1616
private readonly ConcurrentQueue<string> ReceiveFrameQueue = new(); //数据帧处理队列
@@ -42,7 +42,7 @@ public MrtuSerialPort(ComConfig config)
4242
serialPort.StopBits = (System.IO.Ports.StopBits)config.StopBits; //停止位
4343
serialPort.DataReceived += new SerialDataReceivedEventHandler(ReceiveMessage);//串口接收事件
4444

45-
receiveHandleTask = new Task(ReceiveFrame,receiveHandleTaskCts.Token);
45+
receiveHandleTask = new Task(ReceiveFrame, receiveHandleTaskCts.Token);
4646
receiveHandleTask.Start();
4747
this.ComConfig = config;
4848
}
@@ -435,11 +435,13 @@ private void ReceiveFrame()
435435
var responseFrame = new ModbusRtuFrame(frame.GetBytes());//实例化ModbusRtu帧
436436
var requestFrame = new ModbusRtuFrame(request);
437437

438+
#if DEBUG
438439
//对接收的消息直接进行crc校验
439440
if (!ModbusUtils.IsModbusCrcOk(frame.GetBytes()))
440441
{
441442
Debug.WriteLine("应答帧校验失败了");
442443
}
444+
#endif
443445

444446
List<byte> frameList = frame.GetBytes().ToList();//将字符串类型的数据帧转换为字节列表
445447
int slaveId = frameList[0]; //从站地址
@@ -498,31 +500,32 @@ private void ReceiveFrame()
498500
foreach (var x in data)
499501
{
500502
x.UpdateTime = DateTime.Now;
503+
var bytenum = (x.RegisterAddr - requestFrame.StartAddr) * 2;//该数据的字节数
501504
switch (x.MrtuDataType)
502505
{
503506
case MrtuDataType.uShort:
504-
x.Value = Math.Round(x.Rate * Wu.Utils.ConvertUtil.GetUInt16FromBigEndianBytes(responseFrame.RegisterValues, (x.RegisterAddr - requestFrame.StartAddr) * 2), 2);
507+
x.Value = MathExtension.Round2(x.Rate * ModbusUtils.GetUInt16(responseFrame.RegisterValues, bytenum, device.ModbusByteOrder));
505508
break;
506509
case MrtuDataType.Short:
507-
x.Value = Math.Round(x.Rate * Wu.Utils.ConvertUtil.GetInt16FromBigEndianBytes(responseFrame.RegisterValues, (x.RegisterAddr - requestFrame.StartAddr) * 2), 2);
510+
x.Value = MathExtension.Round2(x.Rate * ModbusUtils.GetInt16(responseFrame.RegisterValues, bytenum, device.ModbusByteOrder));
508511
break;
509512
case MrtuDataType.uInt:
510-
x.Value = Math.Round(x.Rate * Wu.Utils.ConvertUtil.GetUIntFromBigEndianBytes(responseFrame.RegisterValues, (x.RegisterAddr - requestFrame.StartAddr) * 2), 2);
513+
x.Value = MathExtension.Round2(x.Rate * ModbusUtils.GetUInt32(responseFrame.RegisterValues, bytenum, device.ModbusByteOrder));
511514
break;
512515
case MrtuDataType.Int:
513-
x.Value = Math.Round(x.Rate * Wu.Utils.ConvertUtil.GetIntFromBigEndianBytes(responseFrame.RegisterValues, (x.RegisterAddr - requestFrame.StartAddr) * 2), 2);
516+
x.Value = MathExtension.Round2(x.Rate * ModbusUtils.GetInt(responseFrame.RegisterValues, bytenum, device.ModbusByteOrder));
514517
break;
515518
case MrtuDataType.uLong:
516-
x.Value = Math.Round(x.Rate * Wu.Utils.ConvertUtil.GetUInt64FromBigEndianBytes(responseFrame.RegisterValues, (x.RegisterAddr - requestFrame.StartAddr) * 2), 2);
519+
x.Value = MathExtension.Round2(x.Rate * ModbusUtils.GetUInt64(responseFrame.RegisterValues, bytenum, device.ModbusByteOrder));
517520
break;
518521
case MrtuDataType.Long:
519-
x.Value = Math.Round(x.Rate * Wu.Utils.ConvertUtil.GetInt64FromBigEndianBytes(responseFrame.RegisterValues, (x.RegisterAddr - requestFrame.StartAddr) * 2), 2);
522+
x.Value = MathExtension.Round2(x.Rate * ModbusUtils.GetInt64(responseFrame.RegisterValues, bytenum, device.ModbusByteOrder));
520523
break;
521524
case MrtuDataType.Float:
522-
x.Value = Math.Round(x.Rate * Wu.Utils.ConvertUtil.GetFloatFromBigEndianBytes(responseFrame.RegisterValues, (x.RegisterAddr - requestFrame.StartAddr) * 2), 2);
525+
x.Value = MathExtension.Round2(x.Rate * ModbusUtils.GetFloat(responseFrame.RegisterValues, bytenum, device.ModbusByteOrder));
523526
break;
524527
case MrtuDataType.Double:
525-
x.Value = Math.Round(x.Rate * Wu.Utils.ConvertUtil.GetDouble(responseFrame.RegisterValues, (x.RegisterAddr - requestFrame.StartAddr) * 2), 2);
528+
x.Value = MathExtension.Round2(x.Rate * ModbusUtils.GetDouble(responseFrame.RegisterValues, bytenum, device.ModbusByteOrder));
526529
break;
527530
case MrtuDataType.Hex:
528531
break;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<UserControl x:Class="Wu.CommTool.Modules.ModbusRtu.Views.DialogViews.MrtuSerialPortsView"
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
5+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
6+
xmlns:local="clr-namespace:Wu.CommTool.Modules.ModbusRtu.Views.DialogViews"
7+
mc:Ignorable="d"
8+
d:DesignHeight="450" d:DesignWidth="800">
9+
<Grid>
10+
11+
</Grid>
12+
</UserControl>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using System.Windows;
7+
using System.Windows.Controls;
8+
using System.Windows.Data;
9+
using System.Windows.Documents;
10+
using System.Windows.Input;
11+
using System.Windows.Media;
12+
using System.Windows.Media.Imaging;
13+
using System.Windows.Navigation;
14+
using System.Windows.Shapes;
15+
16+
namespace Wu.CommTool.Modules.ModbusRtu.Views.DialogViews
17+
{
18+
/// <summary>
19+
/// MrtuSerialPortsView.xaml 的交互逻辑
20+
/// </summary>
21+
public partial class MrtuSerialPortsView : UserControl
22+
{
23+
public MrtuSerialPortsView()
24+
{
25+
InitializeComponent();
26+
}
27+
}
28+
}

Wu.CommTool.Core/Common/ModbusUtils.cs

Lines changed: 115 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,12 @@ public static int GetMrtuDataTypeLengthForRead(MrtuDataType mrtuDataType)
9090
}
9191

9292
/// <summary>
93-
/// 字节序转换
93+
/// 字节序转换 输入字节序视为ABCD, 再根据输入字节序进行转换
9494
/// </summary>
9595
/// <param name="val"></param>
9696
/// <param name="byteOrder"></param>
9797
/// <returns></returns>
98-
public static byte[] ByteOrder(byte[] val, ModbusByteOrder byteOrder)
98+
public static byte[] ConvertByteOrder(byte[] val, ModbusByteOrder byteOrder)
9999
{
100100
//若为单字节的则直接返回
101101
if (val.Length <= 1)
@@ -152,7 +152,7 @@ public static byte[] ByteOrder(byte[] val, ModbusByteOrder byteOrder)
152152
/// <returns></returns>
153153
public static List<ComPort> GetComPorts()
154154
{
155-
List<ComPort > ports = [];
155+
List<ComPort> ports = [];
156156
//查找Com口
157157
using System.Management.ManagementObjectSearcher searcher = new("select * from Win32_PnPEntity where Name like '%(COM[0-999]%'");
158158
var hardInfos = searcher.Get();
@@ -204,4 +204,116 @@ public static bool IsModbusCrcOk(List<byte> frame)
204204
{
205205
return IsModbusCrcOk(frame.ToArray());
206206
}
207+
208+
209+
210+
211+
#region 字节数组处理
212+
/// <summary>
213+
/// 截取字节数组
214+
/// </summary>
215+
/// <param name="input">字节数组</param>
216+
/// <param name="skip">起始位置</param>
217+
/// <param name="take">读取数量</param>
218+
/// <returns></returns>
219+
public static byte[] TakeBytes(byte[] input, int skip, int take)
220+
{
221+
return input.Skip(skip).Take(take).ToArray();
222+
}
223+
224+
/// <summary>
225+
/// 从字节数据中截取 16位无符号整型
226+
/// </summary>
227+
/// <param name="data"></param>
228+
/// <param name="p"></param>
229+
/// <param name="modbusByteOrder"></param>
230+
/// <returns></returns>
231+
public static ushort GetUInt16(byte[] data, int p, ModbusByteOrder modbusByteOrder = ModbusByteOrder.DCBA)
232+
{
233+
return BitConverter.ToUInt16(ConvertByteOrder(TakeBytes(data, p, 2), modbusByteOrder), 0);
234+
}
235+
236+
/// <summary>
237+
/// 从字节数据中截取 16位有符号整型
238+
/// </summary>
239+
/// <param name="data"></param>
240+
/// <param name="p"></param>
241+
/// <param name="modbusByteOrder"></param>
242+
/// <returns></returns>
243+
public static short GetInt16(byte[] data, int p, ModbusByteOrder modbusByteOrder = ModbusByteOrder.DCBA)
244+
{
245+
return BitConverter.ToInt16(ConvertByteOrder(TakeBytes(data, p, 2), modbusByteOrder), 0);
246+
}
247+
248+
/// <summary>
249+
/// 从字节数据中截取 32位无符号整型
250+
/// </summary>
251+
/// <param name="data"></param>
252+
/// <param name="p"></param>
253+
/// <param name="modbusByteOrder"></param>
254+
/// <returns></returns>
255+
public static uint GetUInt32(byte[] data, int p, ModbusByteOrder modbusByteOrder = ModbusByteOrder.DCBA)
256+
{
257+
return BitConverter.ToUInt32(ConvertByteOrder(TakeBytes(data, p, 4), modbusByteOrder), 0);
258+
}
259+
260+
/// <summary>
261+
/// 从字节数据中截取 32位有符号整型
262+
/// </summary>
263+
/// <param name="data"></param>
264+
/// <param name="p"></param>
265+
/// <param name="modbusByteOrder"></param>
266+
/// <returns></returns>
267+
public static int GetInt(byte[] data, int p, ModbusByteOrder modbusByteOrder = ModbusByteOrder.DCBA)
268+
{
269+
return BitConverter.ToInt32(ConvertByteOrder(TakeBytes(data, p, 4), modbusByteOrder), 0);
270+
}
271+
272+
/// <summary>
273+
/// 从字节数组中指定位置读取float数据 32位浮点型
274+
/// </summary>
275+
/// <param name="data"></param>
276+
/// <param name="p">指示数据在数组中的起始位置</param>
277+
/// <returns></returns>
278+
public static float GetFloat(byte[] data, int p, ModbusByteOrder modbusByteOrder = ModbusByteOrder.DCBA)
279+
{
280+
return BitConverter.ToSingle(ConvertByteOrder(TakeBytes(data, p, 4), modbusByteOrder), 0);
281+
}
282+
283+
/// <summary>
284+
/// 从大端数组指定位置读取unsigned Long数据
285+
/// </summary>
286+
/// <param name="data"></param>
287+
/// <param name="p"></param>
288+
/// <param name="modbusByteOrder"></param>
289+
/// <returns></returns>
290+
public static ulong GetUInt64(byte[] data, int p, ModbusByteOrder modbusByteOrder = ModbusByteOrder.DCBA)
291+
{
292+
return BitConverter.ToUInt64(ConvertByteOrder(TakeBytes(data, p, 8), modbusByteOrder), 0);
293+
}
294+
295+
/// <summary>
296+
/// 从大端数组指定位置读取Long数据
297+
/// </summary>
298+
/// <param name="data"></param>
299+
/// <param name="p"></param>
300+
/// /// <param name="modbusByteOrder"></param>
301+
/// <returns></returns>
302+
public static long GetInt64(byte[] data, int p, ModbusByteOrder modbusByteOrder = ModbusByteOrder.DCBA)
303+
{
304+
return BitConverter.ToInt64(ConvertByteOrder(TakeBytes(data, p, 8), modbusByteOrder), 0);
305+
}
306+
307+
/// <summary>
308+
/// 从大端数组指定位置读取Double数据
309+
/// </summary>
310+
/// <param name="data"></param>
311+
/// <param name="p"></param>
312+
/// /// <param name="modbusByteOrder"></param>
313+
/// <returns></returns>
314+
public static double GetDouble(byte[] data, int p, ModbusByteOrder modbusByteOrder = ModbusByteOrder.DCBA)
315+
{
316+
return BitConverter.ToDouble(ConvertByteOrder(TakeBytes(data, p, 8), modbusByteOrder), 0);
317+
}
318+
#endregion
207319
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace Wu.CommTool.Core.Extensions;
2+
3+
/// <summary>
4+
/// System.Math 扩展
5+
/// </summary>
6+
public static class MathExtension
7+
{
8+
9+
public static double Round2(this double value)
10+
{
11+
return Math.Round(value, 2);
12+
}
13+
14+
public static double Round3(this double value)
15+
{
16+
return Math.Round(value, 3);
17+
}
18+
}

0 commit comments

Comments
 (0)