| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading;
- using System.Threading.Tasks;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Media;
- using System.Windows.Shapes;
- using AutoFocusTool.Devices;
- using AutoFocusTool.Imaging;
- using AutoFocusTool.Serial;
- using SerialCamera = AutoFocusTool.Camera.Camera;
- namespace AutoFocusTool
- {
- public partial class MainWindow : Window
- {
- private readonly DeviceScanner _scanner = new DeviceScanner();
- private List<HouseDevice> _houses = new List<HouseDevice>();
- private SerialCamera _camera; // 当前连接的相机
- private HouseMotor _motor; // 当前连接的串口马达+光源
- private HouseDevice _current; // 当前舱室
- private CancellationTokenSource _liveCts; // 实时预览
- private CancellationTokenSource _scanCts; // Z扫描
- private volatile bool _busy; // 串口忙(避免并发命令)
- private int _lastZ = -1, _lastH = -1, _curWell = -1; // 最近回读的Z/水平位置、当前well(供参数显示)
- private int _camWidth = 2592, _camHeight = 1944; // MVC2000 原生分辨率(参考图实测),勿用1600x1200否则画面被裁中央
- private List<(int z, double score)> _curve = new List<(int, double)>();
- public MainWindow()
- {
- InitializeComponent();
- _scanner.Log = Log;
- Closing += (s, e) => Cleanup();
- Log("程序启动。先【扫描设备】,选舱室后【连接】。");
- }
- // ───────────────────────── 日志 ─────────────────────────
- private void Log(string msg)
- {
- void Append()
- {
- string line = $"{DateTime.Now:HH:mm:ss} {msg}\n";
- TxtLog.AppendText(line);
- TxtLog.ScrollToEnd();
- }
- if (Dispatcher.CheckAccess()) Append();
- else Dispatcher.BeginInvoke((Action)Append);
- }
- // ───────────────────────── 扫描设备 ─────────────────────────
- private async void BtnScan_Click(object sender, RoutedEventArgs e)
- {
- BtnScan.IsEnabled = false;
- Log("开始扫描设备(枚举相机 + 扫串口握手)...");
- try
- {
- var houses = await Task.Run(() => _scanner.ScanAll());
- _houses = houses;
- CmbHouse.Items.Clear();
- foreach (var h in houses)
- CmbHouse.Items.Add(h.ToString());
- if (houses.Count > 0)
- {
- CmbHouse.SelectedIndex = 0;
- Log($"扫描完成,发现 {houses.Count} 个舱室。");
- }
- else
- {
- Log("未发现舱室。检查串口连接/相机USB/驱动。");
- }
- }
- catch (Exception ex)
- {
- Log($"扫描异常: {ex.Message}");
- }
- finally
- {
- BtnScan.IsEnabled = true;
- }
- }
- // ───────────────────────── 连接 / 断开 ─────────────────────────
- private void BtnConnect_Click(object sender, RoutedEventArgs e)
- {
- int idx = CmbHouse.SelectedIndex;
- if (idx < 0 || idx >= _houses.Count)
- {
- Log("请先扫描并选择一个舱室。");
- return;
- }
- var h = _houses[idx];
- try
- {
- // 串口
- _motor = new HouseMotor(h.PortName) { Log = Log };
- if (!_motor.Open())
- {
- Log($"串口 {h.PortName} 打开失败。");
- _motor = null;
- return;
- }
- _motor.MotorDelayMs = ParseInt(TxtMotorDelay.Text, 1500);
- // 相机(若配对到)
- if (h.HasCamera)
- {
- _camera = new SerialCamera(h.CcdIndex, _camWidth, _camHeight, ParseInt(TxtExposure.Text, 400));
- int init = _camera.Init(
- (byte)ParseInt(TxtGainR.Text, 25),
- (byte)ParseInt(TxtGainG.Text, 14),
- (byte)ParseInt(TxtGainB.Text, 25));
- if (init == 0)
- {
- _camera.SetOpMode(0); // 拍照模式
- Log($"相机#{h.CcdIndex} 已连接。");
- }
- else
- {
- Log($"相机#{h.CcdIndex} 初始化失败(code={init}),仅串口可用。");
- _camera.Dispose();
- _camera = null;
- }
- }
- else
- {
- Log("该舱室未配对相机,仅串口可用。");
- }
- _current = h;
- TxtConnState.Text = $"已连接 舱室{h.HouseSn}";
- TxtConnState.Foreground = Brushes.LightGreen;
- ControlPanel.IsEnabled = true;
- BtnConnect.IsEnabled = false;
- BtnDisconnect.IsEnabled = true;
- BtnScan.IsEnabled = false;
- InitWellSelectors(); // 填充well下拉 + 16个勾选框
- RefreshPositions();
- }
- catch (Exception ex)
- {
- Log($"连接异常: {ex.Message}");
- }
- }
- private void BtnDisconnect_Click(object sender, RoutedEventArgs e)
- {
- Cleanup();
- TxtConnState.Text = "未连接";
- TxtConnState.Foreground = Brushes.Salmon;
- ControlPanel.IsEnabled = false;
- BtnConnect.IsEnabled = true;
- BtnDisconnect.IsEnabled = false;
- BtnScan.IsEnabled = true;
- Log("已断开。");
- }
- private void Cleanup()
- {
- try { _liveCts?.Cancel(); } catch { }
- try { _scanCts?.Cancel(); } catch { }
- try { if (_motor != null && _camera != null) _motor.CloseLED(); } catch { }
- try { _camera?.Dispose(); } catch { }
- try { _motor?.Dispose(); } catch { }
- _camera = null;
- _motor = null;
- _current = null;
- }
- private static int ParseInt(string s, int def)
- => int.TryParse(s?.Trim(), out int v) ? v : def;
- }
- }
|