using ivf_tl_Entity.GlobalEnums; using System.IO.Ports; namespace ivf_tl_Entity.ComEntitys { /// /// 串口发送接收助手 /// public class Channel { /// /// 异常日志 /// 异常、名称、参数 /// public event Action ExceptionLogEvent; /// /// 错误日志 /// public event Action ErrorLogEvent; /// /// 指令记录日志 /// public event Action CommandLogEvent; /// /// 接收指令 /// public event Action DataReceived; /// /// /// /// /// /// /// /// /// /// /// /// public Channel(int house, string comName, int bufferManagerSize, int BaudRate, int DataBits, StopBits stopBits, Parity parity, int ReadTimeout, int WriteTimeout) { _comName = comName; _house = house; _bufferManagerSize = bufferManagerSize; _baudRate = BaudRate; _dataBits = DataBits; _stopBits = stopBits; _parity = parity; _readTimeout = ReadTimeout; _writeTimeout = WriteTimeout; ringBufferManager = new RingBufferManager(_bufferManagerSize); GetSerialPortValue(_house, _comName, _baudRate, _dataBits, _stopBits, _parity, _readTimeout, _writeTimeout); } /// /// /// /// /// public Channel(int house, string comName) { _comName = comName; _house = house; ringBufferManager = new RingBufferManager(_bufferManagerSize); GetSerialPortValue(_house, _comName, _baudRate, _dataBits, _stopBits, _parity, _readTimeout, _writeTimeout); } public RingBufferManager ringBufferManager; public SerialPort serialPort; private CustomProtocol customProtocol; private int _house = 0; private string _comName; private int _bufferManagerSize = 1024; /// /// 波特率 /// private int _baudRate = 9600; /// /// 数据位 /// private int _dataBits = 8; /// /// 停止位 /// private StopBits _stopBits = StopBits.One; /// /// 奇偶校验位 /// private Parity _parity = Parity.None; /// /// 串口读取超时 /// private int _readTimeout = 3000; /// /// 串口写入超时 /// private int _writeTimeout = 3000; /// /// 获取实例 /// /// houseid /// 串口名称 /// 缓冲区大小 /// 波特率 /// 数据位 /// 停止位 /// 奇偶校验位 /// 串口读取超时 /// 串口写入超时 /// public bool GetSerialPortValue(int house, string comName, int BaudRate, int DataBits, StopBits stopBits, Parity parity, int ReadTimeout, int WriteTimeout) { try { serialPort = new SerialPort(); serialPort.PortName = comName; //波特率 serialPort.BaudRate = BaudRate; //数据位 serialPort.DataBits = DataBits; //两个停止位 serialPort.StopBits = stopBits; //无奇偶校验位 serialPort.Parity = parity; serialPort.ReadTimeout = ReadTimeout; serialPort.WriteTimeout = WriteTimeout; serialPort.DataReceived += SerialPort_DataReceived; return true; } catch (Exception ex) { ExceptionLogEvent?.Invoke(ex, $"[{_house}][{_comName}]创建SerialPort实例", $"[house:{house}][com:{comName}]", LogEnum.RunException); return false; } } /// /// 接收数据 /// /// /// /// private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { string loginfo = $"[{_house}][{customProtocol.comName}][{customProtocol.commandNumber}][{customProtocol.commandType}]"; try { DateTime dateTime = DateTime.Now; byte[] buffer = new byte[serialPort.BytesToRead]; serialPort.Read(buffer, 0, buffer.Length); CommandLogEvent?.Invoke(_house, DateTime.Now, $"{loginfo}[Rec:{StringHelper.ByteToHexStr(buffer)}]", LogEnum.PortComRecord); ringBufferManager.WriteBuffer(buffer, 0, buffer.Length); if (ringBufferManager.DataCount >= customProtocol.lenght) { if (ringBufferManager.DataCount > customProtocol.lenght) { ErrorLogEvent?.Invoke($"{loginfo}缓冲区字节数大于预期", LogEnum.RunError); } byte[] receivedBuffer = new byte[customProtocol.lenght]; ringBufferManager.ReadBuffer(receivedBuffer, 0, customProtocol.lenght); //ringBufferManager.Clear(customProtocol.lenght); ringBufferManager.Clear(); customProtocol.receivedBuffer = receivedBuffer; if (customProtocol.receivedBuffer[customProtocol.lenght - 2] != 0) { customProtocol.IsSuccess = false; ErrorLogEvent?.Invoke($"{loginfo}[Send:{StringHelper.ByteToHexStr(customProtocol.sendBuffer)}][Receive:{StringHelper.ByteToHexStr(customProtocol.receivedBuffer)}]下位机操作失败回复", LogEnum.RunError); } var check = Commander.CheckORC(customProtocol.receivedBuffer); CommandLogEvent?.Invoke(_house, DateTime.Now, $"{loginfo}[Send:{StringHelper.ByteToHexStr(customProtocol.sendBuffer)}][Receive:{StringHelper.ByteToHexStr(customProtocol.receivedBuffer)}][校验结果:{check}]", LogEnum.HouseComRecord); if (!check) { ErrorLogEvent?.Invoke($"{loginfo}[Send:{StringHelper.ByteToHexStr(customProtocol.sendBuffer)}][Receive:{StringHelper.ByteToHexStr(customProtocol.receivedBuffer)}]下位机回复校验失败", LogEnum.RunError); } CommandLogEvent?.Invoke(_house, DateTime.Now, $"{loginfo}[Send:{StringHelper.ByteToHexStr(customProtocol.sendBuffer)}][Receive:{StringHelper.ByteToHexStr(customProtocol.receivedBuffer)}]", LogEnum.PortComRecord); DataReceived?.Invoke(customProtocol); } } catch (Exception ex) { string canshu = $"{loginfo}[Send:{StringHelper.ByteToHexStr(customProtocol.sendBuffer)}]"; ExceptionLogEvent?.Invoke(ex, $"[{_house}][{customProtocol.comName}][{customProtocol.commandNumber}]串口接收数据", canshu, LogEnum.RunException); } } /// /// 发送数据 /// /// public bool Send(CustomProtocol protocol) { customProtocol = protocol; customProtocol.comName = _comName; string logInfo = $"[{_house}][{protocol.comName}][{protocol.commandNumber}][{protocol.commandType}][Send:{StringHelper.ByteToHexStr(protocol.sendBuffer)}]"; try { serialPort.Write(customProtocol.sendBuffer, 0, customProtocol.sendBuffer.Length); CommandLogEvent?.Invoke(_house, DateTime.Now, logInfo, LogEnum.PortComRecord); return true; } catch (Exception e1) { ExceptionLogEvent?.Invoke(e1, $"[{_house}][{_comName}]发送指令", logInfo, LogEnum.RunException); return false; } } /// /// 打开串口 /// public bool OpenPort() { try { serialPort.Open(); return true; } catch (Exception ex) { ExceptionLogEvent?.Invoke(ex, $"{_house}模块{serialPort.PortName}串口打开", null, LogEnum.RunException); return false; } } /// /// 关闭串口 /// public bool ClosePort() { try { serialPort.Close(); return true; } catch (Exception ex) { ExceptionLogEvent?.Invoke(ex, $"{_house}模块{serialPort.PortName}串口关闭", null, LogEnum.RunException); return false; } } /// /// 清理串口缓冲区 /// /// public bool DiscardPortBuffer() { try { serialPort.DiscardInBuffer(); serialPort.DiscardOutBuffer(); return true; } catch (Exception ex) { ExceptionLogEvent?.Invoke(ex, $"[{_house}][{_comName}]清理串口缓冲区", null, LogEnum.RunException); return false; } } /// /// 释放串口类 /// /// public bool PortDispose() { try { serialPort.Dispose(); return true; } catch (Exception ex) { ExceptionLogEvent?.Invoke(ex, $"[{_house}][{_comName}]释放串口类", null, LogEnum.RunException); return false; } } /// /// 重新打开串口 /// /// public bool ReopenPort() { ringBufferManager.Clear(); for (int i = 0; i < 3; i++) { try { bool DiscardBuffer = DiscardPortBuffer(); bool closePort = ClosePort(); bool portdispose = PortDispose(); var a = GetSerialPortValue(_house, _comName, _baudRate, _dataBits, _stopBits, _parity, _readTimeout, _writeTimeout); if (a) { var b = OpenPort(); if (b) { return true; } } } catch (Exception ex) { ExceptionLogEvent?.Invoke(ex, $"[{_house}][{_comName}]重新打开串口", null, LogEnum.RunException); } } return false; } } }