diff --git a/Cs_HMI/Project/StateMachine/_SPS.cs b/Cs_HMI/Project/StateMachine/_SPS.cs index e16910f..4663dbd 100644 --- a/Cs_HMI/Project/StateMachine/_SPS.cs +++ b/Cs_HMI/Project/StateMachine/_SPS.cs @@ -207,7 +207,7 @@ namespace Project //연결은 되었으나 통신이 지난지 10초가 지났다면 자동종료한다 var tsRecv = VAR.TIME.RUN(recvtime); var tsConn = VAR.TIME.RUN(conntry); - if (tsRecv.TotalSeconds > 10 && tsConn.TotalSeconds > 5) + if (tsRecv.TotalSeconds > 30 && tsConn.TotalSeconds > 5) { this.BeginInvoke(new Action(() => { diff --git a/Cs_HMI/SubProject/AGV/Narumi.cs b/Cs_HMI/SubProject/AGV/Narumi.cs index 825cf58..f65e041 100644 --- a/Cs_HMI/SubProject/AGV/Narumi.cs +++ b/Cs_HMI/SubProject/AGV/Narumi.cs @@ -267,8 +267,12 @@ namespace arDev nDataTemp = Convert.ToByte(rcvdNow.Substring(idx, 2), 16); signal1.SetValue(nDataTemp); idx += 2; - nDataTemp = Convert.ToByte(rcvdNow.Substring(idx, 2), 16); - signal2.SetValue(nDataTemp); + if(idx < rcvdNow.Length-2) + { + nDataTemp = Convert.ToByte(rcvdNow.Substring(idx, 2), 16); + signal2.SetValue(nDataTemp); + } + DataReceive?.Invoke(this, new DataEventArgs(DataType.STS)); diff --git a/Cs_HMI/SubProject/AGV/NarumiSerialComm.cs b/Cs_HMI/SubProject/AGV/NarumiSerialComm.cs index 7725af9..23f26a9 100644 --- a/Cs_HMI/SubProject/AGV/NarumiSerialComm.cs +++ b/Cs_HMI/SubProject/AGV/NarumiSerialComm.cs @@ -51,6 +51,12 @@ namespace arDev public string WriteErrorMessage = string.Empty; public int WaitTimeout { get; set; } = 1000; public int MinRecvLength { get; set; } = 1; + + // Polling Thread related + protected Thread _recvThread; + protected volatile bool _isReading = false; + + /// /// 포트이름 /// @@ -103,7 +109,7 @@ namespace arDev _device = new System.IO.Ports.SerialPort(); this.BaudRate = 9600; ScanInterval = 10; - _device.DataReceived += barcode_DataReceived; + // _device.DataReceived += barcode_DataReceived; // Removed event handler _device.ErrorReceived += this.barcode_ErrorReceived; _device.WriteTimeout = 3000; _device.ReadTimeout = 3000; @@ -147,9 +153,23 @@ namespace arDev // } - _device.DataReceived -= barcode_DataReceived; + // Stop reading thread + _isReading = false; + + // _device.DataReceived -= barcode_DataReceived; // Removed event handler _device.ErrorReceived -= this.barcode_ErrorReceived; + if (_recvThread != null && _recvThread.IsAlive) + { + _recvThread.Join(500); + } + + if (_device != null) + { + if (_device.IsOpen) _device.Close(); + _device.Dispose(); + } + // Free any unmanaged objects here. // disposed = true; @@ -159,8 +179,24 @@ namespace arDev { try { - _device.Open(); - return IsOpen; + if (_device.IsOpen == false) + { + _device.Open(); + } + + if (_device.IsOpen) + { + // Start polling thread + if (_isReading == false) + { + _isReading = true; + _recvThread = new Thread(ReadPort); + _recvThread.IsBackground = true; + _recvThread.Start(); + } + return true; + } + return false; } catch (Exception ex) { @@ -193,14 +229,31 @@ namespace arDev public virtual bool Close() { - if (_device != null && _device.IsOpen) + try { - _device.DiscardInBuffer(); - _device.DiscardOutBuffer(); - _device.Close(); //dispose에서는 포트를 직접 클리어하지 않게 해뒀다. - return true; + _isReading = false; // Stop thread loop + + if (_recvThread != null && _recvThread.IsAlive) + { + if (!_recvThread.Join(500)) // Wait for thread to finish + { + // _recvThread.Abort(); // Avoid Abort if possible + } + } + + if (_device != null && _device.IsOpen) + { + _device.DiscardInBuffer(); + _device.DiscardOutBuffer(); + _device.Close(); //dispose에서는 포트를 직접 클리어하지 않게 해뒀다. + return true; + } + else return false; + } + catch (Exception) + { + return false; } - else return false; } protected Boolean RaiseRecvData() { @@ -226,6 +279,9 @@ namespace arDev try { + // UI update might need Invoke if this event handler updates UI directly, + // but usually the subscriber handles Invoke. + // Since we are running on a background thread now, subscribers must be aware. Message?.Invoke(this, new MessageEventArgs(Data, true)); //recvmessage if (ProcessRecvData(Data) == false) { @@ -262,9 +318,12 @@ namespace arDev } byte[] buffer = new byte[] { }; + + // Replaced with ReadPort Loop + /* void barcode_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { - + try { int ReadCount = _device.BytesToRead; @@ -308,6 +367,62 @@ namespace arDev } } + */ + + void ReadPort() + { + while (_isReading) + { + try + { + if (_device == null || !_device.IsOpen) + { + Thread.Sleep(100); + continue; + } + + int readCount = _device.BytesToRead; + if (readCount > 0) + { + byte[] buffer = new byte[readCount]; + _device.Read(buffer, 0, buffer.Length); + + byte[] remainBuffer; + Repeat: + if (CustomParser(buffer, out remainBuffer)) + { + //분석완료이므로 받은 데이터를 버퍼에 기록한다 + if (LastReceiveBuffer == null || (LastReceiveBuffer.Length != tempBuffer.Count)) + Array.Resize(ref LastReceiveBuffer, tempBuffer.Count); + Array.Copy(tempBuffer.ToArray(), LastReceiveBuffer, tempBuffer.Count); + tempBuffer.Clear(); + + //수신메세지발생 + RaiseRecvData(); + if (remainBuffer != null && remainBuffer.Length > 0) + { + //버퍼를 변경해서 다시 전송을 해준다. + buffer = new byte[remainBuffer.Length]; // Reallocate buffer for remaining data + Array.Copy(remainBuffer, buffer, remainBuffer.Length); + goto Repeat; //남은 버퍼가 있다면 진행을 해준다. + } + } + } + else + { + Thread.Sleep(20); // Data 없음, 대기 + } + } + catch (Exception ex) + { + // Thread 상에서 Exception 발생 시 로그 남기고 계속 진행 여부 결정 + // 여기서는 에러 메시지 발생시키고 Sleep + ErrorMessage = ex.Message; + this.Message?.Invoke(this, new MessageEventArgs(ex.Message, true)); + Thread.Sleep(1000); + } + } + } #endregion diff --git a/Cs_HMI/SubProject/CommUtil b/Cs_HMI/SubProject/CommUtil index b070b71..ed05439 160000 --- a/Cs_HMI/SubProject/CommUtil +++ b/Cs_HMI/SubProject/CommUtil @@ -1 +1 @@ -Subproject commit b070b711f0167eb7a90f443bd860fb5c16efd5bd +Subproject commit ed05439991fdddba2d7123b7a89a89245bcd044c diff --git a/Document/이메일/RE_ _이노텍_ 통신 프로토콜 송부건 (AGV_V350_LF)-pic다운로드메뉴얼.msg b/Document/이메일/RE_ _이노텍_ 통신 프로토콜 송부건 (AGV_V350_LF)-pic다운로드메뉴얼.msg new file mode 100644 index 0000000..0c65996 Binary files /dev/null and b/Document/이메일/RE_ _이노텍_ 통신 프로토콜 송부건 (AGV_V350_LF)-pic다운로드메뉴얼.msg differ diff --git a/Document/이메일/RE_ _이노텍_ 통신 프로토콜 송부건 (AGV_V350_LF)-프토토콜+펌웨어파일.msg b/Document/이메일/RE_ _이노텍_ 통신 프로토콜 송부건 (AGV_V350_LF)-프토토콜+펌웨어파일.msg new file mode 100644 index 0000000..29296ac Binary files /dev/null and b/Document/이메일/RE_ _이노텍_ 통신 프로토콜 송부건 (AGV_V350_LF)-프토토콜+펌웨어파일.msg differ diff --git a/Document/이메일/_이노텍_ RFID 헥사파일 송부건.msg b/Document/이메일/_이노텍_ RFID 헥사파일 송부건.msg new file mode 100644 index 0000000..dce1763 Binary files /dev/null and b/Document/이메일/_이노텍_ RFID 헥사파일 송부건.msg differ diff --git a/Document/이메일/_이노텍_ 리프트형 AGV 펌웨어 송부건.msg b/Document/이메일/_이노텍_ 리프트형 AGV 펌웨어 송부건.msg new file mode 100644 index 0000000..98ee848 Binary files /dev/null and b/Document/이메일/_이노텍_ 리프트형 AGV 펌웨어 송부건.msg differ diff --git a/Document/이메일/_이노텍_ 통신 프로토콜 송부건 (AGV_V350_LF)-프로토콜.msg b/Document/이메일/_이노텍_ 통신 프로토콜 송부건 (AGV_V350_LF)-프로토콜.msg new file mode 100644 index 0000000..7307f8f Binary files /dev/null and b/Document/이메일/_이노텍_ 통신 프로토콜 송부건 (AGV_V350_LF)-프로토콜.msg differ diff --git a/Document/통신프로토콜/리듐인산철 통신프로토콜정리 .xlsx b/Document/통신프로토콜/리듐인산철 통신프로토콜정리 .xlsx new file mode 100644 index 0000000..993980d Binary files /dev/null and b/Document/통신프로토콜/리듐인산철 통신프로토콜정리 .xlsx differ diff --git a/Document/통신프로토콜/통신 프로토콜_AGV_V350_LF_24.11.20.xlsx b/Document/통신프로토콜/통신 프로토콜_AGV_V350_LF_24.11.20.xlsx new file mode 100644 index 0000000..651b78c Binary files /dev/null and b/Document/통신프로토콜/통신 프로토콜_AGV_V350_LF_24.11.20.xlsx differ diff --git a/Document/통신프로토콜/통신 프로토콜_AGV_V350_LF_25.01.10.xlsx b/Document/통신프로토콜/통신 프로토콜_AGV_V350_LF_25.01.10.xlsx new file mode 100644 index 0000000..91da91a Binary files /dev/null and b/Document/통신프로토콜/통신 프로토콜_AGV_V350_LF_25.01.10.xlsx differ diff --git a/Document/통신프로토콜/통신 프로토콜_AGV_V350_LF_25.01.10_r2.xlsx b/Document/통신프로토콜/통신 프로토콜_AGV_V350_LF_25.01.10_r2.xlsx new file mode 100644 index 0000000..2ede3bf Binary files /dev/null and b/Document/통신프로토콜/통신 프로토콜_AGV_V350_LF_25.01.10_r2.xlsx differ