From 76c911084e6e2f3719cac79b31b9ec04be87c176 Mon Sep 17 00:00:00 2001 From: xyy <544939200@qq.com> Date: Mon, 8 Jun 2026 15:48:13 +0800 Subject: [PATCH] --- ViewModels/D7896ViewModel.cs | 177 ++++++++++++++++++++++++++++++++++- 1 file changed, 174 insertions(+), 3 deletions(-) diff --git a/ViewModels/D7896ViewModel.cs b/ViewModels/D7896ViewModel.cs index 17d95b5..68cdfad 100644 --- a/ViewModels/D7896ViewModel.cs +++ b/ViewModels/D7896ViewModel.cs @@ -12,11 +12,14 @@ using PdfSharpCore.Pdf; using System; using System.Collections.ObjectModel; using System.IO; +using System.IO.Ports; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; +using System.Windows.Controls; +using System.Windows.Threading; namespace ASTM_D7896_Tester.ViewModels; @@ -121,6 +124,9 @@ public partial class D7896ViewModel : ObservableObject _th1953Ustd = new Th1963LanService(); StartBackgroundMonitoring(); + + Task.Run(() => initPort()); + } private async void StartBackgroundMonitoring() @@ -200,7 +206,7 @@ public partial class D7896ViewModel : ObservableObject { - + BtnSet(); await _th1963Ustd.ConnectAsync("192.168.1.12", 45454); // 改为实际IP @@ -444,7 +450,7 @@ public partial class D7896ViewModel : ObservableObject // 测量间隔(即使舍弃也等待,让样品恢复) if (validCount < requiredCount && !_stopRequested && attemptCount < maxAttempts) { - try { await Task.Delay(_config.TestParameters.IntervalSeconds * 100, _testCts.Token); } catch (OperationCanceledException) { break; } + try { await Task.Delay(_config.TestParameters.IntervalSeconds * 1000, _testCts.Token); } catch (OperationCanceledException) { break; } } } @@ -776,6 +782,18 @@ public partial class D7896ViewModel : ObservableObject AverageVolumetricHeatCapacity = Measurements.Average(m => m.VolumetricHeatCapacity); } + //[RelayCommand] + //private void Reset() + //{ + // //Measurements.Clear(); + // //AverageThermalConductivity = AverageThermalDiffusivity = AverageVolumetricHeatCapacity = 0; + // //CurrentMeasurementIndex = 0; + // //StatusMessage = "已重置"; + // //TestDateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); + // //TemperatureCurveModel = null; + + //} + [RelayCommand] private void Reset() { @@ -784,7 +802,18 @@ public partial class D7896ViewModel : ObservableObject CurrentMeasurementIndex = 0; StatusMessage = "已重置"; TestDateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); - TemperatureCurveModel = null; + + // 清空曲线:新建一个空白的 PlotModel 替换原来的 + TemperatureCurveModel = new PlotModel + { + Title = "温升与冷却曲线", + Background = OxyColors.White + }; + TemperatureCurveModel.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = "时间 (s)" }); + TemperatureCurveModel.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Title = "温升 (℃)" }); + TemperatureCurveModel.InvalidatePlot(true); + + CurveTitle = "温升曲线"; } [RelayCommand] @@ -1042,4 +1071,146 @@ public partial class D7896ViewModel : ObservableObject } catch { } } + + private SerialPort _serialPort; + private bool _isConnected = false; + + private async Task initPort() + { + + try + { + string port = "COM10"; + int baud = 19200; + _serialPort = new SerialPort(port, baud, Parity.None, 8, StopBits.One); + _serialPort.ReadTimeout = 1000; // 关键:避免永久阻塞 + _serialPort.WriteTimeout = 1000; + _serialPort.Open(); + + _isConnected = true; + + + // 发送配置命令(不输出电流,只设置模式),同样异步等待但不死锁 + await ConfigureOptimalMode(); + } + catch (Exception ex) + { + MessageBox.Show($"连接失败: {ex.Message}"); + _isConnected = false; + } + } + + private async Task ConfigureOptimalMode() + { + // 构造命令:电流 0,但强制 PC 模式和跟踪模式 + byte[] configCmd = new byte[12]; + configCmd[0] = 0xFE; + configCmd[1] = 0xFE; + configCmd[2] = 0x55; // 识别码高 + configCmd[3] = 0xAA; // 识别码低 + configCmd[4] = 0x00; // 电流高字节 (0A) + configCmd[5] = 0x00; // 电流低字节 + configCmd[6] = 0x01; // PC调节模式 + configCmd[7] = 0x01; + configCmd[8] = 0x00; // 开启跟踪模式 + configCmd[9] = 0x00; + configCmd[10] = 0xFF; + configCmd[11] = 0xFF; + + await SendCommandSafe(configCmd); + } + + #region 安全的命令发送(异步读取,不卡UI) + private async Task SendCommandSafe(byte[] command) + { + if (!_isConnected || _serialPort == null || !_serialPort.IsOpen) + { + + return false; + } + + try + { + // 清空缓冲区 + _serialPort.DiscardInBuffer(); + _serialPort.DiscardOutBuffer(); + + // 发送命令 + await _serialPort.BaseStream.WriteAsync(command, 0, command.Length); + + + // 异步读取12字节(带超时) + byte[] buffer = new byte[12]; + int totalRead = 0; + DateTime start = DateTime.Now; + while (totalRead < 12 && (DateTime.Now - start).TotalMilliseconds < 1500) + { + if (_serialPort.BytesToRead > 0) + { + int read = await _serialPort.BaseStream.ReadAsync(buffer, totalRead, 12 - totalRead); + if (read > 0) totalRead += read; + } + else + await Task.Delay(20); + } + + if (totalRead == 12) + { + + // 解析回采电流 (byte4, byte5) + int rawCurrent = (buffer[4] << 8) | buffer[5]; + double actualCurrent = rawCurrent / 1000.0; + + return true; + } + else + { + return false; + } + } + catch (Exception ex) + { + return false; + } + } + + + private async void BtnSet() + { + if (!_isConnected) + { + MessageBox.Show("请先连接串口"); + return; + } + double target = 0.650; + + // 构造12字节电流命令 + int raw = (int)(target * 1000); + byte cmdH = (byte)((raw >> 8) & 0xFF); + byte cmdL = (byte)(raw & 0xFF); + + byte[] currentCmd = new byte[12]; + currentCmd[0] = 0xFE; + currentCmd[1] = 0xFE; + currentCmd[2] = 0x55; + currentCmd[3] = 0xAA; + currentCmd[4] = cmdH; + currentCmd[5] = cmdL; + currentCmd[6] = 0x01; + currentCmd[7] = 1; + currentCmd[8] = 0; + currentCmd[9] = 0x00; + currentCmd[10] = 0xFF; + currentCmd[11] = 0xFF; + + await SendCommandSafe(currentCmd); + } + + + #endregion + + + + + } \ No newline at end of file