From 1eb59a0127e9d366c18492dea24ad99a799fd49b Mon Sep 17 00:00:00 2001 From: backuppc Date: Wed, 5 Nov 2025 14:28:32 +0900 Subject: [PATCH] .. --- ReadMe.MD | 17 +- enigprotocol/Commands.cs | 23 ++- enigprotocol/EEProtocol.cs | 382 ++++++++++++++++++------------------- enigprotocol/EventArgs.cs | 26 +-- enigprotocol/Packet.cs | 34 ++-- 5 files changed, 253 insertions(+), 229 deletions(-) diff --git a/ReadMe.MD b/ReadMe.MD index 1c2f529..88c24a2 100644 --- a/ReadMe.MD +++ b/ReadMe.MD @@ -41,13 +41,13 @@ This README provides a comprehensive overview of the `ENIGProtocol` library, mak public enum DeviceType : byte { ACS = 0, - AGV1 = 10, - AGV2 = 11, - BUFFER1 = 20, - BUFFER2 = 21, - BUFFER3 = 22, - BUFFER4 = 23, - BUFFER5 = 24, + AGV1 = 10+1, + AGV2 = 10+2, + BUFFER1 = 20+1, + BUFFER2 = 20+2, + BUFFER3 = 20+3, + BUFFER4 = 20+4, + BUFFER5 = 20+5, DOOR = 30, } ``` @@ -82,6 +82,9 @@ public enum DeviceType : byte - H -> E | Move : cmd(100) : 대상태그까지 이동(자동이동) - Target[1] = {DeviceType} - TagID[4] = 0000 + - H -> E | Move : cmd(107) : 대상별칭까지 이동(자동이동) + - Target[1] = {DeviceType} + - TagID[4] = 0000 - H -> E | Stop : cmd(101) : 멈춤 - H -> E | Reset : cmd(102) : 오류 소거 - H -> E | Charge On: cmd(103) : 충전실행(충전기 이동 후 자동 충전 진행) diff --git a/enigprotocol/Commands.cs b/enigprotocol/Commands.cs index f443da9..f342ed3 100644 --- a/enigprotocol/Commands.cs +++ b/enigprotocol/Commands.cs @@ -4,7 +4,10 @@ using System.Text; namespace ENIGProtocol { - public enum AGVCommands + /// + /// host -> eq + /// + public enum AGVCommandHE : byte { Goto = 100, Stop = 101, @@ -14,4 +17,22 @@ namespace ENIGProtocol MarkStop, LiftControl } + + /// + /// eq -> host + /// + public enum AGVCommandEH : byte + { + Error = 1, + Arrived = 2, + ReadRFID = 3, + Status=9, + } + + public enum AGVErrorCode : byte + { + PredictFix, + TurnTimeout, + TurnError, + } } diff --git a/enigprotocol/EEProtocol.cs b/enigprotocol/EEProtocol.cs index d3bea66..b9c1884 100644 --- a/enigprotocol/EEProtocol.cs +++ b/enigprotocol/EEProtocol.cs @@ -1,55 +1,55 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace ENIG -{ - // 장비 타입 정의 - public enum DeviceType - { - ACS = 0, - AGV1 = 10, - AGV2 = 11, - BUFFER1 = 20, - BUFFER2 = 21, - BUFFER3 = 22, - BUFFER4 = 23, - BUFFER5 = 24, - DOOR = 30, - } - - public partial class EEProtocol - { - // 패킷 수신 이벤트 정의 - // 데이터 수신 이벤트 정의 - public event EventHandler OnDataReceived; - public event EventHandler OnMessage; - - // CRC16 계산을 위한 테이블 - private static readonly ushort[] CRC16_TABLE = new ushort[256]; - - // CRC16 테이블 초기화 - public EEProtocol() - { - const ushort polynomial = 0x7979; - for (ushort i = 0; i < CRC16_TABLE.Length; i++) - { - ushort value = 0; - ushort temp = i; - for (byte j = 0; j < 8; j++) - { - if (((value ^ temp) & 0x0001) != 0) - { - value = (ushort)((value >> 1) ^ polynomial); - } - else - { - value >>= 1; - } - temp >>= 1; - } - CRC16_TABLE[i] = value; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace ENIG +{ + // 장비 타입 정의 + public enum DeviceType + { + ACS = 0, + AGV1 = 10, + AGV2 = 11, + BUFFER1 = 20, + BUFFER2 = 21, + BUFFER3 = 22, + BUFFER4 = 23, + BUFFER5 = 24, + DOOR = 30, + } + + public partial class EEProtocol + { + // 패킷 수신 이벤트 정의 + // 데이터 수신 이벤트 정의 + public event EventHandler OnDataReceived; + public event EventHandler OnMessage; + + // CRC16 계산을 위한 테이블 + private static readonly ushort[] CRC16_TABLE = new ushort[256]; + + // CRC16 테이블 초기화 + public EEProtocol() + { + const ushort polynomial = 0x7979; + for (ushort i = 0; i < CRC16_TABLE.Length; i++) + { + ushort value = 0; + ushort temp = i; + for (byte j = 0; j < 8; j++) + { + if (((value ^ temp) & 0x0001) != 0) + { + value = (ushort)((value >> 1) ^ polynomial); + } + else + { + value >>= 1; + } + temp >>= 1; + } + CRC16_TABLE[i] = value; } //// CRC 테이블 출력 @@ -62,162 +62,162 @@ namespace ENIG // } // Console.Write($"0x{CRC16_TABLE[i]:X4}, "); //} - //Console.WriteLine(); - - - } - - // CRC16 계산 메서드 - public ushort CalculateCRC16(byte[] data) - { - ushort crc = 0xFFFF; - for (int i = 0; i < data.Length; i++) - { - byte index = (byte)(crc ^ data[i]); - crc = (ushort)((crc >> 8) ^ CRC16_TABLE[index]); - } - return crc; - } - - // 패킷 생성 메서드 - public byte[] CreatePacket(byte id, byte command, byte[] data) - { - var packet = new Packet - { - ID = id, - Command = command, - Data = data ?? new byte[0], - Length = (byte)(1 + 1 + (data?.Length ?? 0)) // ID + Command + Data 길이 - }; - - // 패킷 조립 - List packetData = new List(); - packetData.Add(Packet.STX); - packetData.Add(packet.Length); - packetData.Add(packet.ID); - packetData.Add(packet.Command); - if (packet.Data != null) - packetData.AddRange(packet.Data); - - // CRC16 계산 - packet.CRC16 = CalculateCRC16(packetData.Skip(1).ToArray()); // STX 제외하고 계산 - packetData.AddRange(BitConverter.GetBytes(packet.CRC16)); - packetData.Add(Packet.ETX); - - return packetData.ToArray(); - } - - //패킷테스트 - public void PacketTest(byte[] rawData) - { - var hexstr = string.Join(" ", rawData.Select(t => t.ToString("X2"))); - RaiseMessage( $"TestPacket : {hexstr}"); - ParsePacket(rawData); - } - - //메세지 발생 - public void RaiseMessage(string message, bool isError = false) - { - OnMessage?.Invoke(this, new MessageEventArgs { IsError = isError, Message = message }); - } - - // 패킷 파싱 메서드 - public bool ParsePacket(byte[] rawData) - { - try - { + //Console.WriteLine(); + + + } + + // CRC16 계산 메서드 + public ushort CalculateCRC16(byte[] data) + { + ushort crc = 0xFFFF; + for (int i = 0; i < data.Length; i++) + { + byte index = (byte)(crc ^ data[i]); + crc = (ushort)((crc >> 8) ^ CRC16_TABLE[index]); + } + return crc; + } + + // 패킷 생성 메서드 + public byte[] CreatePacket(byte id, byte command, byte[] data) + { + var packet = new Packet + { + ID = id, + Command = command, + Data = data ?? new byte[0], + Length = (byte)(1 + 1 + (data?.Length ?? 0)) // ID + Command + Data 길이 + }; + + // 패킷 조립 + List packetData = new List(); + packetData.Add(Packet.STX); + packetData.Add(packet.Length); + packetData.Add(packet.ID); + packetData.Add(packet.Command); + if (packet.Data != null) + packetData.AddRange(packet.Data); + + // CRC16 계산 + packet.CRC16 = CalculateCRC16(packetData.Skip(1).ToArray()); // STX 제외하고 계산 + packetData.AddRange(BitConverter.GetBytes(packet.CRC16)); + packetData.Add(Packet.ETX); + + return packetData.ToArray(); + } + + //패킷테스트 + public void PacketTest(byte[] rawData) + { + var hexstr = string.Join(" ", rawData.Select(t => t.ToString("X2"))); + RaiseMessage( $"TestPacket : {hexstr}"); + ParsePacket(rawData); + } + + //메세지 발생 + public void RaiseMessage(string message, bool isError = false) + { + OnMessage?.Invoke(this, new MessageEventArgs { IsError = isError, Message = message }); + } + + // 패킷 파싱 메서드 + public bool ParsePacket(byte[] rawData) + { + try + { if (rawData.Length < 7) // 최소 패킷 크기 { var hexstring = string.Join(" ", rawData.Select(t => t.ToString("X2"))); RaiseMessage($"Too Short Data:{hexstring}"); return false; - } - - + } + + if (rawData[0] != Packet.STX || rawData[rawData.Length - 1] != Packet.ETX) { var hexstring = string.Join(" ", rawData.Select(t => t.ToString("X2"))); RaiseMessage($"STX/ETX Error Data:{hexstring}"); return false; - } - - - byte length = rawData[1]; + } + + + byte length = rawData[1]; if (length + 5 != rawData.Length) // STX + Length + CRC16(2) + ETX = 5 { var hexstring = string.Join(" ", rawData.Select(t => t.ToString("X2"))); RaiseMessage($"Length Error ({length+5} != {rawData.Length}) Data:{hexstring}"); return false; - } - - - // CRC16 검증 - byte[] dataForCrc = rawData.Skip(1).Take(length + 1).ToArray(); - ushort calculatedCrc = CalculateCRC16(dataForCrc); - ushort receivedCrc = BitConverter.ToUInt16(rawData, rawData.Length - 3); - + } + + + // CRC16 검증 + byte[] dataForCrc = rawData.Skip(1).Take(length + 1).ToArray(); + ushort calculatedCrc = CalculateCRC16(dataForCrc); + ushort receivedCrc = BitConverter.ToUInt16(rawData, rawData.Length - 3); + if (receivedCrc != 0xFFFF && calculatedCrc != receivedCrc) //FF 무시 { RaiseMessage($"CRC Error ID:{rawData[2]:X2},CMD:{rawData[3]:X2}", true); return false; - } - - - // 패킷 생성 - var packet = new Packet - { - Length = length, - ID = rawData[2], - Command = rawData[3], - Data = rawData.Skip(4).Take(length - 2).ToArray(), // ID와 Command 길이(2) 제외 - CRC16 = receivedCrc, - RawData = rawData, - }; - - // 이벤트 발생 - OnDataReceived?.Invoke(this, new DataEventArgs { ReceivedPacket = packet }); - return true; - } - catch - { - return false; - } - } - - // 데이터 수신 처리 메서드 (시리얼 포트에서 데이터를 받았을 때 호출) - private List buffer = new List(); - public void ProcessReceivedData(byte[] data) - { - buffer.AddRange(data); - - while (buffer.Count > 0) - { - // STX 찾기 - int stxIndex = buffer.FindIndex(b => b == Packet.STX); - if (stxIndex == -1) - { - buffer.Clear(); - break; - } - - // 불필요한 데이터 제거 - if (stxIndex > 0) - buffer.RemoveRange(0, stxIndex); - - // 패킷 길이 확인을 위한 최소 데이터 확인 - if (buffer.Count < 2) - break; - - int expectedLength = buffer[1] + 5; // 전체 패킷 길이 - if (buffer.Count < expectedLength) - break; - - // 패킷 추출 및 처리 - byte[] packetData = buffer.Take(expectedLength).ToArray(); - buffer.RemoveRange(0, expectedLength); - - ParsePacket(packetData); - } - } - } + } + + + // 패킷 생성 + var packet = new Packet + { + Length = length, + ID = rawData[2], + Command = rawData[3], + Data = rawData.Skip(4).Take(length - 2).ToArray(), // ID와 Command 길이(2) 제외 + CRC16 = receivedCrc, + RawData = rawData, + }; + + // 이벤트 발생 + OnDataReceived?.Invoke(this, new DataEventArgs { ReceivedPacket = packet }); + return true; + } + catch + { + return false; + } + } + + // 데이터 수신 처리 메서드 (시리얼 포트에서 데이터를 받았을 때 호출) + private List buffer = new List(); + public void ProcessReceivedData(byte[] data) + { + buffer.AddRange(data); + + while (buffer.Count > 0) + { + // STX 찾기 + int stxIndex = buffer.FindIndex(b => b == Packet.STX); + if (stxIndex == -1) + { + buffer.Clear(); + break; + } + + // 불필요한 데이터 제거 + if (stxIndex > 0) + buffer.RemoveRange(0, stxIndex); + + // 패킷 길이 확인을 위한 최소 데이터 확인 + if (buffer.Count < 2) + break; + + int expectedLength = buffer[1] + 5; // 전체 패킷 길이 + if (buffer.Count < expectedLength) + break; + + // 패킷 추출 및 처리 + byte[] packetData = buffer.Take(expectedLength).ToArray(); + buffer.RemoveRange(0, expectedLength); + + ParsePacket(packetData); + } + } + } } \ No newline at end of file diff --git a/enigprotocol/EventArgs.cs b/enigprotocol/EventArgs.cs index dc1e266..a3884f4 100644 --- a/enigprotocol/EventArgs.cs +++ b/enigprotocol/EventArgs.cs @@ -1,18 +1,18 @@ -using System; - -namespace ENIG -{ - - public partial class EEProtocol - { +using System; + +namespace ENIG +{ + + public partial class EEProtocol + { public class MessageEventArgs : EventArgs { public string Message { get; set; } public bool IsError { get; set; } - } - public class DataEventArgs : EventArgs - { - public Packet ReceivedPacket { get; set; } - } - } + } + public class DataEventArgs : EventArgs + { + public Packet ReceivedPacket { get; set; } + } + } } \ No newline at end of file diff --git a/enigprotocol/Packet.cs b/enigprotocol/Packet.cs index 1eee804..92d96df 100644 --- a/enigprotocol/Packet.cs +++ b/enigprotocol/Packet.cs @@ -1,20 +1,20 @@ -namespace ENIG +namespace ENIG { // 패킷 구조체 - public class Packet - { - public const byte STX = 0x02; - public const byte ETX = 0x03; - public byte Length { get; set; } - public byte ID { get; set; } - public byte Command { get; set; } - public byte[] Data { get; set; } - public ushort CRC16 { get; set; } - - public byte[] RawData { get; set; } - public Packet() - { - Data = new byte[0]; - } - } + public class Packet + { + public const byte STX = 0x02; + public const byte ETX = 0x03; + public byte Length { get; set; } + public byte ID { get; set; } + public byte Command { get; set; } + public byte[] Data { get; set; } + public ushort CRC16 { get; set; } + + public byte[] RawData { get; set; } + public Packet() + { + Data = new byte[0]; + } + } } \ No newline at end of file