This commit is contained in:
xyy
2026-03-26 21:37:34 +08:00
parent b161e884e7
commit 6983e84c36
8 changed files with 178 additions and 30 deletions

View File

@@ -31,8 +31,20 @@ namespace MembranePoreTester.Models
public double BubbleCurrentPressure { get; set; } // 泡点压力(数值)
private double _bubbleCurrentPressure;
// 当前压力 - 添加通知
public double BubbleCurrentPressure
{
get => _bubbleCurrentPressure;
set
{
if (_bubbleCurrentPressure != value)
{
_bubbleCurrentPressure = value;
OnPropertyChanged();
}
}
}
public string PressureUnit { get; set; } // Pa/cmHg/psi
public DateTime TestDate { get; set; } = DateTime.Now;
public string Tester { get; set; }

View File

@@ -93,6 +93,10 @@ namespace MembranePoreTester.ViewModels
public BubblePointViewModel()
{
if (IsInDesignMode())
{
return; // 设计时跳过PLC初始化
}
_plcService = App.PlcService;
_plcConfig = App.PlcConfig;
@@ -113,7 +117,11 @@ namespace MembranePoreTester.ViewModels
_timer.Start();
// 立即读取一次
Task.Run(async () => await ReadCurrentPlcAsync());
Task.Run(async () =>
{
await ReadCurrentPlcAsync();
}
);
}
public override void Dispose()
@@ -122,13 +130,18 @@ namespace MembranePoreTester.ViewModels
base.Dispose();
}
private async Task ReadCurrentPlcAsync()
{
try
{
float rawPressure = await _plcService.ReadPressureAsync(StationId);
Record.BubbleCurrentPressure = rawPressure;
OnPropertyChanged(nameof(Record.BubbleCurrentPressure));
Record.BubbleCurrentPressure =Math.Round( rawPressure,2);
OnPropertyChanged(nameof(Record.BubbleCurrentPressure));
}
catch (Exception ex)
{

View File

@@ -12,9 +12,41 @@ namespace MembranePoreTester.ViewModels
public class MainViewModel : ViewModelBase
{
public ObservableCollection<StationItem> Stations { get; } = new();
public class PressureModeItem
{
public string Text { get; set; }
public int Value { get; set; }
public override string ToString()
{
return Text; // 直接返回要显示的文本
}
}
public class StationItem : ViewModelBase
{
private PressureModeItem _selectedPressureMode;
private List<PressureModeItem> _pressureModeList;
public List<PressureModeItem> PressureModeList => _pressureModeList ??= new List<PressureModeItem>
{
new PressureModeItem { Text = "低压", Value = 1 },
new PressureModeItem { Text = "高压", Value = 0 }
};
public PressureModeItem SelectedPressureMode
{
get => _selectedPressureMode;
set
{
if (SetProperty(ref _selectedPressureMode, value))
{
Task.Run(async () => await WritePressureModeAsync(value?.Text ?? "低压"));
}
}
}
private readonly IPlcService _plcService;
private readonly PlcConfiguration _plcConfig;
private bool _isPressing;
@@ -29,13 +61,13 @@ namespace MembranePoreTester.ViewModels
public string HighLowPressure
{
get => _highLowPressure;
get => _selectedPressureMode?.Text ?? "低压";
set
{
if (SetProperty(ref _highLowPressure, value))
var mode = PressureModeList.FirstOrDefault(m => m.Text == value);
if (mode != null)
{
// 当选择变化时,写入 PLC 压力模式寄存器
Task.Run(async () => await WritePressureModeAsync(value));
SelectedPressureMode = mode;
}
}
}
@@ -46,17 +78,25 @@ namespace MembranePoreTester.ViewModels
set => SetProperty(ref _pressButtonText, value);
}
// 使能状态(只读)
public bool EnableStatus
{
get => _enableStatus;
private set => SetProperty(ref _enableStatus, value);
private set
{
if (SetProperty(ref _enableStatus, value))
{
// 当 EnableStatus 变化时,通知依赖的属性也变化
OnPropertyChanged(nameof(EnableStatusText));
OnPropertyChanged(nameof(EnableStatusColor));
}
}
}
// 使能状态显示文本
public string EnableStatusText => EnableStatus ? "运行中" : "未启动";
// 使能状态显示颜色(绿色表示运行中,灰色表示未启动)
public string EnableStatusColor => EnableStatus ? "Green" : "Gray";
// 使能状态显示颜色(更亮的颜色)
public string EnableStatusColor => EnableStatus ? "#00FF00" : "#FF3333";
// 定时器,用于轮询 M21 状态
private System.Windows.Threading.DispatcherTimer _timer;
@@ -67,8 +107,21 @@ namespace MembranePoreTester.ViewModels
public ICommand StopCommand { get; }
public ICommand EnableCommand { get; } // 备用,但可以使用复选框直接绑定
public StationItem()
{
if (IsInDesignMode())
{
return; // 设计时跳过PLC初始化
}
_plcService = App.PlcService;
_plcConfig = App.PlcConfig;
@@ -81,15 +134,55 @@ namespace MembranePoreTester.ViewModels
_timer.Interval = TimeSpan.FromSeconds(1);
_timer.Tick += async (s, e) => await ReadEnableStatusAsync();
_timer.Start();
// 延迟2秒后读取确保连接稳定
Task.Delay(2000).ContinueWith(async _ =>
{
await ReadPressureModeAsync();
}, TaskScheduler.Default);
}
private async Task ReadPressureModeAsync()
{
try
{
ushort[] values = await _plcService.ReadHoldingRegistersAsync(_plcConfig.PressureModeRegister, 1);
ushort val = values[0];
string newValue = val == 0 ? "高压" : "低压";
Application.Current.Dispatcher.Invoke(() =>
{
// 更新选中项
HighLowPressure = newValue;
});
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"读取压力模式失败: {ex.Message}");
}
}
private async Task TogglePressAsync()
{
_isPressing = !_isPressing;
await WriteCoilAsync(_plcConfig.PressCoil, _isPressing);
PressButtonText = _isPressing ? "停止加压" : "加压";
}
try
{
// 先读取PLC当前的加压状态
bool currentStatus = await _plcService.ReadCoilAsync(_plcConfig.PressCoil);
// 切换状态
_isPressing = !currentStatus;
// 写入新状态到PLC
await WriteCoilAsync(_plcConfig.PressCoil, _isPressing);
// 更新按钮文字
PressButtonText = _isPressing ? "停止加压" : "加压";
}
catch (Exception ex)
{
MessageBox.Show($"读取加压状态失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private async Task ReadEnableStatusAsync()
{
@@ -97,6 +190,20 @@ namespace MembranePoreTester.ViewModels
{
bool status = await _plcService.ReadCoilAsync(_plcConfig.EnableCoil); // 读取 M21
EnableStatus = status;
bool pressStatus = await _plcService.ReadCoilAsync(_plcConfig.PressCoil);//这里也要更新加压的按钮状态
_isPressing = pressStatus;
// 在UI线程更新按钮文字
Application.Current.Dispatcher.Invoke(() =>
{
PressButtonText = pressStatus ? "停止加压" : "加压";
});
}
catch (Exception ex)
{

View File

@@ -52,6 +52,12 @@ namespace MembranePoreTester.ViewModels
}
}
public bool IsInDesignMode()
{
return System.ComponentModel.DesignerProperties.GetIsInDesignMode(
new System.Windows.DependencyObject());
}
// 新增:检查是否已释放
protected bool IsDisposed => _disposed;

View File

@@ -27,25 +27,35 @@
<DockPanel>
<!-- 工位控制栏 -->
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="5">
<ComboBox SelectedItem="{Binding HighLowPressure}" Width="80" Margin="5">
<ComboBoxItem IsSelected="True">低压</ComboBoxItem>
<ComboBoxItem >高压</ComboBoxItem>
</ComboBox>
<ComboBox ItemsSource="{Binding PressureModeList}"
SelectedItem="{Binding SelectedPressureMode}" Width="80" Margin="5"/>
<Button Content="启动" Command="{Binding StartCommand}" Width="80" Margin="5"/>
<Button Content="停止" Command="{Binding StopCommand}" Width="80" Margin="5"/>
<Button Content="{Binding PressButtonText}" Command="{Binding PressCommand}" Width="80" Margin="5"/>
<!--<Button Content="涨破" Command="{Binding BurstCommand}" Width="80" Margin="5"/>-->
<!--<CheckBox Content="使能" IsChecked="{Binding EnableChecked}" Margin="5"/>-->
<!-- 原来的复选框 -->
<!-- <CheckBox Content="使能" IsChecked="{Binding EnableChecked}" Margin="5"/> -->
<Button Content="{Binding PressButtonText}" Command="{Binding PressCommand}" Width="80" Margin="5"/>
<!-- 替换为状态指示灯 -->
<StackPanel Orientation="Horizontal" Margin="5">
<Ellipse Width="12" Height="12" Fill="{Binding EnableStatusColor}" Margin="2"/>
<TextBlock Text="{Binding EnableStatusText}" VerticalAlignment="Center"/>
<!-- 带阴影和光泽的圆形指示灯 -->
<Grid Width="18" Height="18" Margin="2">
<Ellipse Fill="{Binding EnableStatusColor}">
<Ellipse.Effect>
<DropShadowEffect BlurRadius="3" ShadowDepth="0" Opacity="0.5"/>
</Ellipse.Effect>
</Ellipse>
<Ellipse Margin="2,2,2,2" Opacity="0.6">
<Ellipse.Fill>
<RadialGradientBrush>
<GradientStop Color="White" Offset="0.2"/>
<GradientStop Color="Transparent" Offset="1"/>
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
</Grid>
<TextBlock Text="{Binding EnableStatusText}" VerticalAlignment="Center" Margin="5,0,0,0"/>
</StackPanel>
</StackPanel>

View File

@@ -14,7 +14,7 @@
"PressureModeRegister": 2, // 压力模式寄存器0=低压1=高压)
// 线圈控制M 元件)
"PressCoil": 100, // 加压线圈M100ON 开始加压OFF 停止
"PressCoil": 140, // 加压线圈M100ON 开始加压OFF 停止
"StartCoil": 20, // 启动线圈M20ON 启动测试程序
"EnableCoil": 21, // 使能线圈M21状态反馈只读
"StopCoil": 7, // 停止线圈M7ON 停止测试

Binary file not shown.

Binary file not shown.