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;
|
}
|
}
|
|
/// <summary>
|
/// 종결자 설정.
|
/// </summary>
|
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;
|
}
|
}
|
}
|
}
|
}
|