using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Threading;
namespace arDev
{
public class RS232 : IDisposable
{
protected Boolean _isinit = false;
#region "Event Args"
///
/// 데이터를 수신할떄 사용함(RAW 포함)
///
public class ReceiveDataEventArgs : EventArgs
{
private readonly byte[] _buffer = null;
///
/// 바이트배열의 버퍼값
///
public byte[] Value { get { return _buffer; } }
///
/// 버퍼(바이트배열)의 데이터를 문자로 반환합니다.
///
public string StrValue
{
get
{
//return string.Empty;
if (_buffer == null || _buffer.Length < 1) return string.Empty;
else return System.Text.Encoding.Default.GetString(_buffer);
}
}
public ReceiveDataEventArgs(byte[] buffer)
{
_buffer = buffer;
}
}
public class MessageEventArgs : EventArgs
{
private readonly Boolean _isError = false;
public Boolean IsError { get { return _isError; } }
private readonly string _message = string.Empty;
public string Message { get { return _message; } }
public MessageEventArgs(Boolean isError, string Message)
{
_isError = isError;
_message = Message;
}
}
#endregion
#region "Enum & Structure"
///
/// 데이터수신시 해당 데이터의 끝을 결정하는 방식을 설정합니다.
///
public enum eTerminal : byte
{
///
/// line feed
///
LF = 0,
///
/// carrige return
///
CR,
///
/// cr+lf
///
CRLF,
///
/// stx + ETx 구성된 프로토콜을 감지합니다. stx,etx는 임의 지정이 가능하며 기본값으로는 stx = 0x02, etx = 0x03 을 가지고 있습니다.
///
ETX,
///
/// 데이터의 길이를 가지고 판단합니다.
///
Length,
///
/// 설정없음 .. 일정시간동안 대기한 후 버퍼의 내용을 모두 데이터로 인정합니다.
///
None,
///
/// 내부 Receive 이벤트를 사용하지 않고 Raw 이벤트를 사용합니다.
/// 이 값을 설정할 경우 내부 Receivce 이벤트 내에서 메세지 수신 이벤트가 발생하지 않습니다.
/// DataParSER을 상속하여 해당 파서에서 데이터를 분리하세요. True 이면 분리성공, false 이면 완료될때까지 대기합니다.
///
CustomParser
}
#endregion
#region "Public variable"
///
/// WriteDataSync 명령 사용시 최대로 기다리는 시간
///
public int syncTimeout = 5000;
///
/// 오류가 발생했다면 이 변수에 그 내용이 기록됩니다.
///
public string errorMessage = string.Empty;
/////
///// WriteDataSync 명령 사용시 최대로 기다리는 시간
/////
//public int syncTimeout = 5000;
///
/// 이 값은 종단기호 형식이 Length 일때 사용됩니다. 버퍼의 갯수이 이 값과 일치하면 수신 이벤트를 발생합니다.
///
public int MaxDataLength = 0x0d;
///
/// 마지막으로 데이터는 전송한 시간
///
public DateTime lastSendTime;
///
/// 최종 전송 메세지
///
public byte[] lastSendBuffer;
///
/// 마지막으로 데이터를 받은 시간
///
public DateTime lastRecvTime = DateTime.Parse("1982-11-23");
///
/// 데이터 전송시 전송메세지를 발생할것인가? 171113
///
public Boolean EnableTxMessage { get; set; }
///
/// terminal 이 stx 일때에만 사용하며 기본값은 0x03
///
[Description("종단기호형식이 ETX일때 사용하는 데이터의 종료문자값입니다. 바이트값이므로 0~255 사이로 입력하세요.")]
[Category("설정"), DisplayName("Data End Byte")]
public byte ETX { get; set; }
#endregion
#region "Protect & private Variable"
protected Boolean CheckACK { get; set; }
protected Boolean CheckNAK { get; set; }
///
/// 메세지 수신시 사용하는 내부버퍼
///
protected List _buffer = new List();
///
/// 데이터의 끝을 분석하는 종단기호의 설정
///
private eTerminal _term = eTerminal.LF;
///
/// WriteDataSync 명령사용시 활성화됨
///
protected Boolean _isSync = false;
///
/// sync timeOUt체크시 사용합니다.
///
private System.Diagnostics.Stopwatch _wat = new System.Diagnostics.Stopwatch();
///
/// Serialport Device
///
protected System.IO.Ports.SerialPort _device;
///
/// for autoreset events
///
protected ManualResetEvent _mre;
protected Boolean isDisposed = false;
#endregion
#region "Internal Events"
void barcode_ErrorReceived(object sender, System.IO.Ports.SerialErrorReceivedEventArgs e)
{
if (Message != null) Message(this, new MessageEventArgs(true, e.ToString()));
}
void barcode_PinChanged(object sender, System.IO.Ports.SerialPinChangedEventArgs e)
{
if (serialPinchanged != null)
serialPinchanged(this, e);
//if (Message != null) Message(this, new MessageEventArgs(true, "PinChanged"));
}
void barcode_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
this.lastRecvTime = DateTime.Now;
if (_isSync) return; //싱크모드일경우에는 해당 루틴에서 직접 읽는다
_isSync = false;
//none일경우에는 100ms 정도 기다려준다.
if (_term == eTerminal.None)
{
//none 일경우에는 무조건 데이터로 취급한다.
System.Threading.Thread.Sleep(200);
_buffer.Clear();
}
try
{
int ReadCount = _device.BytesToRead;
byte[] buffer = new byte[ReadCount];
_device.Read(buffer, 0, buffer.Length);
if (ReceiveData_Raw != null) ReceiveData_Raw(this, new ReceiveDataEventArgs(buffer));
System.Text.StringBuilder LogMsg = new StringBuilder();
if (Terminal == eTerminal.CustomParser)
{
byte[] remainBuffer;
Repeat:
if (CustomParser(buffer, out remainBuffer))
{
//parser ok
RaiseRecvData(_buffer.ToArray());
_buffer.Clear();
if (remainBuffer != null && remainBuffer.Length > 0)
{
//버퍼를 변경해서 다시 전송을 해준다.
buffer = new byte[remainBuffer.Length];
Array.Copy(remainBuffer, buffer, buffer.Length);
goto Repeat; //남은 버퍼가 있다면 진행을 해준다.
}
}
}
else
{
foreach (byte bb in buffer)
{
switch (_term)
{
case eTerminal.CR:
if (bb == 0x0D)
{
RaiseRecvData(_buffer.ToArray()); ;
_buffer.Clear();
}
else _buffer.Add(bb);
break;
case eTerminal.LF:
if (bb == 0x0A)
{
RaiseRecvData(_buffer.ToArray()); ;
_buffer.Clear();
}
else _buffer.Add(bb);
break;
case eTerminal.CRLF:
if (bb == 0x0A)
{
RaiseRecvData(_buffer.ToArray()); ;
_buffer.Clear();
}
else if (bb == 0x0D)
{
//0d는 그냥 넘어간다.
}
else _buffer.Add(bb);
break;
case eTerminal.Length:
_buffer.Add(bb);
if (_buffer.Count == MaxDataLength)
{
RaiseRecvData(_buffer.ToArray()); ;
_buffer.Clear();
}
else if (_buffer.Count > MaxDataLength)
{
RaiseMessage("Buffer Length Error " + _buffer.Count.ToString() + "/" + MaxDataLength.ToString(), true);
_buffer.Clear();
}
break;
case eTerminal.ETX: //asc타입의 프로토콜에서는 STX,ETX가 고유값이다.
if (bb == STX)
{
_buffer.Clear();
}
else if (bb == ETX)
{
RaiseRecvData(_buffer.ToArray()); ;
_buffer.Clear();
}
else _buffer.Add(bb);
break;
case eTerminal.None:
_buffer.Add(bb);
break;
}
}
//170802
if (_term == eTerminal.None)
{
RaiseRecvData(_buffer.ToArray()); ;
_buffer.Clear();
}
}
}
catch (Exception ex)
{
if (IsOpen())
{
//_device.DiscardInBuffer();
//_device.DiscardOutBuffer();
}
errorMessage = ex.Message;
RaiseMessage(ex.Message, true);
}
}
#endregion
#region "External Events"
///
/// 바코드에서 들어오는 데이터의 원본 메세지
///
public event EventHandler ReceiveData_Raw;
///
/// 데이터가 들어올 경우 발생합니다 (종단기호=Termianl) 문자열이 발견된 후에 발생함
///
public event EventHandler ReceiveData;
///
/// 데이터를 전송할 때 해당 이벤트가 발생합니다.
///
public event EventHandler SendData;
///
/// 오류 및 기타 일반 메세지
///
public event EventHandler Message;
///
/// 시리얼포트의 핀 상태값이 변경될 때 발생합니다.
///
public event EventHandler serialPinchanged;
#endregion
#region "Properties"
///
/// 식별번호(임의지정가능) - 장치 생성시 입력
///
[Description("이 장치의 식별 ID(임의 지정가능)")]
[Category("설정"), DisplayName("Device No")]
public string Tag { get; set; }
///
/// terminal 이 etx 일때에만 사용하며 기본값은 0x02
///
[Description("종단기호형식이 ETX일때 사용하는 데이터의 시작문자값입니다. 바이트값이므로 0~255 사이로 입력하세요.")]
[Category("설정"), DisplayName("Data Start Byte")]
public byte STX { get; set; }
///
/// 내장 분석기(Parser)를 사용할 경우 최종 데이터에서 CR,LF를 제거할지 선택합니다.
///
[Description("내장분석기(Parser)를 사용할 경우 최종 데이터에서 CR.LF를 제거할지 선택합니다.")]
[Category("기타"), DisplayName("CRLF 제거")]
public Boolean RemoveCRLFNULL { get; set; }
///
/// 종단기호 형식
///
[Description("데이터의 종단기호를 설정합니다. 지정한 데이터가 올경우")]
[Category("설정"), DisplayName("종단기호")]
public eTerminal Terminal { get { return _term; } set { _term = value; } }
[Category("설정")]
public System.IO.Ports.Parity Parity
{
get
{
return _device.Parity;
}
set
{
_device.Parity = value;
}
}
[Category("설정")]
public int DataBits
{
get
{
return _device.DataBits;
}
set
{
_device.DataBits = value;
}
}
[Category("설정")]
public System.IO.Ports.StopBits StopBits
{
get
{
return _device.StopBits;
}
set
{
_device.StopBits = value;
}
}
[Category("설정")]
public System.IO.Ports.Handshake Handshake
{
get
{
return _device.Handshake;
}
set
{
_device.Handshake = value;
}
}
#region "pin state & pin setting"
///
/// Data Terminal Ready
///
[Description("Data Terminal Ready 신호의 사용여부")]
[Category("PIN")]
public Boolean DtrEnable
{
get
{
return _device.DtrEnable;
}
set
{
_device.DtrEnable = value;
}
}
///
/// Request To Send
///
[Description("Request to Send 신호의 사용여부")]
[Category("PIN")]
public Boolean RtsEnable
{
get
{
return _device.RtsEnable;
}
set
{
_device.RtsEnable = value;
}
}
///
/// Data set Ready 신호 상태
///
[Description("Data Set Ready 신호 상태")]
[Category("PIN")]
public Boolean PIN_DSR
{
get
{
if (!IsOpen()) return false;
return _device.DsrHolding;
}
}
///
/// Carrier Detect
///
[Description("Carrier Detect 신호 상태")]
[Category("PIN")]
public Boolean PIN_CD
{
get
{
if (!IsOpen()) return false;
return _device.CDHolding;
}
}
///
/// Clear to Send
///
[Description("Clear to Send 신호 상태")]
[Category("PIN")]
public Boolean PIN_CTS
{
get
{
if (!IsOpen()) return false;
return _device.CtsHolding;
}
}
///
/// Break State
///
[Description("중단신호 상태")]
[Category("PIN")]
public Boolean PIN_BreakState
{
get
{
if (!IsOpen()) return false;
return _device.BreakState;
}
}
#endregion
///
/// 포트가 열려있는지 확인
///
[Description("현재 시리얼포트가 열려있는지 확인합니다")]
[Category("정보"), DisplayName("Port Open")]
public virtual Boolean IsOpen()
{
if (_device == null) return false;
return _device.IsOpen;
}
///
/// 초기화등이 성공했는지 확인합니다.close 되었다면 실패입니다. isinit 변수값을 적절히 수정하시기 바랍니다.
///
[Description("초기화성공여부 별도의 초기화 코드가없다면 isOpen 과 동일합니다.")]
[Category("정보"), DisplayName("Init OK?")]
public virtual Boolean IsInit()
{
if (!IsOpen() || !_isinit) return false;
return true;
}
///
/// 쓰기타임아웃
///
[Description("쓰기명령어의 최대대기시간(단위:ms)\r\n지정 시간을 초과할 경우 오류가 발생합니다.")]
[Category("설정"), DisplayName("쓰기 제한시간")]
public int WriteTimeout
{
get { return _device.WriteTimeout; }
set { _device.WriteTimeout = value; }
}
///
/// 읽기타임아웃
///
[Description("읽기명령어의 최대대기시간(단위:ms)\r\n지정 시간을 초과할 경우 오류가 발생합니다.")]
[Category("설정"), DisplayName("읽기 제한시간")]
public int ReadTimeout
{
get { return _device.ReadTimeout; }
set { _device.ReadTimeout = value; }
}
///
/// 포트이름
///
[Description("시리얼 포트 이름")]
[Category("설정"), DisplayName("Port Name")]
public string PortName { get { return _device.PortName; } set { if (string.IsNullOrEmpty(value) == false) _device.PortName = value; } }
///
/// RS232 Baud Rate
///
[Description("시리얼 포트 전송 속도")]
[Category("설정"), DisplayName("Baud Rate")]
public int BaudRate { get { return _device.BaudRate; } set { _device.BaudRate = value; } }
#endregion
#region "Method"
///
/// 쓰기버퍼비우기
///
public void ClearWriteBuffer()
{
if (_device.IsOpen) _device.DiscardOutBuffer();
}
///
/// 읽기버퍼비우기
///
public void ClearReadBuffer()
{
if (_device.IsOpen) _device.DiscardInBuffer();
}
///
/// 장치의 초기화작업을 수행합니다.(이 값은 기본값으로 true가 무조건 설정됩니다) 오버라이드하여 각 상황에 맞게 처리하세요.
///
protected virtual void Init()
{
if (!IsOpen()) _isinit = false;
else _isinit = true;
}
protected virtual Boolean CustomParser(byte[] buf, out byte[] remainBuffer)
{
remainBuffer = new byte[] { };
return true;
}
#region "Raise Message Events (임의로 메세지를 발생시킵니다)"
///
/// 보낸메세지 이벤트를 발생
///
/// String Data
public void RaiseSendData(string data)
{
RaiseSendData(System.Text.Encoding.Default.GetBytes(data));
}
///
/// 보낸메세지 이벤트를 발생 합니다.
///
/// Byte Array
public void RaiseSendData(byte[] data)
{
try
{
if (SendData != null) SendData(this, new ReceiveDataEventArgs(data));
}
catch (Exception ex)
{
RaiseMessage("RaiseSendData:" + ex.Message, true);
}
}
///
/// 지정한 데이터로 바코드가 수신된것처럼 발생시킵니다.
///
///
public void RaiseRecvData(byte[] b)
{
byte[] Data;
if (RemoveCRLFNULL) //제거해야하는경우에만 처리 170822
Data = RemoveCRLF(b);
else
Data = b;
try
{
if (ReceiveData != null) ReceiveData(this, new ReceiveDataEventArgs(Data));
}
catch (Exception ex)
{
RaiseMessage("RaiseDataMessage:" + ex.Message, true);
}
}
///
/// 지정한 데이터로 바코드가 수신된것처럼 발생시킵니다.
///
///
public void RaiseRecvData(string data)
{
RaiseRecvData(System.Text.Encoding.Default.GetBytes(data));
}
///
/// 메세지이벤트를 발생합니다. 오류메세지일 경우 2번째 파라미터를 true 로 입력하세요.
///
/// 메세지
/// 오류라면 True로 설정하세요. 기본값=False
public void RaiseMessage(string message, Boolean isError = false)
{
if (isError) errorMessage = message; //170920
if (Message != null) Message(this, new MessageEventArgs(isError, message));
}
#endregion
///
/// 포트열기(실패시 False)를 반환
///
public virtual Boolean Open(Boolean runInit = true)
{
try
{
_device.Open();
if (_device.IsOpen)
{
Init();
}
else
{
_isinit = false;
}
return _isinit;
}
catch (Exception ex)
{
errorMessage = ex.Message;
RaiseMessage(ex.Message, true);
return false;
}
}
public virtual Boolean Open(string portname, int baud, Boolean runInit = true)
{
try
{
this.PortName = portname;
this.BaudRate = baud;
_device.Open();
if (_device.IsOpen)
{
Init();
}
else
{
_isinit = false;
}
return _isinit;
}
catch (Exception ex)
{
errorMessage = ex.Message;
RaiseMessage(ex.Message, true);
return false;
}
}
///
/// 포트닫기
///
public virtual void Close()
{
if (_device != null && _device.IsOpen)
{
_isinit = false;
_device.DiscardInBuffer();
_device.DiscardOutBuffer();
//외부에서 닫기를 하면 진행된다?
System.Threading.Tasks.Task.Run(new Action(() =>
{
_device.Close();
}));
}
}
///
/// 메세지내용중 Cr,LF 를 제거합니다.
///
protected byte[] RemoveCRLF(byte[] src)
{
List bcdbuf = new List();
foreach (byte by in src)
{
if (by == 0x00 || by == 0x0d || by == 0x0a || by == 0x02 || by == 0x03) continue;
bcdbuf.Add(by);
}
return bcdbuf.ToArray();
}
#endregion
#region "Method Write Data"
///
/// 포트에 쓰기(barcode_DataReceived 이벤트로 메세지수신)
///
public virtual Boolean WriteData(string data)
{
byte[] buf = System.Text.Encoding.Default.GetBytes(data);
return WriteData(buf);
}
public virtual Boolean Write(string data)
{
return WriteData(data);
}
public virtual Boolean Write(byte[] buf)
{
return WriteData(buf);
}
///
/// 포트에 쓰기 반환될 때까지 기다림(SyncTimeOut 값까지 기다림)
///
public virtual byte[] WriteDataSync(string data)
{
byte[] buf = System.Text.Encoding.Default.GetBytes(data);
return WriteDataSync(buf);
}
///
/// _buffer를 클리어하고 입력된 데이터를 버퍼에 추가합니다.
///
///
public void setRecvBuffer(byte[] buf)
{
this._buffer.Clear();
this._buffer.AddRange(buf);
}
public int WriteError = 0;
public string WriteErrorMessage = string.Empty;
///
/// 포트에 쓰기 반환될 때까지 기다림(SyncTimeOut 값까지 기다림)
///
public virtual byte[] WriteDataSync(byte[] data, Boolean useReset = true)
{
errorMessage = string.Empty;
_isSync = true;
byte[] recvbuf = null;
// Boolean bRet = false;
//171214
if (!IsOpen())
{
errorMessage = "Port Closed";
return null;
}
//171205 : 타임아웃시간추가
if (useReset)
{
if (!_mre.WaitOne(syncTimeout))
{
errorMessage = string.Format("WriteDataSync:MRE:WaitOne:TimeOut 3000ms");
RaiseMessage(errorMessage, true);
return null;
}
_mre.Reset();
}
//save last command
lastSendTime = DateTime.Now;
if (lastSendBuffer == null) lastSendBuffer = new byte[data.Length]; //171113
else Array.Resize(ref lastSendBuffer, data.Length);
Array.Copy(data, lastSendBuffer, data.Length);
Boolean sendOK = false;
try
{
_device.DiscardInBuffer();
_device.DiscardOutBuffer();
_buffer.Clear(); //171205
_device.Write(data, 0, data.Length);
WriteError = 0;
WriteErrorMessage = string.Empty;
sendOK = true;
}
catch (Exception ex)
{
WriteError += 1;
WriteErrorMessage = ex.Message;
}
if (sendOK)
{
try
{
//171113
if (EnableTxMessage && SendData != null) SendData(this, new ReceiveDataEventArgs(data));
_wat.Restart();
Boolean bTimeOut = false;
_buffer.Clear();
Boolean bDone = false;
while (!bDone)
{
if (_wat.ElapsedMilliseconds > WriteTimeout)
{
errorMessage = "(Sync)WriteTimeOut";
bTimeOut = true;
break;
}
else
{
int RecvCnt = _device.BytesToRead;
if (RecvCnt > 0)
{
byte[] rbuf = new byte[RecvCnt];
_device.Read(rbuf, 0, rbuf.Length);
if (_term == eTerminal.CustomParser)
{
byte[] remainBuffer;
Repeat:
if (CustomParser(rbuf, out remainBuffer))
{
var newMem = new byte[_buffer.Count];
_buffer.CopyTo(newMem);
RaiseRecvData(newMem);
bDone = true;
if (remainBuffer != null && remainBuffer.Length > 0)
{
rbuf = new byte[remainBuffer.Length];
Buffer.BlockCopy(remainBuffer, 0, rbuf, 0, rbuf.Length);
goto Repeat;
}
}
}
else
{
foreach (byte b in rbuf)
{
if (CheckACK && b == 0x06) //ack
{
_buffer.Add(b);
bDone = true;
break;
}
else if (CheckNAK && b == 0x15) //nak
{
_buffer.Add(b);
bDone = true;
break;
}
else
{
switch (_term)
{
case eTerminal.CR:
if (b == 0x0D)
{
bDone = true;
break;
}
else _buffer.Add(b);
break;
case eTerminal.LF:
if (b == 0x0A)
{
bDone = true;
break;
}
else _buffer.Add(b);
break;
case eTerminal.CRLF:
if (b == 0x0A)
{
bDone = true;
break;
}
else if (b == 0x0d)
{
//pass
}
else
{
_buffer.Add(b);
}
break;
case eTerminal.Length:
_buffer.Add(b);
if (_buffer.Count == MaxDataLength)
{
bDone = true;
break;
}
else if (_buffer.Count > MaxDataLength)
{
RaiseMessage("Buffer Length Error " + _buffer.Count.ToString() + "/" + MaxDataLength.ToString(), true);
_buffer.Clear();
}
break;
case eTerminal.ETX:
if (b == STX)
{
_buffer.Clear();
}
else if (b == ETX)
{
bDone = true;
break;
}
else _buffer.Add(b);
break;
}
}
}
}
}
}
}
_wat.Stop();
if (!bTimeOut)
{
recvbuf = new byte[_buffer.Count];
Buffer.BlockCopy(_buffer.ToArray(), 0, recvbuf, 0, recvbuf.Length);
//recvbuf = _buffer.ToArray();
// bRet = true;
}
}
catch (Exception ex)
{
errorMessage = ex.Message;
//bRet = false;
}
finally
{
if (useReset)
_mre.Set();//release
}
}
//syncmode off
_isSync = false;
return recvbuf;
}
///
/// 포트에 쓰기(barcode_DataReceived 이벤트로 메세지수신)
///
public virtual Boolean WriteData(byte[] data)
{
Boolean bRet = false;
//171205 : 타임아웃시간추가
if (!_mre.WaitOne(3000))
{
errorMessage = string.Format("WriteData:MRE:WaitOne:TimeOut 3000ms");
RaiseMessage(errorMessage, true);
return false;
}
_mre.Reset();
//Array.Resize(ref data, data.Length + 2);
try
{
lastSendTime = DateTime.Now;
if (lastSendBuffer == null) lastSendBuffer = new byte[data.Length]; //171113
else Array.Resize(ref lastSendBuffer, data.Length);
Array.Copy(data, lastSendBuffer, data.Length);
_device.Write(data, 0, data.Length);
//171113
if (EnableTxMessage && SendData != null) SendData(this, new ReceiveDataEventArgs(data));
bRet = true;
WriteError = 0;
WriteErrorMessage = string.Empty;
}
catch (Exception ex)
{
// this.isinit = false;
RaiseMessage(ex.Message, true);// if (ReceivceData != null) ReceivceData(this, true, ex.Message);
bRet = false;
WriteError += 1; //연속쓰기오류횟수
WriteErrorMessage = ex.Message;
}
finally
{
_mre.Set();
}
return bRet;
}
#endregion
///
/// 지정한ID를 가진 장치를 생성합니다.
///
///
public RS232(string tag_ = "")
{
_mre = new ManualResetEvent(true);
this.Tag = tag_;
this._device = new System.IO.Ports.SerialPort();
_device.DataReceived += barcode_DataReceived;
_device.ErrorReceived += barcode_ErrorReceived;
_device.PinChanged += barcode_PinChanged;
_device.ReadTimeout = 2000;
_device.WriteTimeout = 2000;
_device.BaudRate = 9600;
_term = eTerminal.CRLF;
STX = 0x02;
ETX = 0x03;
RemoveCRLFNULL = false;
EnableTxMessage = false;
}
~RS232()
{
Dispose();
}
///
/// close를 호출합니다.
///
public virtual void Dispose()
{
if (!isDisposed) //180219
{
isDisposed = true;
_isinit = false;
_device.DataReceived -= barcode_DataReceived;
_device.ErrorReceived -= barcode_ErrorReceived;
_device.PinChanged -= barcode_PinChanged;
Close();
}
}
}
}