using IvfTl.Control.Entity;
using IvfTl.Control.Entity.GlobalEnums;
using ivf_tl_UtilHelper;
using System.Diagnostics;
namespace ivf_tl_SerialHelper.Util
{
///
/// 封装指令发送以及解析线程
///
public class ComBin
{
///
/// 异常日志
/// 异常、名称、参数
///
public event Action ExceptionLogEvent;
///
/// 错误日志
///
public event Action ErrorLogEvent;
///
/// 指令记录日志
///
public event Action CommandLogEvent;
///
/// 串口状态
///
public event Action ComStateEvent;
public ComBin(int houseId, string portName)
{
this.houseId = houseId;
this.portName = portName;
_commandQueue = new Queue();
_channel = new Channel(houseId, portName);
_channel.DataReceived += _channel_DataReceived;
_channel.ExceptionLogEvent += _channel_ExceptionLogEvent;
_channel.ErrorLogEvent += _channel_ErrorLogEvent;
_channel.CommandLogEvent += _channel_CommandLogEvent; ;
StartSendCommandThread();
}
private void _channel_CommandLogEvent(int arg1, DateTime arg2, string arg3, LogEnum arg4)
{
CommandLogEvent?.Invoke(arg1, arg2, arg3, arg4);
}
private void _channel_ErrorLogEvent(string arg1, LogEnum arg2)
{
ErrorLogEvent?.Invoke(arg1, arg2);
}
private void _channel_ExceptionLogEvent(Exception arg1, string arg2, string arg3, LogEnum arg4)
{
ExceptionLogEvent?.Invoke(arg1, arg2, arg3, arg4);
}
public Channel _channel { get; set; } = null;
///
/// 是否停止发送指令线程循环
///
public bool IsStop = false;
///
/// 指令发送失败以后是否无限重发
///
public bool IsStopWhile = true;
private int houseId = 0;
private string portName = null;
///
/// 命令队列
///
private Queue _commandQueue;
///
/// 指令超时重发等待毫秒
///
private int milliseconds = 1000 * 30;
///
/// 发送指令的线程同步控制器
///
private AutoResetEvent sendAutoResetEvent = new AutoResetEvent(false);
///
/// 运行线程等待指令的同步控制器
///
private AutoResetEvent taskAutoResetEvent = new AutoResetEvent(false);
///
/// 指令发送锁
///
private object SendCommandLock = new object();
///
/// 指令计数
///
private double commandNumber = 1;
///
/// 串口状态 0正常 1异常
///
private int ComState = -1;
///
/// 开启发送指令线程
///
public void StartSendCommandThread()
{
Task.Factory.StartNew(() =>
{
Stopwatch SendStopWatch = new Stopwatch();
CustomProtocol customProtocol = null;
while (true)
{
try
{
if (IsStop)
{
return;
}
lock (_commandQueue)
{
if (_commandQueue.Any())
{
customProtocol = _commandQueue.Dequeue();
}
}
if (customProtocol != null)
{
SendStopWatch.Restart();
string Content = $"[{houseId}][{portName}][{customProtocol.commandNumber}][{customProtocol.commandType}][Send:{StringHelper.ByteToHexStr(customProtocol.sendBuffer)}]";
customProtocol.IsSuccess = SendCommand(customProtocol, Content);
string Content11 = $"{Content}[Rec:{StringHelper.ByteToHexStr(customProtocol.receivedBuffer)}]";
if (customProtocol.WaitTime != 0)
{
CommandLogEvent?.Invoke(houseId, DateTime.Now, $"{Content11}[等待{customProtocol.WaitTime}毫秒]", LogEnum.HouseComRecord);
Thread.Sleep(customProtocol.WaitTime);
}
CommandLogEvent?.Invoke(houseId, DateTime.Now, $"{Content11}[本轮指令总耗时:{StringHelper.TimeToString(SendStopWatch.Elapsed)}][End]", LogEnum.HouseComRecord);
SendStopWatch.Stop();
if (customProtocol.IsWaitOne)
{
taskAutoResetEvent.Set();
}
customProtocol = null;
}
else
{
//CommandLogEvent?.Invoke(houseId, DateTime.Now, $"空指令,等待50毫秒", LogEnum.HouseComRecord);
Thread.Sleep(50);
}
}
catch (Exception ex)
{
ExceptionLogEvent?.Invoke(ex, $"[{houseId}][{portName}]指令发送线程", null, LogEnum.RunException);
}
}
}, TaskCreationOptions.LongRunning);
}
///
/// 指令发送
///
///
///
private bool SendCommand(CustomProtocol customProtocol, string Content)
{
try
{
//超时重发3次后表示通讯中断
var result = false;
bool isopen = true;
bool sendRs = false;
do
{
for (int i = 0; i < 3; i++)
{
if (isopen)
{
sendRs = _channel.Send(customProtocol);
CommandLogEvent?.Invoke(houseId, DateTime.Now, $"{Content}[第{i + 1}次发送结果:{sendRs}]", LogEnum.HouseComRecord);
}
if (sendRs)
{
result = sendAutoResetEvent.WaitOne(milliseconds);//延时等待下位机回复
if (result)
{
break;
}
else
{
sendRs = false;
CommandLogEvent?.Invoke(houseId, DateTime.Now, $"{Content}第{i + 1}次等待超时", LogEnum.HouseComRecord);
ErrorLogEvent?.Invoke($"{Content}第{i + 1}次等待超时", LogEnum.RunError);
if (i != 2)
{
isopen = _channel.ReopenPort();
CommandLogEvent?.Invoke(houseId, DateTime.Now, $"{Content}[第{i + 1}次重新打开串口结果:{isopen}]", LogEnum.HouseComRecord);
if (!isopen)
{
ErrorLogEvent?.Invoke($"{Content}第{i + 1}次重新打开串口失败", LogEnum.RunError);
}
}
}
}
else
{
ErrorLogEvent?.Invoke($"{Content}第{i + 1}次发送失败", LogEnum.RunError);
if (i != 2)
{
Thread.Sleep(milliseconds);
isopen = _channel.ReopenPort();
CommandLogEvent?.Invoke(houseId, DateTime.Now, $"{Content}[第{i + 1}次重新打开串口结果:{isopen}]", LogEnum.HouseComRecord);
if (!isopen)
{
ErrorLogEvent?.Invoke($"{Content}第{i + 1}次重新打开串口失败", LogEnum.RunError);
}
}
}
}
//ErrorLogEvent?.Invoke($"{result}、{IsStopWhile}", LogEnum.RunError);
if (!result && !IsStopWhile)
{
return false;
}
ComlossAlarm(result);
} while (!result);
return true;
}
catch (Exception ex)
{
ExceptionLogEvent?.Invoke(ex, $"{Content}指令发送", null, LogEnum.RunException);
return false;
}
}
private void _channel_DataReceived(CustomProtocol obj)
{
sendAutoResetEvent.Set();
}
///
/// 发送封装
///
///
private void Enqueue(CustomProtocol custom)
{
lock (_commandQueue)
{
_commandQueue.Enqueue(custom);
}
}
public bool OpenPort()
{
bool ok = _channel.OpenPort();
// 借用复用死锁修复(D1-08):HAL.ScanDevices 扫描每口后经 SerialChannelImpl.Close() 置 IsStop=true,
// 令发送线程 while(IsStop)return 永久退出;采集端 serialBin.Start() 随后借用同一缓存 ComBin、
// 直接调本方法重开端口(返回 True)再 ShakeHandsWait 入队握手指令,但发送线程已死、无人出队处理,
// ShakeHandsWait 的 taskAutoResetEvent.WaitOne()(无超时)→ 永久死锁(旧合并 operate 僵尸即卡此)。
// 故:重开端口成功且发送线程处于停止态时,复位 IsStop 并重启发送线程(SendCommandLock 防并发双起)。
if (ok)
{
lock (SendCommandLock)
{
if (IsStop)
{
IsStop = false;
StartSendCommandThread();
}
}
}
return ok;
}
public bool ClosePort()
{
return _channel.ClosePort();
}
///
/// 通讯报警
///
///
public void ComlossAlarm(bool result)
{
if(!result)
{
if(ComState != 1)
{
ComState = 1;
ComStateEvent?.Invoke(1);
}
return;
}
if (ComState == 0) return;
ComState = 0;
ComStateEvent?.Invoke(0);
}
#region 仓室状态
///
/// 握手指令
///
public int ShakeHandsWait(CustomProtocol custom)
{
//握手
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.commandType = Enums.ShakeHands;
custom.CreateHandCommand();
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (!custom.IsSuccess) return -1;
return Analysiser.ParseShakeHandsCommand(custom.receivedBuffer);
}
///
/// 读仓门状态
///
///
///
public State DoorStatusWait(CustomProtocol custom)
{
custom.commandType = Enums.DoorStatus;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateReadDoorCommand();
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (!custom.IsSuccess) return State.未知;
return Analysiser.ParseDoorStatus(custom.receivedBuffer);
}
///
/// 仓室温度
///
///
///
public decimal TemperatureWait(CustomProtocol custom)
{
custom.commandType = Enums.Temperature;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateReadTemperatureCommand();
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (!custom.IsSuccess) return -1m;
return Analysiser.ParseTemperatureCommand(custom.receivedBuffer);
}
///
/// 上盖板温度
///
///
///
public decimal ShangTemperatureWait(CustomProtocol custom)
{
custom.commandType = Enums.Temperature;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateReadShangTemperatureCommand();
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (!custom.IsSuccess) return -1m;
return Analysiser.ParseTemperatureCommand(custom.receivedBuffer);
}
///
/// 玻璃片下方温度
///
///
///
public decimal BoLiTemperatureWait(CustomProtocol custom)
{
custom.commandType = Enums.BoLiTemperature;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateReadBoLiTemperatureCommand();
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (!custom.IsSuccess) return -1m;
return Analysiser.ParseTemperatureCommand(custom.receivedBuffer);
}
///
/// 仓室压力
///
///
///
public decimal PressureWait(CustomProtocol custom)
{
custom.commandType = Enums.Pressure;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateReadPressureCommand();
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (!custom.IsSuccess) return -1m;
return Analysiser.ParsePressureCommand(custom.receivedBuffer);
}
///
/// 获取缓冲瓶状态
///
///
public (decimal, decimal, decimal) BufferBottleState(CustomProtocol custom)
{
custom.commandType = Enums.BufferBottlePressure;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateBufferBottlePressureCommand();
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (!custom.IsSuccess) return (-1m,-1m,-1m);
return (Analysiser.ParsePressureCommand(custom.receivedBuffer), Analysiser.ParseTLTemperature1Command(custom.receivedBuffer), Analysiser.ParseTLTemperature2Command(custom.receivedBuffer));
}
#endregion
#region 电机
///
/// 水平电机复位
///
///
///
public bool HorizontalMotorResetWait(CustomProtocol custom, int waitTime)
{
custom.commandType = Enums.HorizontalMotorReset;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateHorizontalMotorResetCommand();
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (waitTime > 0)
{
Thread.Sleep(waitTime);
}
return custom.IsSuccess;
}
///
/// 水平电机绝对运动
///
///
///
///
///
public bool HorizontalMotorAbsoluteWait(CustomProtocol custom, int waitTime, int newValue)
{
custom.commandType = Enums.HorizontalMotorAbsolute;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.HorizontalMotorPulse = newValue;
custom.CreateHorizontalMotorMoveToCommand(newValue);
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (waitTime > 0)
{
Thread.Sleep(waitTime);
}
return custom.IsSuccess;
}
///
/// 水平电机正向运动(相对)
/// 忠实搬运 operate 侧 ComBin.HorizontalMotorForwardWait(命令构造器 control 侧已存在)。
///
public bool HorizontalMotorForwardWait(CustomProtocol custom, int waitTime, int newValue)
{
custom.commandType = Enums.HorizontalMotorForward;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.HorizontalMotorPulse = newValue;
custom.CreateHorizontalMotorForwardCommand(newValue);
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (waitTime > 0)
{
Thread.Sleep(waitTime);
}
return custom.IsSuccess;
}
///
/// 水平电机反向运动(相对)
/// 忠实搬运 operate 侧 ComBin.HorizontalMotorBackward(命令构造器 control 侧已存在)。
///
public bool HorizontalMotorBackwardWait(CustomProtocol custom, int waitTime, int newValue)
{
custom.commandType = Enums.HorizontalMotorBackward;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.HorizontalMotorPulse = newValue;
custom.CreateHorizontalMotorBackwardCommand(newValue);
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (waitTime > 0)
{
Thread.Sleep(waitTime);
}
return custom.IsSuccess;
}
///
/// 读水平电机位置
///
public int ReadHorizontalMotorWait(CustomProtocol custom)
{
custom.commandType = Enums.ReadHorizontalMotor;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateReadHorizontalMotorCommand();
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (!custom.IsSuccess) return -1;
return Analysiser.ParseCurrentMotor(custom.receivedBuffer);
}
///
/// 读垂直电机位置
///
public int ReadVerticalMotorWait(CustomProtocol custom)
{
custom.commandType = Enums.ReadVerticalMotor;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateReadVerticalMotorCommand();
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (!custom.IsSuccess) return -1;
return Analysiser.ParseCurrentMotor(custom.receivedBuffer);
}
///
/// 垂直电机复位
///
public bool VerticalMotorResetWait(CustomProtocol custom, int waitTime)
{
custom.commandType = Enums.VerticalMotorReset;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateVerticalMotorResetCommand();
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (waitTime > 0)
{
Thread.Sleep(waitTime);
}
return custom.IsSuccess;
}
///
/// 垂直电机绝对运动
///
/// 指令对象
/// 电机运动等待时间
/// 垂直电机目标位置
/// 当前水平电机位置
/// 图片编号
/// 当前well
/// 当前层数
public bool VerticalMotorAbsoluteWait(CustomProtocol custom, int waitTime, int currentVer, int currentHor, int pictureId, int well, int focal)
{
custom.commandType = Enums.VerticalMotorAbsolute;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.VerticalMotorPulse = currentVer;
custom.HorizontalMotorPulse = currentHor;
custom.pictureId = pictureId;
custom.well = well;
custom.focal = focal;
custom.CreateVerticalMotorAbsoluteMovementCommand(currentVer);
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (waitTime > 0)
{
Thread.Sleep(waitTime);
}
return custom.IsSuccess;
}
///
/// 垂直电机正向运动(相对)
/// 忠实搬运 operate 侧 ComBin.VerticalMotorForwardWait(命令构造器 control 侧已存在)。
///
public bool VerticalMotorForwardWait(CustomProtocol custom, int waitTime, int newValue)
{
custom.commandType = Enums.VerticalMotorForward;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateVerticalMotorForwardCommand(newValue);
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (waitTime > 0)
{
Thread.Sleep(waitTime);
}
return custom.IsSuccess;
}
///
/// 垂直电机反向运动(相对)
/// 忠实搬运 operate 侧 ComBin.VerticalMotorBackwardWait(命令构造器 control 侧已存在)。
///
public bool VerticalMotorBackwardWait(CustomProtocol custom, int waitTime, int newValue)
{
custom.commandType = Enums.VerticalMotorBackward;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateVerticalMotorBackwardCommand(newValue);
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (waitTime > 0)
{
Thread.Sleep(waitTime);
}
return custom.IsSuccess;
}
#endregion
#region 控制
///
/// 自动换气开关
/// 忠实搬运 operate 侧 ComBin.AutoWait(命令构造器/枚举 control 侧本任务已补)。
///
public bool AutoWait(CustomProtocol custom, bool auto)
{
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.commandType = Enums.AutoAirSwap;
custom.CreateAutoCommand(auto);
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (!custom.IsSuccess) return false;
return custom.receivedBuffer[custom.lenght - 2] == 0;
}
///
/// 仓室补气
///
///
public bool HouseAerationWait(CustomProtocol custom)
{
custom.commandType = Enums.HouseAeration;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateHouseAerationCommand();
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
return custom.IsSuccess;
}
///
/// 仓室排气
///
///
public bool HouseVentWait(CustomProtocol custom)
{
custom.commandType = Enums.HouseVent;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateHouseVentCommand();
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
return custom.IsSuccess;
}
///
/// 缓冲瓶补气
///
///
public bool BufferBottleAerationWait(CustomProtocol custom)
{
custom.commandType = Enums.BufferBottleAeration;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateBufferBottleAerationCommand();
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
return custom.IsSuccess;
}
///
/// 关闭仓室进气阀
///
///
///
public bool CloseIntakeValveWait(CustomProtocol custom, int waitTime)
{
custom.commandType = Enums.CloseIntakeValve;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateCloseIntakeValveCommand();
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (waitTime > 0)
{
Thread.Sleep(waitTime);
}
return custom.IsSuccess;
}
///
/// 打开仓室排气阀
///
///
public bool OpenExhaustValveWait(CustomProtocol custom, int waitTime)
{
custom.commandType = Enums.OpenExhaustValve;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateOpenExhaustValveCommand();
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (waitTime > 0)
{
Thread.Sleep(waitTime);
}
return custom.IsSuccess;
}
///
/// 打开舱室进气阀
///
///
///
///
public bool OpenIntakeValveWait(CustomProtocol custom, int waitTime)
{
custom.commandType = Enums.OpenIntakeValve;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateOpenIntakeValveCommand();
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (waitTime > 0)
{
Thread.Sleep(waitTime);
}
return custom.IsSuccess;
}
///
/// 关闭排气阀
///
///
///
public void CloseExhaustValveWait(CustomProtocol custom, int waitTime)
{
custom.commandType = Enums.CloseExhaustValve;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateCloseExhaustValveCommand();
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (waitTime > 0)
{
Thread.Sleep(waitTime);
}
}
///
/// 打开LEd灯
///
///
public void OpenLEDWait(CustomProtocol custom)
{
custom.commandType = Enums.OpenLED;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateOpenLEDCommand();
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
}
///
/// 关闭Led灯
///
///
public void CloseLEDWait(CustomProtocol custom)
{
custom.commandType = Enums.CloseLED;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateCloseLEDCommand();
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
}
#endregion
#region 参数
///
/// 读取TL仪器编号
///
public int ReadTLNumWait(CustomProtocol custom)
{
custom.commandType = Enums.ReadTLNum;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateReadTLNumCommand();
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (!custom.IsSuccess) return -1;
return Analysiser.ParseEEPROMPulse(custom.receivedBuffer);
}
///
/// 获取CCDSN
///
public int GetCCDSNWait(CustomProtocol custom)
{
custom.commandType = Enums.GetCCDSN;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateGetModuleCommand();
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (!custom.IsSuccess) return -1;
return Analysiser.ParseEEPROMPulse(custom.receivedBuffer);
}
///
/// 读E方-->水平电机位置
///
public int ReadEEPROMhoriMtWellHorHorWait(CustomProtocol custom,int horIndex)
{
custom.commandType = Enums.ReadEEPROMhoriMtWellHor;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateReadEEPROMhoriMtWellHoriPos(horIndex);
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (!custom.IsSuccess) return -1;
return Analysiser.ParseEEPROMPulse(custom.receivedBuffer);
}
///
/// 读E方-->垂直电机清晰位置
///
///
public int ReadEEPROMvertMtStartPulseWait(CustomProtocol custom)
{
custom.commandType = Enums.ReadEEPROMvertMtStartPulse;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateReadEEPROMvertMtStartPulse(1);
custom.IsWaitOne = true;
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (!custom.IsSuccess) return -1;
return Analysiser.ParseEEPROMPulse(custom.receivedBuffer);
}
///
/// 读E方-->垂直电机间隔脉冲
///
///
public int ReadEEPROMvertMtScanPluseWait(CustomProtocol custom)
{
custom.commandType = Enums.ReadEEPROMvertMtScanPluse;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.IsWaitOne = true;
custom.CreateReadEEPROMvertMtScanPluse();
Enqueue( custom);//断层扫描间隔数
taskAutoResetEvent.WaitOne();
if (!custom.IsSuccess) return -1;
return Analysiser.ParseEEPROMPulse(custom.receivedBuffer);
}
///
/// 读E方-->仓室进气阀打开时间
///
///
public int ReadEEPROOpenIntakeTimeWait(CustomProtocol custom)
{
custom.commandType = Enums.ReadEEPROOpenIntakeTime;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.IsWaitOne = true;
custom.CreateReadEEPROOpenIntakeTimeCommand();
Enqueue( custom);
taskAutoResetEvent.WaitOne();
if (!custom.IsSuccess) return -1;
return Analysiser.ParseEEPROMPulse(custom.receivedBuffer);
}
///
/// 读E方-->缓冲瓶进气阀打开时间
///
///
public int ReadEEPROOpenIntakeTimeBufferWait(CustomProtocol custom)
{
custom.commandType = Enums.ReadEEPROOpenIntakeTime;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.IsWaitOne = true;
custom.CreateReadEEPROOpenIntakeTimeBufferCommand();
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (!custom.IsSuccess) return -1;
return Analysiser.ParseEEPROMPulse(custom.receivedBuffer);
}
///
/// 读E方-->下加热板目标温度
///
///
public decimal ReadTargetTempWait(CustomProtocol custom)
{
custom.commandType = Enums.ReadTargetTemp;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.CreateReadTargetTemp();
custom.IsWaitOne = true;
Enqueue( custom);
taskAutoResetEvent.WaitOne();
if (!custom.IsSuccess) return -1m;
var num = Analysiser.ParseEEPROMPulse(custom.receivedBuffer);
return Math.Round(num / 100.00m, 2, MidpointRounding.AwayFromZero);
}
///
/// 读E方-->灯光亮度
///
///
public int ReadEEPROMLightNumWait(CustomProtocol custom)
{
custom.commandType = Enums.ReadLightNum;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.IsWaitOne = true;
custom.CreateReadEEPROMLightNum();
Enqueue(custom);
taskAutoResetEvent.WaitOne();
if (!custom.IsSuccess) return -1;
return Analysiser.ParseEEPROMPulse(custom.receivedBuffer);
}
// ── M1-B2 写E方调试动作包装(operate 调试页接入 lease.Serial 走本类,杜绝调试页 new ComBin/开第二个物理口)──
// 字节级一致性:T1.1 子代理已逐字节核实下列 4 个 Create* builder 与 operate 端完全相同
// (命令码 0x12 + 相同 well 地址表/固定地址 + 小端 pulse + 同 CreateORC 校验),故发送字节安全。
// ⚠ 待真机(V-010):写E方为破坏性操作;control 端 CustomProtocolLength 对 0x12 期望回包长度与 operate 不同,
// "写成功判定/回包等待"语义需真机核对(不影响发出的命令字节)。WriteEEPROOpenVentTime/WriteLightNum
// 因 control Commander 缺对应 builder,未在此补——调试页对应动作保留旧路径并标注待真机,不臆造字节。
/// 写E方→第 wellSn(1-16) 水平电机位置脉冲(命令 0x12,builder 与 operate 逐字节一致)。⚠ 待真机 V-010。
public void WriteEEPROMhoriMtWellHorHorWait(CustomProtocol custom, int wellSn, int newValue)
{
custom.commandType = Enums.WriteEEPROMhoriMtWell1HoriPos;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.IsWaitOne = true;
custom.CreateWriteEEPROMhoriMtWellHoriPos(wellSn, newValue);
Enqueue(custom);
taskAutoResetEvent.WaitOne();
return;
}
/// 写E方→垂直电机扫描间隔脉冲(builder 与 operate 逐字节一致)。⚠ 待真机 V-010。
public void WriteEEPROMvertMtScanPluseWait(CustomProtocol custom, int newValue)
{
custom.commandType = Enums.WriteEEPROMvertMtScanPluse;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.IsWaitOne = true;
custom.CreateWriteEEPROMvertMtScanPluse(newValue);
Enqueue(custom);
taskAutoResetEvent.WaitOne();
return;
}
/// 写E方→舱室进气阀打开时间(builder 与 operate 逐字节一致,地址 00 03 0c)。⚠ 待真机 V-010。
public void WriteEEPROOpenIntakeTimeWait(CustomProtocol custom, int newValue)
{
custom.commandType = Enums.WriteEEPROOpenIntakeTime;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.IsWaitOne = true;
custom.CreateWriteEEPROOpenIntakeTimeCommand(newValue);
Enqueue(custom);
taskAutoResetEvent.WaitOne();
return;
}
/// 写E方→缓冲瓶进气阀打开时间(builder 与 operate 逐字节一致,地址 00 05 0c)。⚠ 待真机 V-010。
public void WriteEEPROOpenIntakeTimeBufferWait(CustomProtocol custom, int newValue)
{
custom.commandType = Enums.WriteEEPROOpenIntakeTime;
custom.logDateTime = DateTime.Now;
custom.commandNumber = commandNumber++;
custom.IsWaitOne = true;
custom.CreateWriteEEPROOpenIntakeTimeBufferCommand(newValue);
Enqueue(custom);
taskAutoResetEvent.WaitOne();
return;
}
#endregion
#region 调试模式
#endregion
}
}