From b80edaea78c9b106a33e58b293448e353765507a Mon Sep 17 00:00:00 2001 From: "GukSang.Jin" Date: Tue, 19 May 2026 16:55:00 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B020260519?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Services/ModbusTcpPlcService.cs | 35 +++++++++++++++++++++------------ ViewModels/StationViewModel.cs | 18 ++++++++++++----- Views/ShowData.xaml.cs | 9 ++++----- 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/Services/ModbusTcpPlcService.cs b/Services/ModbusTcpPlcService.cs index 1e059f7..b742660 100644 --- a/Services/ModbusTcpPlcService.cs +++ b/Services/ModbusTcpPlcService.cs @@ -95,7 +95,7 @@ namespace TabletTester2025.Services public async Task ReadFloatAsync(ushort startAddress) { var registers = await ReadHoldingRegistersAsync(startAddress, 2); - return UshortToFloat(registers[1], registers[0]); + return RegistersToFloat(registers[0], registers[1]); } public async Task ReadIntAsync(ushort startAddress) @@ -122,13 +122,10 @@ namespace TabletTester2025.Services public Task WriteFloatAsync(ushort startAddress, float value) { - byte[] bytes = BitConverter.GetBytes(value); - ushort[] registers = - { - (ushort)((bytes[2] << 8) | bytes[3]), - (ushort)((bytes[0] << 8) | bytes[1]) - }; + if (!float.IsFinite(value)) + throw new ArgumentOutOfRangeException(nameof(value), "PLC浮点写入值不能是NaN或Infinity。"); + ushort[] registers = FloatToRegisters(value); return ExecuteAsync(master => master.WriteMultipleRegistersAsync(_config.SlaveId, startAddress, registers)); } @@ -168,16 +165,28 @@ namespace TabletTester2025.Services } } - private static float UshortToFloat(ushort high, ushort low) + private static float RegistersToFloat(ushort highWord, ushort lowWord) { - byte[] bytes = new byte[4]; - bytes[0] = (byte)(high >> 8); - bytes[1] = (byte)(high & 0xFF); - bytes[2] = (byte)(low >> 8); - bytes[3] = (byte)(low & 0xFF); + byte[] bytes = + { + (byte)(lowWord & 0xFF), + (byte)(lowWord >> 8), + (byte)(highWord & 0xFF), + (byte)(highWord >> 8) + }; return BitConverter.ToSingle(bytes, 0); } + private static ushort[] FloatToRegisters(float value) + { + byte[] bytes = BitConverter.GetBytes(value); + return new[] + { + (ushort)((bytes[3] << 8) | bytes[2]), + (ushort)((bytes[1] << 8) | bytes[0]) + }; + } + private void CloseConnection() { try { _master?.Dispose(); } catch { } diff --git a/ViewModels/StationViewModel.cs b/ViewModels/StationViewModel.cs index 3802e48..84f8f16 100644 --- a/ViewModels/StationViewModel.cs +++ b/ViewModels/StationViewModel.cs @@ -1039,8 +1039,8 @@ namespace TabletTester2025.ViewModels try { _isLoadingFriabilityTime = true; - float value = await _plc.ReadFloatAsync(registerAddress); - if (float.IsFinite(value) && value > 0) + int value = await _plc.ReadIntAsync(registerAddress); + if (value > 0) { FriabilityTargetTimeMin = value; } @@ -1108,7 +1108,7 @@ namespace TabletTester2025.ViewModels try { - await _plc.WriteFloatAsync(registerAddress, (float)value); + await _plc.WriteRegisterAsync(registerAddress, ToPlcTimeRegisterValue(value)); } catch { } } @@ -1233,16 +1233,24 @@ namespace TabletTester2025.ViewModels private async Task WriteDisintegrationTimeAsync(double value) { - if (_plcConfig.DisintegrationTime == 0 || value <= 0) + if (_plcConfig.DisintegrationTime == 0 || value <= 0 || !double.IsFinite(value)) return; try { - await _plc.WriteFloatAsync(_plcConfig.DisintegrationTime, (float)value); + await _plc.WriteRegisterAsync(_plcConfig.DisintegrationTime, ToPlcTimeRegisterValue(value)); } catch { } } + private static ushort ToPlcTimeRegisterValue(double value) + { + return (ushort)Math.Clamp( + (int)Math.Round(value, MidpointRounding.AwayFromZero), + 0, + ushort.MaxValue); + } + private async Task WriteDisintegrationSpeedAsync(double value) { if (_plcConfig.DisintegrationSpeed == 0 || value <= 0) diff --git a/Views/ShowData.xaml.cs b/Views/ShowData.xaml.cs index 578b81a..61b7962 100644 --- a/Views/ShowData.xaml.cs +++ b/Views/ShowData.xaml.cs @@ -60,8 +60,7 @@ namespace 片剂四用仪.Views else { float value = await _plc.ReadFloatAsync((ushort)m.Address); - - Dispatcher.Invoke(() => tb.Text = value.ToString("F2")); + Dispatcher.Invoke(() => tb.Text = float.IsFinite(value) ? value.ToString("0.###") : string.Empty); } } @@ -114,9 +113,9 @@ namespace 片剂四用仪.Views } else { - if (double.TryParse(textBox.Text, out double val)) + if (double.TryParse(textBox.Text, out double val) && double.IsFinite(val)) { - textBox.Text = val.ToString("F3"); + textBox.Text = val.ToString("0.###"); await _plc.WriteFloatAsync((ushort)mapping.Address, (float)val); } } @@ -139,7 +138,7 @@ namespace 片剂四用仪.Views new PlcParamMapping("txt_WeightLossRate", 416, PlcParamType.Int), new PlcParamMapping("txt_DisintegrationSpeed", 330, PlcParamType.Float), - new PlcParamMapping("txt_DisintegrationTime", 420, PlcParamType.Float), + new PlcParamMapping("txt_DisintegrationTime", 420, PlcParamType.Int), new PlcParamMapping("txt_DissolutionTime", 430, PlcParamType.Int), new PlcParamMapping("txt_Dissolution1SamplingInterval", 432, PlcParamType.Float),