This commit is contained in:
xyy
2026-04-02 14:34:29 +08:00
parent e25f4b0e2f
commit 2b3da1e2e5
10 changed files with 245 additions and 92 deletions

View File

@@ -35,6 +35,9 @@ namespace MembranePoreTester.Communication
public ushort PressureUpperLimit { get; set; } = 300; // 加压上限 D300 public ushort PressureUpperLimit { get; set; } = 300; // 加压上限 D300
public ushort PressureRate { get; set; } = 280; // 加压速率 D280 public ushort PressureRate { get; set; } = 280; // 加压速率 D280
public ushort HPCoeff11 { get; set; } = 74; // 1工位加压速率
// 高压/低压系数(每个工位独立) // 高压/低压系数(每个工位独立)
public ushort HPCoeff1 { get; set; } = 3120; // 工位1 高压系数 public ushort HPCoeff1 { get; set; } = 3120; // 工位1 高压系数
public ushort LPCoeff1 { get; set; } = 3122; // 工位1 低压系数 public ushort LPCoeff1 { get; set; } = 3122; // 工位1 低压系数

View File

@@ -49,6 +49,9 @@ namespace MembranePoreTester.Models
public DateTime TestDate { get; set; } = DateTime.Now; public DateTime TestDate { get; set; } = DateTime.Now;
public string Tester { get; set; } public string Tester { get; set; }
public string SpeedRate1 { get; set; }
public double MaxPoreSize => CalculateMaxPore(); public double MaxPoreSize => CalculateMaxPore();
private double CalculateMaxPore() private double CalculateMaxPore()

View File

@@ -119,6 +119,7 @@ namespace MembranePoreTester.ViewModels
if (StationId > 0 && !IsDisposed) if (StationId > 0 && !IsDisposed)
{ {
await ReadCurrentPlcAsync(); await ReadCurrentPlcAsync();
await ReadSpeedRateAsync(); // 新增:读取加压速率
} }
}; };
_timer.Start(); _timer.Start();
@@ -132,6 +133,36 @@ namespace MembranePoreTester.ViewModels
//); //);
} }
// 新增:读取加压速率并赋值给 Record.SpeedRate1
private async Task ReadSpeedRateAsync()
{
try
{
float speedRate = 0;
switch (StationId)
{
case 1:
speedRate = await _plcService. ReadFloatAsync(_plcConfig.HPCoeff11);
Record.SpeedRate1 = speedRate.ToString("F3");
break;
//case 2:
// speedRate = await _plcService.ReadFloatAsync(_plcConfig.PressureRate2);
// Record.SpeedRate2 = speedRate.ToString("F3");
// break;
//case 3:
// speedRate = await _plcService.ReadFloatAsync(_plcConfig.PressureRate3);
// Record.SpeedRate3 = speedRate.ToString("F3");
// break;
}
OnPropertyChanged(nameof(Record));
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"读取加压速率失败: {ex.Message}");
}
}
public override void Dispose() public override void Dispose()
{ {
_timer?.Stop(); _timer?.Stop();

View File

@@ -121,8 +121,16 @@ namespace MembranePoreTester.ViewModels
{ {
if (SetProperty(ref _pressureUpperLimit, value)) if (SetProperty(ref _pressureUpperLimit, value))
{ {
if (HighLowPressure == "低压")
{
if (value > 200)
{
MessageBox.Show("低压模式,加压上限不能超过200!");
return;
}
}
// 值改变时写入PLC // 值改变时写入PLC
_ = WriteFloatAsync(_plcConfig.PressureUpperLimit, (float)value); _ = _plcService.WriteMultipleRegistersAsync(_plcConfig.PressureUpperLimit, (float)value);
} }
} }
} }
@@ -135,7 +143,7 @@ namespace MembranePoreTester.ViewModels
if (SetProperty(ref _pressureRate, value)) if (SetProperty(ref _pressureRate, value))
{ {
// 值改变时写入PLC // 值改变时写入PLC
_ = WriteFloatAsync(_plcConfig.PressureRate, (float)value); _ = _plcService.WriteMultipleRegistersAsync(_plcConfig.PressureRate, (float)value);
} }
} }
} }
@@ -148,6 +156,9 @@ namespace MembranePoreTester.ViewModels
float upperLimit = await _plcService.ReadFloatAsync(_plcConfig.PressureUpperLimit); float upperLimit = await _plcService.ReadFloatAsync(_plcConfig.PressureUpperLimit);
float rate = await _plcService.ReadFloatAsync(_plcConfig.PressureRate); float rate = await _plcService.ReadFloatAsync(_plcConfig.PressureRate);
Application.Current.Dispatcher.Invoke(() => Application.Current.Dispatcher.Invoke(() =>
{ {
PressureUpperLimit = upperLimit; PressureUpperLimit = upperLimit;

View File

@@ -104,14 +104,16 @@ namespace MembranePoreTester.ViewModels
if (TestMode.Contains("湿膜")) if (TestMode.Contains("湿膜"))
{ {
float rawFlow = await _plcService.ReadWetFlowAsync(); float rawFlow = await _plcService.ReadWetFlowAsync();
flow = Math.Round(rawFlow, 2); flow = Math.Round(ConvertFlowByMode(rawFlow), 2);
} }
else else
{ {
float rawFlow = await _plcService.ReadDryFlowAsync(); float rawFlow = await _plcService.ReadDryFlowAsync();
flow = Math.Round(rawFlow, 2); flow = Math.Round(ConvertFlowByMode(rawFlow), 2);
} }
CurrentFlow = flow;
// 3. 直接新增一行(不查找相同压力) // 3. 直接新增一行(不查找相同压力)
var newPoint = new Models.DataPoint var newPoint = new Models.DataPoint
{ {
@@ -340,12 +342,12 @@ namespace MembranePoreTester.ViewModels
if (TestMode == "湿膜") if (TestMode == "湿膜")
{ {
float rawWet = await _plcService.ReadWetFlowAsync(); float rawWet = await _plcService.ReadWetFlowAsync();
SelectedDataPoint.WetFlow = rawWet; SelectedDataPoint.WetFlow = ConvertFlowByMode(rawWet);
} }
else else
{ {
float rawDry = await _plcService.ReadDryFlowAsync(); float rawDry = await _plcService.ReadDryFlowAsync();
SelectedDataPoint.DryFlow = rawDry; SelectedDataPoint.DryFlow = ConvertFlowByMode(rawDry);
} }
} }
else else
@@ -355,12 +357,12 @@ namespace MembranePoreTester.ViewModels
if (TestMode == "湿膜") if (TestMode == "湿膜")
{ {
float rawWet = await _plcService.ReadWetFlowAsync(); float rawWet = await _plcService.ReadWetFlowAsync();
newPoint.WetFlow = rawWet; newPoint.WetFlow = ConvertFlowByMode(ConvertFlowByMode(rawWet));
} }
else else
{ {
float rawDry = await _plcService.ReadDryFlowAsync(); float rawDry = await _plcService.ReadDryFlowAsync();
newPoint.DryFlow = rawDry; newPoint.DryFlow = ConvertFlowByMode(rawDry);
} }
Record.DataPoints.Add(newPoint); Record.DataPoints.Add(newPoint);
} }
@@ -405,6 +407,7 @@ namespace MembranePoreTester.ViewModels
// 修改 Calculate 方法: // 修改 Calculate 方法:
private void Calculate() private void Calculate()
{ {
var cleanedPoints = CleanDataPoints(Record.DataPoints);
if (Record.DataPoints.Count < 2) return; if (Record.DataPoints.Count < 2) return;
AveragePoreSize = PoreDistributionAnalysis.CalculateAveragePore( AveragePoreSize = PoreDistributionAnalysis.CalculateAveragePore(
@@ -412,6 +415,30 @@ namespace MembranePoreTester.ViewModels
RangePercentage = PoreDistributionAnalysis.CalculatePoreRangePercentage( RangePercentage = PoreDistributionAnalysis.CalculatePoreRangePercentage(
Record.DataPoints, Record.PressureUnit, Record.Liquid, LowerPore, UpperPore); Record.DataPoints, Record.PressureUnit, Record.Liquid, LowerPore, UpperPore);
// 可选:提示用户过滤了多少无效点
int invalidCount = Record.DataPoints.Count - cleanedPoints.Count;
if (invalidCount > 0)
{
MessageBox.Show($"已自动过滤 {invalidCount} 个无效数据点");
System.Diagnostics.Debug.WriteLine($"已自动过滤 {invalidCount} 个无效数据点");
}
}
private List<Models.DataPoint> CleanDataPoints(IEnumerable<Models.DataPoint> points)
{
return points
.Where(p => p.Pressure > 0.001) // 移除压力接近0的点
.Where(p => !(Math.Abs(p.WetFlow) < 0.001 && Math.Abs(p.DryFlow) < 0.001)) // 移除双零流量点
.GroupBy(p => Math.Round(p.Pressure, 2)) // 按压力四舍五入分组(避免重复压力)
.Select(g => new Models.DataPoint
{
Pressure = g.Key,
WetFlow = g.Max(x => x.WetFlow), // 取最大值避免0覆盖有效值
DryFlow = g.Max(x => x.DryFlow)
})
.OrderBy(p => p.Pressure)
.ToList();
} }
private void GenerateReport() private void GenerateReport()
@@ -681,6 +708,16 @@ namespace MembranePoreTester.ViewModels
public ICommand ClearAllCommand { get; } public ICommand ClearAllCommand { get; }
private double _currentFlow;
public double CurrentFlow
{
get => _currentFlow;
set => SetProperty(ref _currentFlow, value);
}
// 修改命令初始化(构造函数中) // 修改命令初始化(构造函数中)
@@ -695,5 +732,17 @@ namespace MembranePoreTester.ViewModels
} }
} }
private double ConvertFlowByMode(double rawFlow)
{
// 如果当前选择的是小流量模式则需要除以1000因为PLC可能存储的是mL/min
if (SelectedPressureMode != null && SelectedPressureMode.Text.Contains("小流量"))
return rawFlow / 1000.0;
else
return rawFlow;
}
} }
} }

View File

@@ -24,6 +24,7 @@
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="*"/> <RowDefinition Height="*"/>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<!-- 输入区域 --> <!-- 输入区域 -->
@@ -39,19 +40,23 @@
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="膜类型:"/> <Label Grid.Row="0" Grid.Column="0" Content="膜类型:"/>
<ComboBox Grid.Row="0" Grid.Column="1" ItemsSource="{Binding MembraneTypes}" SelectedItem="{Binding Record.SampleType}" Margin="5"/> <ComboBox Grid.Row="0" Grid.Column="1" ItemsSource="{Binding MembraneTypes}" SelectedItem="{Binding Record.SampleType}" Margin="5"/>
<Label Grid.Row="0" Grid.Column="2" Content="规格:"/> <!--<Label Grid.Row="0" Grid.Column="2" Content="规格:"/>
<TextBox Grid.Row="0" Grid.Column="3" Text="{Binding Record.SampleSpec}" Margin="5"/> <TextBox Grid.Row="0" Grid.Column="3" Text="{Binding Record.SampleSpec}" Margin="5"/>-->
<Label Grid.Row="1" Grid.Column="0" Content="室温(°C):"/> <!--<Label Grid.Row="1" Grid.Column="0" Content="室温(°C):"/>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Record.RoomTemperature}" Margin="5"/> <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Record.RoomTemperature}" Margin="5"/>-->
<Label Grid.Row="1" Grid.Column="2" Content="浸润时间(h):"/> <Label Grid.Row="1" Grid.Column="0" Content="浸润时间(h):"/>
<TextBox Grid.Row="1" Grid.Column="3" Text="{Binding Record.SoakingTime}" Margin="5"/> <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Record.SoakingTime}" Margin="5"/>
<Label Grid.Row="2" Grid.Column="0" Content="加压速率:"/>
<TextBox Grid.Row="2" Grid.Column="1" IsEnabled="False" Text="{Binding Record.SpeedRate1}" Margin="5"/>
</Grid> </Grid>
</GroupBox> </GroupBox>
@@ -74,7 +79,7 @@
<Label Content="泡点压力(Pa)" FontWeight="Normal" Margin="5,0,0,0"/> <Label Content="泡点压力(Pa)" FontWeight="Normal" Margin="5,0,0,0"/>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Record.BubblePointPressure}" Width="150" Margin="5"/> <TextBox Text="{Binding Record.BubblePointPressure}" Width="150" Margin="5"/>
<Button Content="涨破" Command="{Binding ReadPlcCommand}" Padding="10,5" Margin="5" Background="#FF9800"/> <Button Content="出泡" Command="{Binding ReadPlcCommand}" Padding="10,5" Margin="5" Background="#FF9800"/>
<ComboBox ItemsSource="{Binding PressureUnits}" SelectedItem="{Binding Record.PressureUnit}" Width="80" Margin="5"/> <ComboBox ItemsSource="{Binding PressureUnits}" SelectedItem="{Binding Record.PressureUnit}" Width="80" Margin="5"/>
<Button Content="计算最大孔径" Command="{Binding CalculateCommand}" Padding="10,5" Margin="5" Background="#2196F3"/> <Button Content="计算最大孔径" Command="{Binding CalculateCommand}" Padding="10,5" Margin="5" Background="#2196F3"/>
</StackPanel> </StackPanel>

View File

@@ -90,7 +90,7 @@
</Style.Triggers> </Style.Triggers>
</Style> </Style>
</Window.Resources> </Window.Resources>
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<DockPanel> <DockPanel>
<!-- 顶部历史记录栏 --> <!-- 顶部历史记录栏 -->
@@ -168,5 +168,8 @@
</DataTemplate> </DataTemplate>
</TabControl.ContentTemplate> </TabControl.ContentTemplate>
</TabControl> </TabControl>
</DockPanel> </DockPanel>
</ScrollViewer>
</Window> </Window>

View File

@@ -7,6 +7,33 @@
<StackPanel Margin="10"> <StackPanel Margin="10">
<!--<GroupBox Header="加压速率">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
--><!-- 预留空白 --><!--
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" FontWeight="Bold">工位</Label>
<Label Grid.Row="0" Grid.Column="1" FontWeight="Bold">加压速率</Label>
<Label Grid.Row="1" Grid.Column="0">工位1</Label>
<TextBox x:Name="txtHPCoeff11" Grid.Row="1" Grid.Column="1" Width="80" HorizontalAlignment="Left"/>
</Grid>
</GroupBox>-->
<GroupBox Header="高压/低压系数"> <GroupBox Header="高压/低压系数">
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>

View File

@@ -32,6 +32,7 @@ namespace MembranePoreTester.Views
//[txtPressureRate] = (_config.PressureRate, "加压速率"), //[txtPressureRate] = (_config.PressureRate, "加压速率"),
//[txtPressureCoeff] = (_config.PressureCoeff, "加压系数"), //[txtPressureCoeff] = (_config.PressureCoeff, "加压系数"),
//[txtHPCoeff11] = (_config.HPCoeff11, "工位1加压速率"),
[txtHPCoeff1] = (_config.HPCoeff1, "工位1高压系数"), [txtHPCoeff1] = (_config.HPCoeff1, "工位1高压系数"),
[txtLPCoeff1] = (_config.LPCoeff1, "工位1低压系数"), [txtLPCoeff1] = (_config.LPCoeff1, "工位1低压系数"),
[txtHPCoeff2] = (_config.HPCoeff2, "工位2高压系数"), [txtHPCoeff2] = (_config.HPCoeff2, "工位2高压系数"),

View File

@@ -124,16 +124,17 @@
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<!-- 新增第5行 -->
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="膜类型:"/> <Label Grid.Row="0" Grid.Column="0" Content="膜类型:"/>
<ComboBox Grid.Row="0" Grid.Column="1" ItemsSource="{Binding MembraneTypes}" <ComboBox Grid.Row="0" Grid.Column="1" ItemsSource="{Binding MembraneTypes}"
SelectedItem="{Binding Record.SampleType}"/> SelectedItem="{Binding Record.SampleType}"/>
<!--<Label Grid.Row="0" Grid.Column="2" Content="规格:"/>
<TextBox Grid.Row="0" Grid.Column="3" Text="{Binding Record.SampleSpec}"/>-->
<Label Grid.Row="0" Grid.Column="2" Content="室温(°C):"/>
<TextBox Grid.Row="0" Grid.Column="3" Text="{Binding Record.RoomTemperature}"/> <!--<Label Grid.Row="0" Grid.Column="2" Content="室温(°C):"/>
<TextBox Grid.Row="0" Grid.Column="3" Text="{Binding Record.RoomTemperature}"/>-->
<Label Grid.Row="1" Grid.Column="2" Content="浸润时间(h):"/> <Label Grid.Row="1" Grid.Column="2" Content="浸润时间(h):"/>
<TextBox Grid.Row="1" Grid.Column="3" Text="{Binding Record.SoakingTime}"/> <TextBox Grid.Row="1" Grid.Column="3" Text="{Binding Record.SoakingTime}"/>
@@ -162,6 +163,25 @@
Width="90" Width="90"
HorizontalAlignment="Center" HorizontalAlignment="Center"
Margin="0,5,5,5"/> Margin="0,5,5,5"/>
<!--<StackPanel Orientation="Horizontal" Grid.Row="4">
<TextBlock Text="实时流量:" VerticalAlignment="Center" Margin="0,0,5,0"/>
<TextBox Text="{Binding CurrentFlow, StringFormat=F2}"
IsReadOnly="True"
Width="70"
Background="Transparent"
BorderThickness="0"
FontWeight="Bold"
Foreground="#2196F3"/>
<TextBlock Text="L/min" VerticalAlignment="Center" Margin="5,0,0,0"/>
</StackPanel>-->
<Label Grid.Row="4" Grid.Column="0" Content="实时流量(L/min):"/>
<TextBox Grid.Row="4" Grid.Column="1" IsEnabled="False" Text="{Binding CurrentFlow, StringFormat=F2}"/>
</Grid> </Grid>
</GroupBox> </GroupBox>