/// <summary> /// 入队一条指令 /// </summary> /// <param name="allowDiscard">是否允许丢弃该指令</param> /// <param name="cmdEventHandler">串口指令事件处理器</param> /// <param name="sendCMDTimeout">发送指令超时时长(毫秒)</param> /// <param name="reciveDataTimeout">接收数据超时时长(毫秒)</param> /// <param name="cmd">指令</param> public void EnqueueBytes(Boolean allowDiscard, SerialPortCMDEventHandler cmdEventHandler, int sendCMDTimeout, int reciveDataTimeout, byte[] cmd) { if (!useCMDQueue) { System.Console.WriteLine("不使用队列的串口设备不能调用此方法"); return; } CMDQueue.Enqueue(allowDiscard, cmdEventHandler, sendCMDTimeout, reciveDataTimeout, cmd); }
/// <summary> /// 关闭串口 /// </summary> internal void Close() { IsClosed = true; if (OpenStatusListenerTimer != null) { try { OpenStatusListenerTimer.Dispose(); } catch (Exception ex) { System.Console.Write(ex); OpenStatusListenerTimer = null; } } if (AfterOpenEventHandlerListenerTimer != null) { try { AfterOpenEventHandlerListenerTimer.Dispose(); } catch (Exception ex) { System.Console.Write(ex); AfterOpenEventHandlerListenerTimer = null; } } if (CMDQueue != null) { try { CMDQueue.Dispose(); } catch (Exception ex) { System.Console.Write(ex); CMDQueue = null; } } if (serialPort == null) { return; } try { serialPort.Close();// 尝试关闭 } catch (Exception ex) { System.Console.Write(ex); serialPort = null; } }
private int byteLength = 0; // 部分响应信息字节长度 /// <summary> /// 开始打开串口 /// </summary> /// <param name="SerialDataReceivedEventHandlerX">串口数据接收事件处理器扩展</param> /// <param name="BeforeOpen">尝试打开串口前操作</param> /// <param name="OpenSuccess">尝试打开串口成功操作</param> /// <param name="OpenError">尝试打开串口失败操作</param> /// <param name="StillOpen">仍处于打开状态操作</param> /// <param name="Disconnect">已经断开操作</param> /// <param name="BeforeReOpen">尝试重新打开串口前操作</param> /// <param name="ReOpenSuccess">尝试重新打开串口成功操作</param> /// <param name="ReOpenError">尝试重新打开串口失败操作</param> /// <param name="AfterOpen">串口打开后操作</param> internal void Start( SerialDataReceivedEventHandlerX SerialDataReceivedEventHandlerX, BeforeOpen BeforeOpen, OpenSuccess OpenSuccess, OpenError OpenError, StillOpen StillOpen, Disconnect Disconnect, BeforeReOpen BeforeReOpen, ReOpenSuccess ReOpenSuccess, ReOpenError ReOpenError, AfterOpen AfterOpen ) { // 设置串口数据接收事件处理器 serialPort.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler((sender, e) => { if (IsClosed) { return; } byte[] readedBytes = new byte[serialPort.BytesToRead]; int byteLength = readedBytes.Length; if (byteLength == 0) { CMDQueue.CancelCurrentCMD(); return; } serialPort.Read(readedBytes, 0, byteLength); String hexString = HexUtils.BytesToHexString(readedBytes, true).Trim(); if ("".Equals(hexString)) { CMDQueue.CancelCurrentCMD(); return; } if (ModbusUtils.IsFullCmd(hexString)) { if (useCMDQueue) { CMDQueue.FinishCurrentCMD(hexString); } SerialDataReceivedEventHandlerX?.Invoke(this.sid, this.portName, hexString); this.hexString = ""; this.byteLength = 0; } else { this.hexString += " " + hexString; this.hexString = this.hexString.Trim(); this.byteLength += byteLength; if (ModbusUtils.IsFullCmd(this.hexString)) { if (useCMDQueue) { CMDQueue.FinishCurrentCMD(hexString); } SerialDataReceivedEventHandlerX?.Invoke(this.sid, this.portName, this.hexString); this.hexString = ""; this.byteLength = 0; } } }); // 每100毫秒执行一次指令队列 if (useCMDQueue) { CMDQueue = new SerialPortCMDQueue(this.sid, this.portName, serialPort); CMDQueue.Start(); } BeforeOpen?.Invoke(this.sid, this.portName); // 尝试打开串口前操作 if (this.Open()) // 尝试打开串口 { OpenSuccess?.Invoke(this.sid, this.portName); // 尝试打开串口成功操作 OpenStatus = true; if (AfterOpen != null) { AfterOpenEventHandlerListenerTimer = new Timer((obj) => { AfterOpen(this.sid, this.portName);// 串口打开后操作 }, null, 0, this.afterOpenEventHandlerPeriod); } } else { OpenError?.Invoke(this.sid, this.portName);// 尝试打开串口失败操作 OpenStatus = null; if (AfterOpen != null) { AfterOpenEventHandlerListenerTimer = new Timer((obj) => { if (IsClosed) { return; } AfterOpen(this.sid, this.portName);// 串口打开后操作 }, null, Timeout.Infinite, Timeout.Infinite); } } // 无论打开成功与否,后续都需要监听该串口是否处于打开状态。 OpenStatusListenerTimer = new Timer((o) => { if (IsClosed) { return; } switch (OpenStatus) // 上一次的串口打开状态 { case null: // 首次打开串口失败 case false: // 后续打开串口失败 { BeforeReOpen?.Invoke(this.sid, this.portName); // 尝试重新打开串口前操作 if (this.Open()) // 尝试重新打开串口 { ReOpenSuccess?.Invoke(this.sid, this.portName); // 尝试重新打开串口成功操作 OpenStatus = true; if (AfterOpen != null) { AfterOpenEventHandlerListenerTimer.Change(0, this.afterOpenEventHandlerPeriod); // 重新开启计时器 } } else { ReOpenError?.Invoke(this.sid, this.portName); // 尝试重新打开串口失败 OpenStatus = false; } } break; case true: // 首次或后续打开串口成功 { if (serialPort.IsOpen) // 仍处于打开状态 { StillOpen?.Invoke(this.sid, this.portName); // 仍处于打开状态操作 OpenStatus = true; } else // 已经断开 { Disconnect?.Invoke(this.sid, this.portName); // 已经断开操作 OpenStatus = false; if (AfterOpen != null) { AfterOpenEventHandlerListenerTimer.Change(Timeout.Infinite, Timeout.Infinite); // 暂停计时器 } } } break; } }, null, this.checkOpenStatusPeriod, this.checkOpenStatusPeriod); }