更新
This commit is contained in:
@@ -35,6 +35,9 @@ namespace TabletTester2025.ViewModels
|
||||
private bool _isLoadingDisintegrationSpeed;
|
||||
private bool _isLoadingFriabilityRounds;
|
||||
private bool _isUpdatingFriabilityWeightFromPlc;
|
||||
private bool _isReadingHardnessLiveForce;
|
||||
private int _hardnessGroupNo;
|
||||
private int _currentHardnessGroupNo;
|
||||
|
||||
private readonly List<double> _dissolution1Times = new();
|
||||
private readonly List<double> _dissolution1Values = new();
|
||||
@@ -85,6 +88,7 @@ namespace TabletTester2025.ViewModels
|
||||
|
||||
private List<double> _hardnessResults = new();
|
||||
public ObservableCollection<HardnessSamplePoint> HardnessSamplePoints { get; } = new();
|
||||
public ObservableCollection<HardnessDisplaySamplePoint> HardnessDisplaySamplePoints { get; } = new();
|
||||
|
||||
// 脆碎度
|
||||
[ObservableProperty] private double _weightBefore;
|
||||
@@ -121,6 +125,7 @@ namespace TabletTester2025.ViewModels
|
||||
public IAsyncRelayCommand HardnessUpCommand { get; }
|
||||
public IAsyncRelayCommand HardnessDownCommand { get; }
|
||||
public IAsyncRelayCommand HardnessResetCommand { get; }
|
||||
public IAsyncRelayCommand ClearHardnessRecordsCommand { get; }
|
||||
public IAsyncRelayCommand HardnessForward { get; }//前进
|
||||
public IAsyncRelayCommand HardnessBack { get; }//后退
|
||||
|
||||
@@ -201,6 +206,7 @@ namespace TabletTester2025.ViewModels
|
||||
StartHardnessCommand = new AsyncRelayCommand(RunHardnessAsync);
|
||||
StartFriabilityCommand = new AsyncRelayCommand(RunFriabilityAsync);
|
||||
StartDisintegrationCommand = new AsyncRelayCommand(RunDisintegrationAsync);
|
||||
ClearHardnessRecordsCommand = new AsyncRelayCommand(ClearHardnessRecordsAsync);
|
||||
|
||||
StartDissolutionCommand = new AsyncRelayCommand(StartDissolution1Async);
|
||||
|
||||
@@ -230,6 +236,7 @@ namespace TabletTester2025.ViewModels
|
||||
DissolutionPlotModel.Series.Add(_dissolution1Series);
|
||||
DissolutionPlotModel.Series.Add(_dissolution2Series);
|
||||
|
||||
StartHardnessLiveForcePolling();
|
||||
|
||||
|
||||
HardnessDownCommand = new AsyncRelayCommand(async () =>
|
||||
@@ -246,15 +253,6 @@ namespace TabletTester2025.ViewModels
|
||||
await _plc.WriteCoilAsync(_plcConfig.HardnessStartReset, true);
|
||||
await Task.Delay(100); // 脉冲宽度,可根据PLC程序调整20~100ms
|
||||
await _plc.WriteCoilAsync(_plcConfig.HardnessStartReset, false);
|
||||
_hardnessResults.Clear();
|
||||
HardnessSamplePoints.Clear();
|
||||
HardnessCurrentCount = 0;
|
||||
HardnessAvg = 0;
|
||||
HardnessAverageDeviation = 0;
|
||||
HardnessRSD = 0;
|
||||
HardnessMax = 0;
|
||||
HardnessMin= 0;
|
||||
HardnessShishilizhi = 0;
|
||||
Phase = TestPhase.Idle;
|
||||
|
||||
});
|
||||
@@ -1289,11 +1287,54 @@ namespace TabletTester2025.ViewModels
|
||||
await _plc.WriteCoilAsync(coilAddress, false);
|
||||
}
|
||||
|
||||
private async Task RunHardnessAsync()
|
||||
private void StartHardnessLiveForcePolling()
|
||||
{
|
||||
_hardnessGlobalTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(500) };
|
||||
_hardnessGlobalTimer.Tick += async (_, _) =>
|
||||
{
|
||||
if (_isReadingHardnessLiveForce || Phase == TestPhase.Running)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
_isReadingHardnessLiveForce = true;
|
||||
await ReadHardnessLiveForceAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// The footer connection status already reflects PLC availability; avoid popup noise during idle polling.
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isReadingHardnessLiveForce = false;
|
||||
}
|
||||
};
|
||||
_hardnessGlobalTimer.Start();
|
||||
}
|
||||
|
||||
private Task ClearHardnessRecordsAsync()
|
||||
{
|
||||
if (Phase == TestPhase.Running && CurrentTest == TestType.Hardness)
|
||||
{
|
||||
MessageBox.Show("硬度测试运行中,不能清空记录。");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
ResetCurrentHardnessGroup();
|
||||
HardnessDisplaySamplePoints.Clear();
|
||||
_hardnessGroupNo = 0;
|
||||
_currentHardnessGroupNo = 0;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void StartNewHardnessGroup()
|
||||
{
|
||||
_currentHardnessGroupNo = ++_hardnessGroupNo;
|
||||
ResetCurrentHardnessGroup();
|
||||
}
|
||||
|
||||
private void ResetCurrentHardnessGroup()
|
||||
{
|
||||
if (Phase != TestPhase.Idle) return;
|
||||
CurrentTest = TestType.Hardness;
|
||||
Phase = TestPhase.Running;
|
||||
HardnessPass = false;
|
||||
_hardnessResults.Clear();
|
||||
HardnessSamplePoints.Clear();
|
||||
@@ -1303,6 +1344,14 @@ namespace TabletTester2025.ViewModels
|
||||
HardnessRSD = 0;
|
||||
HardnessMax = 0;
|
||||
HardnessMin = 0;
|
||||
}
|
||||
|
||||
private async Task RunHardnessAsync()
|
||||
{
|
||||
if (Phase != TestPhase.Idle) return;
|
||||
CurrentTest = TestType.Hardness;
|
||||
Phase = TestPhase.Running;
|
||||
StartNewHardnessGroup();
|
||||
|
||||
try
|
||||
{
|
||||
@@ -1313,8 +1362,8 @@ namespace TabletTester2025.ViewModels
|
||||
throw new InvalidOperationException("硬度启动线圈未配置");
|
||||
if (completeCoil == 0)
|
||||
throw new InvalidOperationException("硬度完成线圈未配置");
|
||||
if (_plcConfig.HardnessMax == 0)
|
||||
throw new InvalidOperationException("硬度最大力寄存器未配置");
|
||||
if (ResolveHardnessLiveForceRegister() == 0)
|
||||
throw new InvalidOperationException("硬度实时力寄存器未配置");
|
||||
|
||||
await _plc.WriteFloatAsync(_plcConfig.HardnessSudu, (float)HardnessSudu);
|
||||
await _plc.WriteFloatAsync(_plcConfig.HardnessWeiyi, (float)HardnessWeiyi);
|
||||
@@ -1327,15 +1376,8 @@ namespace TabletTester2025.ViewModels
|
||||
if (completeWasActiveBeforeStart)
|
||||
await WaitForCoilStateAsync(completeCoil, false, TimeSpan.FromSeconds(10), "硬度完成信号未复位");
|
||||
|
||||
await WaitForCoilStateAsync(completeCoil, true, TimeSpan.FromSeconds(120), "等待硬度完成信号超时");
|
||||
double value = await ReadHardnessResultAsync();
|
||||
_hardnessResults.Add(value);
|
||||
HardnessSamplePoints.Add(new HardnessSamplePoint
|
||||
{
|
||||
SequenceNo = _hardnessResults.Count,
|
||||
Value = value,
|
||||
RecordedAt = DateTime.Now
|
||||
});
|
||||
double value = await WaitForHardnessSamplePeakAsync(completeCoil);
|
||||
AddHardnessSample(value);
|
||||
ApplyHardnessStatistics(count);
|
||||
await WaitForCoilStateAsync(completeCoil, false, TimeSpan.FromSeconds(10), "硬度完成信号未回落");
|
||||
}
|
||||
@@ -1375,17 +1417,77 @@ namespace TabletTester2025.ViewModels
|
||||
: (ushort)70;
|
||||
}
|
||||
|
||||
private async Task<double> ReadHardnessResultAsync()
|
||||
private ushort ResolveHardnessLiveForceRegister()
|
||||
{
|
||||
double value = await _plc.ReadFloatAsync(_plcConfig.HardnessMax);
|
||||
if (!double.IsFinite(value) || value <= 0)
|
||||
throw new InvalidOperationException("硬度最大力数据异常");
|
||||
return _plcConfig.HardnessShishilizhi != 0
|
||||
? _plcConfig.HardnessShishilizhi
|
||||
: (ushort)1314;
|
||||
}
|
||||
|
||||
private async Task<double> ReadHardnessLiveForceAsync()
|
||||
{
|
||||
double value = await _plc.ReadFloatAsync(ResolveHardnessLiveForceRegister());
|
||||
if (!double.IsFinite(value) || value < 0)
|
||||
throw new InvalidOperationException("硬度实时力数据异常");
|
||||
|
||||
HardnessValue = value;
|
||||
HardnessShishilizhi = value;
|
||||
return value;
|
||||
}
|
||||
|
||||
private async Task<double> WaitForHardnessSamplePeakAsync(ushort completeCoil)
|
||||
{
|
||||
double peak = 0;
|
||||
DateTime deadline = DateTime.Now.AddSeconds(120);
|
||||
|
||||
while (Phase == TestPhase.Running && DateTime.Now <= deadline)
|
||||
{
|
||||
double liveForce = await ReadHardnessLiveForceAsync();
|
||||
if (liveForce > peak)
|
||||
peak = liveForce;
|
||||
|
||||
if (await _plc.ReadCoilAsync(completeCoil))
|
||||
{
|
||||
double finalForce = await ReadHardnessLiveForceAsync();
|
||||
if (finalForce > peak)
|
||||
peak = finalForce;
|
||||
|
||||
if (peak <= 0)
|
||||
throw new InvalidOperationException("硬度实时力数据异常");
|
||||
|
||||
return peak;
|
||||
}
|
||||
|
||||
await Task.Delay(100);
|
||||
}
|
||||
|
||||
if (Phase != TestPhase.Running)
|
||||
throw new InvalidOperationException("硬度测试已停止,未保存结果");
|
||||
|
||||
throw new TimeoutException("等待硬度完成信号超时");
|
||||
}
|
||||
|
||||
private void AddHardnessSample(double value)
|
||||
{
|
||||
_hardnessResults.Add(value);
|
||||
int sequenceNo = _hardnessResults.Count;
|
||||
DateTime recordedAt = DateTime.Now;
|
||||
|
||||
HardnessValue = value;
|
||||
HardnessSamplePoints.Add(new HardnessSamplePoint
|
||||
{
|
||||
SequenceNo = sequenceNo,
|
||||
Value = value,
|
||||
RecordedAt = recordedAt
|
||||
});
|
||||
HardnessDisplaySamplePoints.Add(new HardnessDisplaySamplePoint
|
||||
{
|
||||
GroupNo = _currentHardnessGroupNo,
|
||||
SequenceNo = sequenceNo,
|
||||
Value = value,
|
||||
RecordedAt = recordedAt
|
||||
});
|
||||
}
|
||||
|
||||
private async Task WaitForCoilStateAsync(ushort coilAddress, bool expectedState, TimeSpan timeout, string timeoutMessage)
|
||||
{
|
||||
DateTime deadline = DateTime.Now.Add(timeout);
|
||||
@@ -1421,6 +1523,9 @@ namespace TabletTester2025.ViewModels
|
||||
|
||||
foreach (var sample in HardnessSamplePoints)
|
||||
sample.DeviationFromAverage = Math.Abs(sample.Value - stats.Average);
|
||||
|
||||
foreach (var sample in HardnessDisplaySamplePoints.Where(s => s.GroupNo == _currentHardnessGroupNo))
|
||||
sample.DeviationFromAverage = Math.Abs(sample.Value - stats.Average);
|
||||
}
|
||||
|
||||
/// 脆碎度测试主逻辑(实时状态显示)
|
||||
|
||||
Reference in New Issue
Block a user