| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- using System;
- namespace AutoFocusTool.Serial
- {
- /// <summary>
- /// 单舱室马达+光源的语义化控制接口。封装 Protocol+SerialMotor,
- /// 给 UI/对焦逻辑直接调。所有动作同步阻塞到下位机回复。
- ///
- /// 重要:移动是开环+固定延时(motorDelay),下位机回复只代表"收到指令",
- /// 不代表机械停稳。每次移动后等 MotorDelayMs 再抓图,否则运动模糊。
- /// </summary>
- public class HouseMotor : IDisposable
- {
- private readonly SerialMotor _serial;
- /// <summary>电机到位延时(ms),移动后等待机械稳定。真机标定,默认 1500。</summary>
- public int MotorDelayMs { get; set; } = 1500;
- public string PortName => _serial.PortName;
- public bool IsOpen => _serial.IsOpen;
- public Action<string> Log
- {
- get => _serial.Log;
- set => _serial.Log = value;
- }
- public HouseMotor(string portName)
- {
- _serial = new SerialMotor(portName);
- }
- public bool Open() => _serial.Open();
- public void Close() => _serial.Close();
- /// <summary>握手,返回下位机自报的 houseSn(失败 -1)。</summary>
- public int ShakeHands()
- {
- var r = _serial.Send(Protocol.ShakeHands());
- return r == null ? -1 : Protocol.ParseShakeHands(r);
- }
- /// <summary>读本舱绑定的相机序列号 CCDSN(EEPROM,int)。失败 -1。</summary>
- public int ReadCCDSN()
- {
- var r = _serial.Send(Protocol.GetCCDSN());
- return r == null ? -1 : Protocol.ParseEepromInt(r);
- }
- /// <summary>读 EEPROM 灯光亮度(只读)。失败 -1。</summary>
- public int ReadLightBrightness()
- {
- var r = _serial.Send(Protocol.ReadLightBrightness());
- return r == null ? -1 : Protocol.ParseEepromInt(r);
- }
- /// <summary>读第 wellNum(1-16) 个well的水平电机位置脉冲(EEPROM)。失败 -1。</summary>
- public int ReadWellHorizontalPos(int wellNum)
- {
- var r = _serial.Send(Protocol.ReadWellHorizontalPos(wellNum));
- return r == null ? -1 : Protocol.ParseEepromInt(r);
- }
- /// <summary>
- /// 转动培养皿到第 wellNum(1-16) 个well对准相机:读EEPROM该well位置 → 水平电机绝对运动过去。
- /// 返回该well的水平脉冲位置,失败 -1。
- /// </summary>
- public int RotateToWell(int wellNum)
- {
- int pos = ReadWellHorizontalPos(wellNum);
- if (pos < 0) { Log?.Invoke($"读well{wellNum}位置失败"); return -1; }
- bool ok = HorizontalMoveTo(pos);
- Log?.Invoke($"转到well{wellNum} 位置脉冲={pos} {(ok ? "OK" : "失败")}");
- return ok ? pos : -1;
- }
- /// <summary>读第 wellNum(1-16) 个well的Z对焦零点脉冲(EEPROM)。失败 -1。</summary>
- public int ReadWellFocusZero(int wellNum)
- {
- var r = _serial.Send(Protocol.ReadWellFocusZero(wellNum));
- return r == null ? -1 : Protocol.ParseEepromInt(r);
- }
- /// <summary>读垂直电机扫描间隔脉冲(每层Z步距,EEPROM)。失败 -1。</summary>
- public int ReadScanStep()
- {
- var r = _serial.Send(Protocol.ReadScanStep());
- return r == null ? -1 : Protocol.ParseEepromInt(r);
- }
- // ── 光源 ──
- public bool OpenLED() => _serial.Send(Protocol.OpenLED()) != null;
- public bool CloseLED() => _serial.Send(Protocol.CloseLED()) != null;
- // ── 垂直电机(Z=对焦轴)──
- /// <summary>Z 复位回零,等待 MotorDelayMs。</summary>
- public bool VerticalReset()
- => _serial.Send(Protocol.VerticalReset(), MotorDelayMs) != null;
- /// <summary>Z 绝对运动到指定脉冲,等待 MotorDelayMs 稳定。</summary>
- public bool VerticalMoveTo(int pulse)
- => _serial.Send(Protocol.VerticalAbsolute(pulse), MotorDelayMs) != null;
- /// <summary>Z 绝对运动,自定义稳定延时(ms)。扫描小步移动用短延时提速。</summary>
- public bool VerticalMoveTo(int pulse, int delayMs)
- => _serial.Send(Protocol.VerticalAbsolute(pulse), delayMs) != null;
- /// <summary>Z 相对正转 pulse 步。</summary>
- public bool VerticalForward(int pulse)
- => _serial.Send(Protocol.VerticalForward(pulse), MotorDelayMs) != null;
- /// <summary>Z 相对反转 pulse 步。</summary>
- public bool VerticalBackward(int pulse)
- => _serial.Send(Protocol.VerticalBackward(pulse), MotorDelayMs) != null;
- /// <summary>读 Z 当前位置脉冲。失败 -1。</summary>
- public int ReadVerticalPosition()
- {
- var r = _serial.Send(Protocol.ReadVerticalMotor());
- return r == null ? -1 : Protocol.ParseMotorPosition(r);
- }
- // ── 水平电机(皿孔定位)──
- public bool HorizontalReset()
- => _serial.Send(Protocol.HorizontalReset(), MotorDelayMs) != null;
- public bool HorizontalMoveTo(int pulse)
- => _serial.Send(Protocol.HorizontalAbsolute(pulse), MotorDelayMs) != null;
- /// <summary>水平绝对运动,自定义稳定延时(ms)。扫描小步移动用短延时提速。</summary>
- public bool HorizontalMoveTo(int pulse, int delayMs)
- => _serial.Send(Protocol.HorizontalAbsolute(pulse), delayMs) != null;
- public bool HorizontalForward(int pulse)
- => _serial.Send(Protocol.HorizontalForward(pulse), MotorDelayMs) != null;
- public bool HorizontalBackward(int pulse)
- => _serial.Send(Protocol.HorizontalBackward(pulse), MotorDelayMs) != null;
- public int ReadHorizontalPosition()
- {
- var r = _serial.Send(Protocol.ReadHorizontalMotor());
- return r == null ? -1 : Protocol.ParseMotorPosition(r);
- }
- public void Dispose() => _serial.Dispose();
- }
- }
|