using System; using System.IO.Ports; using System.Threading; namespace SA_LTT.Module { public abstract class ComPort { private object thisLock; private bool lockCheck; protected SerialPort serialPort; private string _terminator; private string _receivedData; private double _receiveWaitSeconds; public bool IsOpen { get { if (serialPort == null) return false; return serialPort.IsOpen; } } public string PortName { get { return serialPort.PortName; } } /// /// 종결자 설정. /// public string Terminator { get { return _terminator; } set { _terminator = value; } } public double ReceiveWaitSeconds { get { return _receiveWaitSeconds; } set { _receiveWaitSeconds = value; } } public ComPort(string portName = "COM1") { thisLock = new object(); serialPort = new SerialPort(); serialPort.PortName = portName; serialPort.BaudRate = 9600; serialPort.DataBits = 8; serialPort.Parity = Parity.None; serialPort.StopBits = StopBits.One; serialPort.Handshake = Handshake.None; serialPort.ReadTimeout = 500; serialPort.WriteTimeout = 500; Terminator = "\r\n"; } public static string[] GetExistPortNames() { return SerialPort.GetPortNames(); } public bool Open() { try { serialPort.Open(); return true; } catch (Exception e) { EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace); return false; } } public bool Close() { try { serialPort.Close(); return true; } catch (Exception e) { EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace); return false; } } protected string WriteRead(string command) { string receivedData = string.Empty; lock (thisLock) { while (lockCheck) Monitor.Wait(thisLock); try { lockCheck = true; _receivedData = string.Empty; if (serialPort.BytesToRead > 0) serialPort.ReadExisting(); serialPort.BaseStream.Flush(); serialPort.Write(command); DateTime check = DateTime.Now; while (true) { if ((DateTime.Now - check).TotalSeconds > ReceiveWaitSeconds) { check = DateTime.Now; break; } } while (true) { if (serialPort.BytesToRead > 0) { receivedData = serialPort.ReadExisting(); if(CheckTerminator(receivedData)) { if(Terminator == null) { if (serialPort.BytesToRead > 0) continue; } receivedData = _receivedData; break; } } if ((DateTime.Now - check).TotalMilliseconds > serialPort.ReadTimeout) { throw new TimeoutException($"receieve timeout"); } } return receivedData; } catch (Exception e) { EquipmentLogManager.Instance.WriteExceptionLog($"{e.StackTrace}\r\n{serialPort.PortName} port, command : {command}, received data : {receivedData}, {e.Message}" ); return receivedData; } finally { lockCheck = false; Monitor.Pulse(thisLock); } } } protected void Write(string command) { lock (thisLock) { while (lockCheck) Monitor.Wait(thisLock); try { lockCheck = true; serialPort.Write(command); } catch (Exception e) { EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace); } finally { lockCheck = false; Monitor.Pulse(thisLock); } } } protected string WriteRead(byte[] command) { string receivedData = string.Empty; lock (thisLock) { while (lockCheck) Monitor.Wait(thisLock); try { lockCheck = true; _receivedData = string.Empty; if (serialPort.BytesToRead > 0) serialPort.ReadExisting(); serialPort.BaseStream.Flush(); serialPort.Write(command, 0, command.Length); DateTime check = DateTime.Now; while(true) { if ((DateTime.Now - check).TotalSeconds > ReceiveWaitSeconds) { check = DateTime.Now; break; } } while (true) { if (serialPort.BytesToRead > 0) { receivedData = serialPort.ReadExisting(); if (CheckTerminator(receivedData)) { double aa = (DateTime.Now - check).TotalMilliseconds; receivedData = _receivedData; break; } } if ((DateTime.Now - check).TotalMilliseconds > serialPort.ReadTimeout) { throw new TimeoutException($"{serialPort.PortName} Port Receieve Timeout"); } } return receivedData; } catch (Exception e) { EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace); return receivedData; } finally { lockCheck = false; Monitor.Pulse(thisLock); } } } protected void Write(byte[] command) { lock (thisLock) { while (lockCheck) Monitor.Wait(thisLock); try { lockCheck = true; serialPort.Write(command, 0, command.Length); } catch (Exception e) { EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace); } finally { lockCheck = false; Monitor.Pulse(thisLock); } } } protected string Read(double timeOutSec) { string receivedData = string.Empty; DateTime check = DateTime.Now; lock (thisLock) { while (lockCheck) Monitor.Wait(thisLock); try { lockCheck = true; while (true) { if (serialPort.BytesToRead > 0) { receivedData = serialPort.ReadExisting(); if (CheckTerminator(receivedData)) { receivedData = _receivedData; break; } } if ((DateTime.Now - check).TotalSeconds > timeOutSec) { throw new TimeoutException($"{serialPort.PortName} Port Receieve Timeout"); } } } catch (Exception e) { EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace); return receivedData; } finally { lockCheck = false; Monitor.Pulse(thisLock); } } return receivedData; } private bool CheckTerminator(string receivedData) { if (Terminator == null) { _receivedData += receivedData; return true; } else { if (receivedData.Contains(Terminator) || _receivedData.Contains(Terminator)) { int terminatorLocation = receivedData.IndexOf(Terminator); if (receivedData.Length == terminatorLocation + Terminator.Length) { _receivedData += receivedData; } else { _receivedData += receivedData.Remove(terminatorLocation + Terminator.Length); } return true; } else { _receivedData += receivedData; return false; } } } } }