687 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			687 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.Linq;
 | |
| using System.Text;
 | |
| using System.Threading;
 | |
| using System.ComponentModel;
 | |
| using System.Windows.Forms;
 | |
| using System.Drawing;
 | |
| using System.Drawing.Design;
 | |
| using System.Reflection;
 | |
| using System.Runtime;
 | |
| using System.Runtime.InteropServices;
 | |
| using System.Threading.Tasks;
 | |
| 
 | |
| namespace arDev
 | |
| {
 | |
|     public partial class MasterK : IDisposable
 | |
|     {
 | |
|         #region "Variable"
 | |
| 
 | |
|         public bool bRunMonitor;  //쓰레드작동시그널
 | |
|         public Boolean bAIMonitor=false; //배경쓰레드에서 아날로그값을 모니터링 합니다.\
 | |
|         public Boolean bDIOMonitor=true; //배경쓰레드에서 dIO를 모니터링 할것인가?
 | |
|         public string errorMessage = string.Empty;
 | |
| 
 | |
|         System.Diagnostics.Stopwatch aiMonWatch = new System.Diagnostics.Stopwatch();
 | |
|         public long LoopDelay;
 | |
| 
 | |
|         protected byte wSTX = 0x05;
 | |
|         protected byte wETX = 0x04;
 | |
|         protected byte rSTX = 0x06;
 | |
|         protected byte rETX = 0x03;
 | |
|         protected int interchar_delay;
 | |
|         protected Boolean bSyncRecvOK = false;// 메세지를 수신할 경우 설정됩니다.
 | |
|         protected Boolean _isInit = false;// 보드가 초기화가 되었는지 확인합니다.
 | |
|         public Boolean disposed = false;// Dipose 되었는가?
 | |
|         protected byte _CommandCode = 0x00;// recv command code
 | |
|         
 | |
|         protected Boolean _bDlc = false;
 | |
|         protected int _dlc = 0;
 | |
|         protected Boolean _bStx = false;    //stx를 찾앗는지?
 | |
|         protected Boolean _bEtx = false;    //etx를 찾앗는지?
 | |
|        
 | |
|         protected Boolean[] _valueI; //입력접점
 | |
|         protected Boolean[] _valueO; //출력접점
 | |
|         protected Boolean[] OldvalueI;
 | |
|         protected Boolean[] OldvalueO;
 | |
|        
 | |
|         protected Thread thMonitor;  //배경쓰레드(상태체크 및 이벤트 발생)
 | |
|         protected ManualResetEvent _mre;
 | |
|         protected string _mreowner = string.Empty;
 | |
|         protected System.Diagnostics.Stopwatch wat = new System.Diagnostics.Stopwatch();
 | |
|         protected System.IO.Ports.SerialPort _device;
 | |
|       
 | |
|         public int DOCount { get; protected set; }
 | |
|         public int DICount { get; protected set; }
 | |
|         public double ThreadSpeed = 0;
 | |
|        
 | |
|         public sRecvMessage LastRecvMessage;
 | |
|         public sSendMessage lastSendMessage;
 | |
|         public DateTime lastSendTime;
 | |
|         public byte[] lastSendBuffer;
 | |
| 
 | |
|         /// <summary>
 | |
|         /// device index
 | |
|         /// </summary>
 | |
|         public byte IDX = 0;
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         public MasterK()
 | |
|         {
 | |
|             //serial port
 | |
|             _device = new System.IO.Ports.SerialPort();
 | |
|             _device.BaudRate = 9600;
 | |
|             _device.DtrEnable = false;
 | |
|             _device.WriteTimeout = 2000;
 | |
|             _device.ReadTimeout = 2000;
 | |
|             _device.DiscardNull = true;
 | |
| 
 | |
|             //autoreset events
 | |
|             _mre = new System.Threading.ManualResetEvent(true);
 | |
|             bRunMonitor = false;
 | |
|             
 | |
|             LoopDelay = 150;
 | |
| 
 | |
|             //모든ls산전은 논리적으로 64개가 지정되어있다.
 | |
|             this.DICount = 64;
 | |
|             this.DOCount = 64;
 | |
| 
 | |
|             //변수초기화
 | |
|             this._valueI = new bool[DICount];
 | |
|             this._valueO = new bool[DOCount];
 | |
|             this.OldvalueI = new bool[_valueI.Length];
 | |
|             this.OldvalueO = new bool[_valueO.Length];
 | |
| 
 | |
|             //초기값설정(인풋)
 | |
|             for (int i = 0; i < _valueI.Length; i++)
 | |
|             {
 | |
|                 this._valueI[i] = false;
 | |
|                 this.OldvalueI[i] = false;
 | |
|             }
 | |
| 
 | |
|             //초기값설정(아웃풋)
 | |
|             for (int i = 0; i < _valueO.Length; i++)
 | |
|             {
 | |
|                 this._valueO[i] = false;
 | |
|                 this.OldvalueO[i] = false;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         ~MasterK()
 | |
|         {
 | |
|             Dispose(false);
 | |
|         }
 | |
| 
 | |
|         public void Close()
 | |
|         {
 | |
|             if (_device.IsOpen)
 | |
|             {
 | |
|                 if (_mre.WaitOne(3000))
 | |
|                 {
 | |
|                     _mre.Reset();
 | |
|                     _mreowner = "Close";
 | |
|                     _device.Close();
 | |
|                     _mre.Set();
 | |
|                 }   
 | |
|                 else
 | |
|                 {
 | |
|                     RaiseMessage(true, "close error timeout");
 | |
|                 }   
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 개체를 해제합니다.
 | |
|         /// </summary>
 | |
|         [Description("")]
 | |
|         public virtual void Dispose()
 | |
|         {
 | |
|             Dispose(true);
 | |
|             GC.SuppressFinalize(this);
 | |
|         }
 | |
| 
 | |
|         // Protected implementation of Dispose pattern.
 | |
|         protected virtual void Dispose(bool disposing)
 | |
|         {
 | |
|             if (disposed)
 | |
|                 return;
 | |
| 
 | |
|             if (disposing)
 | |
|             {
 | |
|                 // Dispose managed resources.
 | |
|             }
 | |
| 
 | |
|             StopMonitor();
 | |
| 
 | |
|             // Call the appropriate methods to clean up
 | |
|             // unmanaged resources here.
 | |
|             // If disposing is false,
 | |
|             // only the following code is executed.
 | |
| 
 | |
|             // Note disposing has been done.
 | |
|             disposed = true;
 | |
| 
 | |
|         }
 | |
| 
 | |
| 
 | |
|         public string PortName
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return _device.PortName;
 | |
|             }
 | |
|             set
 | |
|             {
 | |
|                 _device.PortName = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public Boolean Init(string port,int baud = 19200)
 | |
|         {
 | |
|             Close();
 | |
| 
 | |
|             errorMessage = string.Empty;
 | |
| 
 | |
|             _device.PortName = port;
 | |
|             _device.BaudRate = baud;
 | |
|            
 | |
|             try
 | |
|             {
 | |
|                 _device.Open();
 | |
|                 _device.DiscardInBuffer();
 | |
|                 _device.DiscardOutBuffer();
 | |
| 
 | |
|                 _isInit = true;
 | |
|                 sw_ch = new System.Diagnostics.Stopwatch();
 | |
|                interchar_delay  = GetIntercharDelay();
 | |
|                interframe_delay = GetInterframeDelay();
 | |
| 
 | |
|             }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 _isInit = false;
 | |
|                 errorMessage = ex.Message;
 | |
|                 RaiseMessage(true, ex.Message);
 | |
|             }
 | |
|             return _isInit;
 | |
|         }
 | |
| 
 | |
|       
 | |
| 
 | |
| 
 | |
|         #region "Properties"
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 입력핀 상태값을 확인합니다.
 | |
|         /// </summary>
 | |
|         /// <param name="arridx">0부터 시작하는 인덱스값</param>
 | |
|         /// <returns></returns>
 | |
|         [Description("")]
 | |
|         public Boolean INPUT(int arridx)
 | |
|         {
 | |
|             if (arridx < 0 || arridx > DICount - 1)
 | |
|             {
 | |
|                 if (IOErrorMessage != null)
 | |
|                     IOErrorMessage(this, new MessageEventArgs(true, "INPUT Command : ArrayIndex Error Value=" + arridx.ToString()));
 | |
|                 return false;
 | |
|             }
 | |
|             return this._valueI[arridx];
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 입력핀 상태를 모두 반환합니다.
 | |
|         /// </summary>
 | |
|         [Description("")]
 | |
|         public Boolean[] getInputArray
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return (Boolean[])this._valueI.Clone();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public byte getInputValueToByte(int startindex)
 | |
|         {
 | |
|             System.Collections.BitArray ba = new System.Collections.BitArray(this._valueI);
 | |
|             byte[] value = new byte[8];
 | |
|             ba.CopyTo(value, startindex);
 | |
|             return value[0];
 | |
|         }
 | |
|         public Int64 getInputValue
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 System.Collections.BitArray ba = new System.Collections.BitArray(this._valueI);
 | |
|                 byte[] value = new byte[8];
 | |
|                 ba.CopyTo(value, 0);
 | |
|                 return BitConverter.ToInt64(value, 0);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 출력핀 상태를 모두 반환합니다. 
 | |
|         /// </summary>
 | |
|         [Description("")]
 | |
|         public Boolean[] getOutputArray
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return (Boolean[])this._valueO.Clone();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 출력핀 상태 값을 확인합니다.
 | |
|         /// </summary>
 | |
|         /// <param name="arridx">0부터 시작하는 인덱스값</param>
 | |
|         /// <returns></returns>
 | |
|         [Description("")]
 | |
|         public Boolean OUTPUT(int arridx)
 | |
|         {
 | |
|             // get { return (Boolean[])this._valueO.Clone(); }
 | |
|             if (arridx < 0 || arridx > DOCount - 1)
 | |
|             {
 | |
|                 if (IOErrorMessage != null)
 | |
|                     IOErrorMessage(this, new MessageEventArgs(true, "OUTPUT Command : ArrayIndex Error Value=" + arridx.ToString()));
 | |
|                 return false;
 | |
|             }
 | |
|             return this._valueO[arridx];
 | |
|         }
 | |
| 
 | |
|         
 | |
|         /// <summary>
 | |
|         /// read digital input port state
 | |
|         /// </summary>
 | |
|         /// <returns></returns>
 | |
|         [Description("")]        
 | |
|         public string GetInputState()
 | |
|         {
 | |
|             System.Text.StringBuilder sb = new StringBuilder();
 | |
|             for (int i = 0; i < OldvalueI.Length; i++)
 | |
|                 sb.Append(OldvalueI[i] ? "1" : "0");
 | |
|             return sb.ToString();
 | |
|         }
 | |
|         /// <summary>
 | |
|         /// read digital output port state
 | |
|         /// </summary>
 | |
|         /// <returns></returns>
 | |
|         [Description("")]
 | |
|         public string GetOutputState()
 | |
|         {
 | |
|             System.Text.StringBuilder sb = new StringBuilder();
 | |
|             for (int i = 0; i < OldvalueO.Length; i++)
 | |
|                 sb.Append(OldvalueO[i] ? "1" : "0");
 | |
|             return sb.ToString();
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region "Method"
 | |
| 
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 오류메세지 반환
 | |
|         /// </summary>
 | |
|         /// <returns></returns>
 | |
|         [Description("")]
 | |
|         public string GetErrorMessage()
 | |
|         {
 | |
|             return this.errorMessage;
 | |
|         }
 | |
| 
 | |
|         
 | |
|         #region "raise Message"
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 일반메세지륿 라생시킵니다.
 | |
|         /// </summary>
 | |
|         /// <param name="isError"></param>
 | |
|         /// <param name="message"></param>
 | |
|         [Description("")]
 | |
|         public void RaiseMessage(Boolean isError, string message)
 | |
|         {
 | |
|             if (isError) errorMessage = message; //170920
 | |
|             if (Message != null) Message(this, new MessageEventArgs(isError, message));
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 지정한 데이터로 바코드가 수신된것처럼 발생시킵니다.(Parser를 사용함)
 | |
|         /// </summary>
 | |
|         /// <param name="b"></param>
 | |
|         [Description("")]
 | |
|         public void RaiseDataMessage(eMsgType dir, byte[] Data)
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 if (dir == eMsgType.Rx) Parse_RecvBuffer(Data);
 | |
|                 if (DataMessage != null) DataMessage(this, new DataEventArgs(dir,Data));
 | |
|             }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 errorMessage = ex.Message;
 | |
|                 RaiseMessage(true, "RaiseDataMessage:" + ex.Message);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
|         
 | |
|         /// <summary>
 | |
|         /// Input / Output 핀 상태를 지속적으로 읽는 쓰레드작업을 시작합니다.
 | |
|         /// </summary>
 | |
|         [Description("")]
 | |
|         public void RunMonitor(int loopDelay_ = 150)
 | |
|         {
 | |
|             this.LoopDelay = loopDelay_;
 | |
|             if(!this.bRunMonitor)
 | |
|             {
 | |
|                 this.bRunMonitor = true;
 | |
|                 this.thMonitor = new Thread(new ThreadStart(this.bwMonitor));
 | |
|                 this.thMonitor.IsBackground = true;
 | |
|                 this.thMonitor.Start();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// INPUT/OUPUT 핀 상태를 모니터링하는 쓰레드를 종료시킵니다.
 | |
|         /// </summary>
 | |
|         /// <returns></returns>
 | |
|         [Description("")]
 | |
|         public bool StopMonitor()
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 this.bRunMonitor = false;
 | |
|                 RaiseMessage(false, "Stop Monitor");
 | |
|                 return true;
 | |
|             }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 RaiseMessage(true, ex.Message);
 | |
|                 return false;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 지정한 출력포트의 값을 반전 시킵니다.
 | |
|         /// </summary>
 | |
|         /// <param name="arrIndex"></param>
 | |
|         /// <returns></returns>
 | |
|         [Description("")]
 | |
|         public Boolean SetToggle(int arrIndex)
 | |
|         {
 | |
|             if (!IsInit) return false;
 | |
|             if (arrIndex < 0 || (arrIndex + 1) >  DOCount)
 | |
|                 throw new Exception(string.Format("IDX Range Errror({0}~{1})", 0,  DOCount-1));
 | |
| 
 | |
|             Boolean currentValue = OUTPUT(arrIndex);
 | |
|             return SetOutput(arrIndex, !currentValue);
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 출력을 설정합니다.
 | |
|         /// </summary>
 | |
|         /// <param name="arrIndex"></param>
 | |
|         /// <param name="Value"></param>
 | |
|         /// <param name="Duration"></param>
 | |
|         /// <returns></returns>
 | |
|         [Description("")]
 | |
|         public Boolean SetOutput(int arrIndex, Boolean Value, int Duration = 0)
 | |
|         {
 | |
|             errorMessage = string.Empty;
 | |
|             if (!IsInit)
 | |
|             {
 | |
|                 //RaiseMessage(true, "SetOutput:No Init");
 | |
|                 return false;
 | |
|             }
 | |
| 
 | |
|             //RaiseMessage(false, "Set Output Index=" + arrIndex.ToString() + ",Value=" + Value.ToString());
 | |
| 
 | |
|             if (arrIndex < 0 || (arrIndex + 1)  > DOCount)
 | |
|             {
 | |
|                 RaiseMessage(true, "SetOutput:ArrIndex Error = " + arrIndex.ToString());
 | |
|                 return false;
 | |
|             }
 | |
| 
 | |
|             if (!_mre.WaitOne(1000))
 | |
|             {
 | |
|                 RaiseMessage(true, "SetOutput Wait on timeout");
 | |
|                 return false;
 | |
|             }
 | |
|             _mre.Reset();
 | |
| 
 | |
|             if (Duration < 0) Duration = 0;
 | |
|             int Port = 0x40 + arrIndex; //출력포트는 64번부터 시작한다.
 | |
|             string cmd = "00WSS0107%PX00" + Port.ToString("X2") + (Value ? "01":"00");
 | |
|             
 | |
|             //해당라인에 그값을 쓴다.
 | |
|             Boolean bRet = true;
 | |
| 
 | |
|             try
 | |
|             {
 | |
|                 var buffer = WriteSync(cmd);
 | |
|                 string strBuffer = System.Text.Encoding.Default.GetString(buffer);
 | |
|                 if (buffer == null)
 | |
|                 {
 | |
|                     RaiseMessage(true, "SetOutput:No Response");
 | |
|                     bRet= false;
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     if(buffer[0] == 0x06)
 | |
|                     {
 | |
|                         if (Duration != 0)
 | |
|                         {
 | |
|                             var task = new Task(() =>
 | |
|                             {
 | |
|                                 Thread.Sleep(Duration);
 | |
| 
 | |
|                                 string cmd2 = "00WSS0107%PX00" + Port.ToString("X2") + (Value ? "00" : "01");
 | |
|                                 var buffer2 = WriteSync(cmd2);
 | |
|                                 if (buffer2 == null)
 | |
|                                 {
 | |
|                                     RaiseMessage(true, "SetOutput:Duration toggle Error:No Reponse");
 | |
|                                 }
 | |
|                             });
 | |
|                             task.Start(); //비동기로 실행한다.
 | |
|                         }
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         RaiseMessage(true, "SetOutput:Nak response");
 | |
|                         bRet = false;
 | |
|                     }
 | |
|                     
 | |
|                 }
 | |
|             }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 RaiseMessage(true, "SetOutput:"+ex.Message);
 | |
|                 bRet = false;
 | |
|             }
 | |
|             _mre.Set();
 | |
|             return bRet;
 | |
|         }
 | |
|        
 | |
|       
 | |
|         /// <summary>
 | |
|         /// 이벤트를 강제 생성합니다.
 | |
|         /// </summary>
 | |
|         /// <param name="Direction"></param>
 | |
|         /// <param name="ArrIDX"></param>
 | |
|         /// <param name="newvalue"></param>
 | |
|         [Description("")]
 | |
|         public void RaiseEvent(eIOPINDIR Direction, int ArrIDX, Boolean newvalue)
 | |
|         {
 | |
|             if (IOValueChanged != null)
 | |
|             {
 | |
|                 //mre.WaitOne();
 | |
|                 //mre.Reset();
 | |
| 
 | |
|                 //171226
 | |
|                 if (Direction == eIOPINDIR.INPUT)
 | |
|                 {
 | |
|                     _valueI[ArrIDX] = newvalue;
 | |
|                     OldvalueI[ArrIDX] = newvalue;
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     _valueO[ArrIDX] = newvalue;
 | |
|                     OldvalueO[ArrIDX] = newvalue;
 | |
|                 }
 | |
| 
 | |
|                 try
 | |
|                 {
 | |
|                     if (IOValueChanged != null)
 | |
|                         IOValueChanged(this, new IOValueEventArgs(Direction, ArrIDX, !newvalue, newvalue));
 | |
| 
 | |
|                 }
 | |
|                 catch (Exception ex)
 | |
|                 {
 | |
|                     if (IOErrorMessage != null)
 | |
|                         this.IOErrorMessage(this, new MessageEventArgs(true , string.Format( "{0},{1}:{2}:{3}",ex.Message,Direction,ArrIDX,newvalue)));
 | |
|                 }
 | |
|                 //mre.Set();
 | |
|             }
 | |
| 
 | |
|         }
 | |
| 
 | |
| 
 | |
|         public virtual void UserMonitorCode() { }
 | |
|         
 | |
|         private byte loopIndex = 0;
 | |
|         /// <summary>
 | |
|         /// I/O상태를 모니터링 하여 내부 변수에 값을 저장합니다.
 | |
|         /// </summary>
 | |
|         [Description("")]
 | |
|         protected void bwMonitor()
 | |
|         {
 | |
|             DateTime lastaitime = DateTime.Now;
 | |
|             DateTime lastmottime = DateTime.Now;
 | |
|             System.Diagnostics.Stopwatch wat = new System.Diagnostics.Stopwatch();
 | |
|             while (this.bRunMonitor)
 | |
|             {
 | |
|                 wat.Restart();
 | |
|                 //170905
 | |
|                 if (!IsInit)
 | |
|                 {
 | |
|                     aiMonWatch.Stop();
 | |
|                     System.Threading.Thread.Sleep(1000);
 | |
|                     continue;
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     if (!aiMonWatch.IsRunning) aiMonWatch.Reset();
 | |
|                 }
 | |
| 
 | |
|                 //read dio status
 | |
|                 if (loopIndex == 0)
 | |
|                 {
 | |
|                     //RaiseMessage(false,"Run IOMonitor");
 | |
|                     if (bDIOMonitor)
 | |
|                         Read_RelayPort();
 | |
|                     loopIndex += 1;
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     //RaiseMessage(false, "Run AIMonitor");
 | |
|                     UserMonitorCode();
 | |
|                     loopIndex = 0;
 | |
|                 }
 | |
|                 
 | |
|                 wat.Stop();
 | |
|                 ThreadSpeed = wat.ElapsedMilliseconds;
 | |
|                 if(wat.ElapsedMilliseconds < LoopDelay)
 | |
|                 {
 | |
|                     Thread.Sleep((int)(LoopDelay- wat.ElapsedMilliseconds));
 | |
|                 }
 | |
|             }
 | |
|             wat.Stop();            
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region "Send Method"
 | |
| 
 | |
|         //public Boolean Read_AIPort()
 | |
|         //{
 | |
|         //    if (!_mre.WaitOne(1000))
 | |
|         //    {
 | |
|         //        RaiseMessage(true, "Read_AIPort Wait on timeout");
 | |
|         //        return false;
 | |
|         //    }
 | |
|         //    //RaiseMessage(false, "Read_AIPort");
 | |
|         //    _mre.Reset();
 | |
|         //    System.Threading.Thread.Sleep(25);
 | |
|         //    _mre.Set();
 | |
|         //    return true;
 | |
|         //}
 | |
| 
 | |
|         public Boolean isValid
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 var ts = DateTime.Now - lastrecvTime;
 | |
|                 if (ts.TotalSeconds > 5) return false;
 | |
|                 else return true;
 | |
|             }
 | |
|         }
 | |
|         private DateTime lastrecvTime = DateTime.Now;
 | |
| 
 | |
|         public Boolean Read_RelayPort()
 | |
|         {
 | |
|             if(!_mre.WaitOne(1000))
 | |
|             {
 | |
|                 RaiseMessage(true, "Read_RelayPort Wait on timeout");
 | |
|                 return false;
 | |
|             }
 | |
| 
 | |
|            // RaiseMessage(false, "Read_RelayPort");
 | |
| 
 | |
|             _mre.Reset();
 | |
|             var packet = MakePacket(0, 'R', "SB","%PW000", 8); //"00RSB06%PW00008"
 | |
|             var buffer = WriteSync(packet);
 | |
|             if(buffer != null)
 | |
|             {
 | |
|                 var frame = Parse_RecvBuffer(buffer);
 | |
|                 if(!frame.isError)
 | |
|                 {
 | |
|                     this.Run_RelayPortData(ref frame);
 | |
|                     lastrecvTime = DateTime.Now;    
 | |
|                 }
 | |
|                     
 | |
|                 LastRecvMessage = frame;
 | |
|             }
 | |
|             _mre.Set();
 | |
|             return buffer != null;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 
 | |
|         /// </summary>
 | |
|         /// <param name="Station">0~9</param>
 | |
|         /// <param name="Command">R,W</param>
 | |
|         /// <param name="CmdType">SB,SW ??</param>
 | |
|         /// <param name="Device">%PW000</param>
 | |
|         /// <param name="NumberofData">1</param>
 | |
|         /// <param name="data">HexString</param>
 | |
|         /// <returns></returns>
 | |
|         public string MakePacket(byte Station,char Command,string CmdType,string Device,byte NumberofData,string data = "")
 | |
|         {
 | |
|             string buffer = Station.ToString("X2").PadLeft(2, '0') +
 | |
|                 Command +
 | |
|                 CmdType +
 | |
|                 Device.Length.ToString("X2").PadLeft(2, '0') +
 | |
|                 Device +
 | |
|                 NumberofData.ToString("X2").PadLeft(2, '0');
 | |
|             if (data != "") buffer += data;
 | |
|             return buffer;
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|     }
 | |
| 
 | |
| }
 | 
