From 5d286d5179077e687fe53bbdb4c6a78b219ac429 Mon Sep 17 00:00:00 2001 From: chi Date: Tue, 22 Apr 2025 11:36:27 +0900 Subject: [PATCH] initial commit --- .gitignore | 13 + .vscode/settings.json | 3 + ENIGProtocol.Tests/EEProtocolTests.cs | 52 +++ ENIGProtocol.Tests/ENIGProtocol.Tests.csproj | 33 ++ ENIGProtocol.Tests/UnitTest1.cs | 10 + ENIGProtocol.sln | 37 ++ ReadMe.MD | 160 +++++++ enigprotocol/.gitignore | 8 + enigprotocol/EEProtocol.cs | 223 +++++++++ enigprotocol/ENIGProtocol.csproj | 7 + enigprotocol/EventArgs.cs | 18 + enigprotocol/Packet.cs | 20 + sample/App.config | 6 + sample/Form1.Designer.cs | 447 +++++++++++++++++++ sample/Form1.cs | 216 +++++++++ sample/Form1.resx | 126 ++++++ sample/Program.cs | 22 + sample/Properties/AssemblyInfo.cs | 36 ++ sample/Properties/Resources.Designer.cs | 71 +++ sample/Properties/Resources.resx | 117 +++++ sample/Properties/Settings.Designer.cs | 30 ++ sample/Properties/Settings.settings | 7 + sample/SampleProject.csproj | 92 ++++ sample/arCommUtil.dll | Bin 0 -> 192512 bytes 24 files changed, 1754 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 ENIGProtocol.Tests/EEProtocolTests.cs create mode 100644 ENIGProtocol.Tests/ENIGProtocol.Tests.csproj create mode 100644 ENIGProtocol.Tests/UnitTest1.cs create mode 100644 ENIGProtocol.sln create mode 100644 ReadMe.MD create mode 100644 enigprotocol/.gitignore create mode 100644 enigprotocol/EEProtocol.cs create mode 100644 enigprotocol/ENIGProtocol.csproj create mode 100644 enigprotocol/EventArgs.cs create mode 100644 enigprotocol/Packet.cs create mode 100644 sample/App.config create mode 100644 sample/Form1.Designer.cs create mode 100644 sample/Form1.cs create mode 100644 sample/Form1.resx create mode 100644 sample/Program.cs create mode 100644 sample/Properties/AssemblyInfo.cs create mode 100644 sample/Properties/Resources.Designer.cs create mode 100644 sample/Properties/Resources.resx create mode 100644 sample/Properties/Settings.Designer.cs create mode 100644 sample/Properties/Settings.settings create mode 100644 sample/SampleProject.csproj create mode 100644 sample/arCommUtil.dll diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6f0598c --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +obj +bin +*.user +*.v12 +*.suo +.git +.vs +Debug +__vm +*.pdb +desktop.ini +packages +~*.xlsx diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..359cd76 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "dotnet.preferCSharpExtension": true +} \ No newline at end of file diff --git a/ENIGProtocol.Tests/EEProtocolTests.cs b/ENIGProtocol.Tests/EEProtocolTests.cs new file mode 100644 index 0000000..f54a8d7 --- /dev/null +++ b/ENIGProtocol.Tests/EEProtocolTests.cs @@ -0,0 +1,52 @@ +using Xunit; +using ENIG; + +namespace ENIGProtocol.Tests +{ + public class EEProtocolTests + { + [Fact] + public void TestCRC16Calculation() + { + // 테스트 데이터 + byte[] testData = new byte[] { 0x02,0x00,0xFF }; + + // CRC16 계산 + var protocol = new EEProtocol(); + ushort crc = protocol.CalculateCRC16(testData); + + // 예상 결과와 비교 + Assert.Equal(0x1789, crc); // 실제 예상값으로 수정 필요 + } + + [Fact] + public void TestPacketCreation() + { + // 패킷 생성 테스트 + var protocol = new EEProtocol(); + byte[] packet = protocol.CreatePacket(0x01, 0x02, new byte[] { 0x03, 0x04 }); + + // 패킷 구조 검증 + Assert.Equal(0x02, packet[0]); // STX + Assert.Equal(0x04, packet[1]); // Length + Assert.Equal(0x01, packet[2]); // ID + Assert.Equal(0x02, packet[3]); // Command + Assert.Equal(0x03, packet[4]); // Data[0] + Assert.Equal(0x04, packet[5]); // Data[1] + } + + [Fact] + public void TestPacketParsing() + { + // 패킷 파싱 테스트 + var protocol = new EEProtocol(); + //byte[] testPacket = new byte[] { 0x02, 0x04, 0x01, 0x02, 0x03, 0x04, 0x12, 0x34, 0x03 }; + byte[] testPacket = new byte[] { 0x02, 0x02, 0x00, 0xFF, 0x89, 0x17, 0x03 }; + + + bool result = protocol.ParsePacket(testPacket); + + Assert.True(result); + } + } +} \ No newline at end of file diff --git a/ENIGProtocol.Tests/ENIGProtocol.Tests.csproj b/ENIGProtocol.Tests/ENIGProtocol.Tests.csproj new file mode 100644 index 0000000..fcb8f69 --- /dev/null +++ b/ENIGProtocol.Tests/ENIGProtocol.Tests.csproj @@ -0,0 +1,33 @@ + + + + net6.0 + enable + enable + + false + true + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + + + diff --git a/ENIGProtocol.Tests/UnitTest1.cs b/ENIGProtocol.Tests/UnitTest1.cs new file mode 100644 index 0000000..5ed2225 --- /dev/null +++ b/ENIGProtocol.Tests/UnitTest1.cs @@ -0,0 +1,10 @@ +namespace ENIGProtocol.Tests; + +public class UnitTest1 +{ + [Fact] + public void Test1() + { + + } +} \ No newline at end of file diff --git a/ENIGProtocol.sln b/ENIGProtocol.sln new file mode 100644 index 0000000..3fc2298 --- /dev/null +++ b/ENIGProtocol.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34714.143 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ENIGProtocol", "enigprotocol\ENIGProtocol.csproj", "{B6FCA1B0-C9D1-4159-AB86-25E4BC598C01}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleProject", "sample\SampleProject.csproj", "{FAB31C8A-7DCF-4152-8A82-76F3C10BABA4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ENIGProtocol.Tests", "ENIGProtocol.Tests\ENIGProtocol.Tests.csproj", "{3A677629-1F08-49B2-BC75-58282E439FD4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B6FCA1B0-C9D1-4159-AB86-25E4BC598C01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B6FCA1B0-C9D1-4159-AB86-25E4BC598C01}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B6FCA1B0-C9D1-4159-AB86-25E4BC598C01}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B6FCA1B0-C9D1-4159-AB86-25E4BC598C01}.Release|Any CPU.Build.0 = Release|Any CPU + {FAB31C8A-7DCF-4152-8A82-76F3C10BABA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FAB31C8A-7DCF-4152-8A82-76F3C10BABA4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FAB31C8A-7DCF-4152-8A82-76F3C10BABA4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FAB31C8A-7DCF-4152-8A82-76F3C10BABA4}.Release|Any CPU.Build.0 = Release|Any CPU + {3A677629-1F08-49B2-BC75-58282E439FD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3A677629-1F08-49B2-BC75-58282E439FD4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3A677629-1F08-49B2-BC75-58282E439FD4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3A677629-1F08-49B2-BC75-58282E439FD4}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {07331835-C46C-4B93-965F-AD2714F97F88} + EndGlobalSection +EndGlobal diff --git a/ReadMe.MD b/ReadMe.MD new file mode 100644 index 0000000..cc3bb5a --- /dev/null +++ b/ReadMe.MD @@ -0,0 +1,160 @@ +# ENIG Protocol + +ENIG 프로토콜 통신 라이브러리 + +**Explanation of the README Content:** + +1. **Title and Overview:** Clearly states the purpose of the library. +2. **Key Components:** Explains the main building blocks: + * `DeviceType` enum: Lists the device types. + * `Packet` class: Describes the packet structure. + * `EEProtocol` class: Explains its role in packet handling. +3. **Key Features:** Details the core functionalities of the `EEProtocol` class: + * Packet creation. + * Packet parsing. + * Data reception. + * Event-driven nature. + * CRC16 calculation. +4. **Usage:** Provides code examples for: + * Creating a packet. + * Parsing a packet. + * Processing received data. +5. **Error Handling:** Explains how the library handles invalid data and incomplete packets. +6. **Dependencies:** Lists any required frameworks or libraries. +7. **License:** Placeholder for the project's license. + +This README provides a comprehensive overview of the `ENIGProtocol` library, making it easy for other developers to understand and use it. I hope this is helpful! + + +## 개발 환경 +- Frameworks : .NET Standard 2.0 +- Visual Studio 2022 또는 Visual Studio Code + +## 프로젝트 구조 + +- `EEProtocol.cs`: ENIG 프로토콜 구현 +- `EEProtocolTests.cs`: 단위 테스트 코드 +- `Sample`: C# Winform 샘플 프로젝트 + + +### 기본 패킷 구조 +``` +[STX][LEN][CMD][DATA][CRC16][ETX] +``` + +- **STX (Start of Text)**: 0x02 +- **LEN (Length)**: 데이터 길이 (1바이트) = {CMD+DATA} +- **CMD (Command)**: 명령어 코드 (1바이트) +- **DATA**: 명령어에 따른 데이터 (가변 길이) +- **CRC16**: 데이터 무결성 검사 (2바이트) +- **ETX (End of Text)**: 0x03 + +### 통신 방향 (호스트=ACS, 장비=agv,buffer,door) +- H -> E: 호스트에서 장비로 전송 +- E -> H: 장비에서 호스트로 전송 + +### 명령어 목록 +1. **ACS (AGV Control System)** + - cmd(1): 출입문 열기 + - cmd(2): 출입문 닫기 + - cmd(3): 출입문 상태 확인 (응답: 1=열림, 0=닫힘) + +2. **Buffer** + - 버퍼 관리 관련 명령어 + +3. **AGV** + - AGV 제어 관련 명령어 + +4. **Door** + - H -> E | cmd(1): 출입문 열기 + - H -> E | cmd(2): 출입문 닫기 + - E -> H | cmd(3): 출입문 상태 (data len=1 : 1=열림, 0=닫힘) + +### CRC16 계산 +- CRC16 다항식 사용 +- 초기값: 0xFFFF +- 데이터 무결성 검증에 사용 + + +#### CRC-16 테이블 값 +``` +0x0000, 0x408E, 0x73EF, 0x3361, 0x152D, 0x55A3, 0x66C2, 0x264C, +0x2A5A, 0x6AD4, 0x59B5, 0x193B, 0x3F77, 0x7FF9, 0x4C98, 0x0C16, +0x54B4, 0x143A, 0x275B, 0x67D5, 0x4199, 0x0117, 0x3276, 0x72F8, +0x7EEE, 0x3E60, 0x0D01, 0x4D8F, 0x6BC3, 0x2B4D, 0x182C, 0x58A2, +0x5B9B, 0x1B15, 0x2874, 0x68FA, 0x4EB6, 0x0E38, 0x3D59, 0x7DD7, +0x71C1, 0x314F, 0x022E, 0x42A0, 0x64EC, 0x2462, 0x1703, 0x578D, +0x0F2F, 0x4FA1, 0x7CC0, 0x3C4E, 0x1A02, 0x5A8C, 0x69ED, 0x2963, +0x2575, 0x65FB, 0x569A, 0x1614, 0x3058, 0x70D6, 0x43B7, 0x0339, +0x45C5, 0x054B, 0x362A, 0x76A4, 0x50E8, 0x1066, 0x2307, 0x6389, +0x6F9F, 0x2F11, 0x1C70, 0x5CFE, 0x7AB2, 0x3A3C, 0x095D, 0x49D3, +0x1171, 0x51FF, 0x629E, 0x2210, 0x045C, 0x44D2, 0x77B3, 0x373D, +0x3B2B, 0x7BA5, 0x48C4, 0x084A, 0x2E06, 0x6E88, 0x5DE9, 0x1D67, +0x1E5E, 0x5ED0, 0x6DB1, 0x2D3F, 0x0B73, 0x4BFD, 0x789C, 0x3812, +0x3404, 0x748A, 0x47EB, 0x0765, 0x2129, 0x61A7, 0x52C6, 0x1248, +0x4AEA, 0x0A64, 0x3905, 0x798B, 0x5FC7, 0x1F49, 0x2C28, 0x6CA6, +0x60B0, 0x203E, 0x135F, 0x53D1, 0x759D, 0x3513, 0x0672, 0x46FC, +0x7979, 0x39F7, 0x0A96, 0x4A18, 0x6C54, 0x2CDA, 0x1FBB, 0x5F35, +0x5323, 0x13AD, 0x20CC, 0x6042, 0x460E, 0x0680, 0x35E1, 0x756F, +0x2DCD, 0x6D43, 0x5E22, 0x1EAC, 0x38E0, 0x786E, 0x4B0F, 0x0B81, +0x0797, 0x4719, 0x7478, 0x34F6, 0x12BA, 0x5234, 0x6155, 0x21DB, +0x22E2, 0x626C, 0x510D, 0x1183, 0x37CF, 0x7741, 0x4420, 0x04AE, +0x08B8, 0x4836, 0x7B57, 0x3BD9, 0x1D95, 0x5D1B, 0x6E7A, 0x2EF4, +0x7656, 0x36D8, 0x05B9, 0x4537, 0x637B, 0x23F5, 0x1094, 0x501A, +0x5C0C, 0x1C82, 0x2FE3, 0x6F6D, 0x4921, 0x09AF, 0x3ACE, 0x7A40, +0x3CBC, 0x7C32, 0x4F53, 0x0FDD, 0x2991, 0x691F, 0x5A7E, 0x1AF0, +0x16E6, 0x5668, 0x6509, 0x2587, 0x03CB, 0x4345, 0x7024, 0x30AA, +0x6808, 0x2886, 0x1BE7, 0x5B69, 0x7D25, 0x3DAB, 0x0ECA, 0x4E44, +0x4252, 0x02DC, 0x31BD, 0x7133, 0x577F, 0x17F1, 0x2490, 0x641E, +0x6727, 0x27A9, 0x14C8, 0x5446, 0x720A, 0x3284, 0x01E5, 0x416B, +0x4D7D, 0x0DF3, 0x3E92, 0x7E1C, 0x5850, 0x18DE, 0x2BBF, 0x6B31, +0x3393, 0x731D, 0x407C, 0x00F2, 0x26BE, 0x6630, 0x5551, 0x15DF, +0x19C9, 0x5947, 0x6A26, 0x2AA8, 0x0CE4, 0x4C6A, 0x7F0B, 0x3F85, +``` + + +#### CRC16 계산 테이블 생성 코드 +```csharp +const ushort polynomial = 0x7979; +ushort[] CRC16_TABLE = new ushort[256]; + +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; +} +``` + +#### CRC16 계산 예시 +```csharp +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; +} +``` + +## 라이센스 + + + + + diff --git a/enigprotocol/.gitignore b/enigprotocol/.gitignore new file mode 100644 index 0000000..a06bae1 --- /dev/null +++ b/enigprotocol/.gitignore @@ -0,0 +1,8 @@ +################################################################################ +# 이 .gitignore 파일은 Microsoft(R) Visual Studio에서 자동으로 만들어졌습니다. +################################################################################ + +/obj +/bin +/.vs +/.git diff --git a/enigprotocol/EEProtocol.cs b/enigprotocol/EEProtocol.cs new file mode 100644 index 0000000..d3bea66 --- /dev/null +++ b/enigprotocol/EEProtocol.cs @@ -0,0 +1,223 @@ +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 테이블 출력 + //Console.WriteLine("CRC16 테이블 값:"); + //for (int i = 0; i < CRC16_TABLE.Length; i++) + //{ + // if (i % 8 == 0) + // { + // Console.WriteLine(); + // } + // 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 + { + 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]; + 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); + + 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); + } + } + } +} \ No newline at end of file diff --git a/enigprotocol/ENIGProtocol.csproj b/enigprotocol/ENIGProtocol.csproj new file mode 100644 index 0000000..dbdcea4 --- /dev/null +++ b/enigprotocol/ENIGProtocol.csproj @@ -0,0 +1,7 @@ + + + + netstandard2.0 + + + diff --git a/enigprotocol/EventArgs.cs b/enigprotocol/EventArgs.cs new file mode 100644 index 0000000..dc1e266 --- /dev/null +++ b/enigprotocol/EventArgs.cs @@ -0,0 +1,18 @@ +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; } + } + } +} \ No newline at end of file diff --git a/enigprotocol/Packet.cs b/enigprotocol/Packet.cs new file mode 100644 index 0000000..1eee804 --- /dev/null +++ b/enigprotocol/Packet.cs @@ -0,0 +1,20 @@ +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]; + } + } +} \ No newline at end of file diff --git a/sample/App.config b/sample/App.config new file mode 100644 index 0000000..3916e0e --- /dev/null +++ b/sample/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/sample/Form1.Designer.cs b/sample/Form1.Designer.cs new file mode 100644 index 0000000..ab4bb62 --- /dev/null +++ b/sample/Form1.Designer.cs @@ -0,0 +1,447 @@ +namespace SampleProject +{ + partial class Form1 + { + /// + /// 필수 디자이너 변수입니다. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 사용 중인 모든 리소스를 정리합니다. + /// + /// 관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form 디자이너에서 생성한 코드 + + /// + /// 디자이너 지원에 필요한 메서드입니다. + /// 이 메서드의 내용을 코드 편집기로 수정하지 마세요. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.rtRx = new System.Windows.Forms.RichTextBox(); + this.rtTx = new System.Windows.Forms.RichTextBox(); + this.tbmsg = new System.Windows.Forms.TextBox(); + this.btsend = new System.Windows.Forms.Button(); + this.cmbport = new System.Windows.Forms.ComboBox(); + this.btconnect = new System.Windows.Forms.Button(); + this.tbbaud = new System.Windows.Forms.ComboBox(); + this.statusStrip1 = new System.Windows.Forms.StatusStrip(); + this.sbPort = new System.Windows.Forms.ToolStripStatusLabel(); + this.timer1 = new System.Windows.Forms.Timer(this.components); + this.cmbid = new System.Windows.Forms.ComboBox(); + this.btsim = new System.Windows.Forms.Button(); + this.rtMsg = new System.Windows.Forms.RichTextBox(); + this.tbCmd = new System.Windows.Forms.TextBox(); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.panel1 = new System.Windows.Forms.Panel(); + this.panel2 = new System.Windows.Forms.Panel(); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.label4 = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tabPage1 = new System.Windows.Forms.TabPage(); + this.tabPage2 = new System.Windows.Forms.TabPage(); + this.rtCmd = new System.Windows.Forms.RichTextBox(); + this.btload = new System.Windows.Forms.Button(); + this.btSave = new System.Windows.Forms.Button(); + this.statusStrip1.SuspendLayout(); + this.tableLayoutPanel1.SuspendLayout(); + this.panel1.SuspendLayout(); + this.panel2.SuspendLayout(); + this.tabControl1.SuspendLayout(); + this.tabPage1.SuspendLayout(); + this.tabPage2.SuspendLayout(); + this.SuspendLayout(); + // + // rtRx + // + this.rtRx.Dock = System.Windows.Forms.DockStyle.Fill; + this.rtRx.Font = new System.Drawing.Font("굴림", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129))); + this.rtRx.Location = new System.Drawing.Point(4, 5); + this.rtRx.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.rtRx.Name = "rtRx"; + this.rtRx.Size = new System.Drawing.Size(462, 318); + this.rtRx.TabIndex = 0; + this.rtRx.Text = ""; + // + // rtTx + // + this.rtTx.Dock = System.Windows.Forms.DockStyle.Fill; + this.rtTx.Font = new System.Drawing.Font("굴림", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129))); + this.rtTx.Location = new System.Drawing.Point(474, 5); + this.rtTx.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.rtTx.Name = "rtTx"; + this.rtTx.Size = new System.Drawing.Size(462, 318); + this.rtTx.TabIndex = 1; + this.rtTx.Text = ""; + // + // tbmsg + // + this.tbmsg.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(255)))), ((int)(((byte)(192))))); + this.tbmsg.Dock = System.Windows.Forms.DockStyle.Fill; + this.tbmsg.Font = new System.Drawing.Font("굴림", 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129))); + this.tbmsg.Location = new System.Drawing.Point(436, 5); + this.tbmsg.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.tbmsg.Name = "tbmsg"; + this.tbmsg.Size = new System.Drawing.Size(273, 44); + this.tbmsg.TabIndex = 2; + this.tbmsg.Text = "mesage"; + this.tbmsg.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this.tbmsg.TextChanged += new System.EventHandler(this.tbmsg_TextChanged); + // + // btsend + // + this.btsend.Dock = System.Windows.Forms.DockStyle.Right; + this.btsend.Font = new System.Drawing.Font("굴림", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(129))); + this.btsend.Location = new System.Drawing.Point(709, 5); + this.btsend.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.btsend.Name = "btsend"; + this.btsend.Size = new System.Drawing.Size(120, 42); + this.btsend.TabIndex = 3; + this.btsend.Text = "Send"; + this.btsend.UseVisualStyleBackColor = true; + this.btsend.Click += new System.EventHandler(this.btsend_Click); + // + // cmbport + // + this.cmbport.Dock = System.Windows.Forms.DockStyle.Left; + this.cmbport.Font = new System.Drawing.Font("굴림", 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129))); + this.cmbport.FormattingEnabled = true; + this.cmbport.Location = new System.Drawing.Point(58, 3); + this.cmbport.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.cmbport.Name = "cmbport"; + this.cmbport.Size = new System.Drawing.Size(218, 40); + this.cmbport.TabIndex = 4; + // + // btconnect + // + this.btconnect.Dock = System.Windows.Forms.DockStyle.Right; + this.btconnect.Location = new System.Drawing.Point(765, 3); + this.btconnect.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.btconnect.Name = "btconnect"; + this.btconnect.Size = new System.Drawing.Size(186, 40); + this.btconnect.TabIndex = 5; + this.btconnect.Text = "connect"; + this.btconnect.UseVisualStyleBackColor = true; + this.btconnect.Click += new System.EventHandler(this.btconnect_Click); + // + // tbbaud + // + this.tbbaud.Dock = System.Windows.Forms.DockStyle.Left; + this.tbbaud.Font = new System.Drawing.Font("굴림", 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129))); + this.tbbaud.FormattingEnabled = true; + this.tbbaud.Location = new System.Drawing.Point(331, 3); + this.tbbaud.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.tbbaud.Name = "tbbaud"; + this.tbbaud.Size = new System.Drawing.Size(171, 40); + this.tbbaud.TabIndex = 6; + this.tbbaud.Text = "9600"; + // + // statusStrip1 + // + this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.sbPort}); + this.statusStrip1.Location = new System.Drawing.Point(0, 583); + this.statusStrip1.Name = "statusStrip1"; + this.statusStrip1.Padding = new System.Windows.Forms.Padding(1, 0, 20, 0); + this.statusStrip1.Size = new System.Drawing.Size(954, 22); + this.statusStrip1.TabIndex = 7; + this.statusStrip1.Text = "statusStrip1"; + // + // sbPort + // + this.sbPort.Name = "sbPort"; + this.sbPort.Size = new System.Drawing.Size(121, 17); + this.sbPort.Text = "toolStripStatusLabel1"; + // + // timer1 + // + this.timer1.Tick += new System.EventHandler(this.timer1_Tick); + // + // cmbid + // + this.cmbid.Dock = System.Windows.Forms.DockStyle.Left; + this.cmbid.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cmbid.Font = new System.Drawing.Font("굴림", 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129))); + this.cmbid.FormattingEnabled = true; + this.cmbid.Location = new System.Drawing.Point(60, 5); + this.cmbid.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.cmbid.Name = "cmbid"; + this.cmbid.Size = new System.Drawing.Size(183, 40); + this.cmbid.TabIndex = 8; + // + // btsim + // + this.btsim.Dock = System.Windows.Forms.DockStyle.Right; + this.btsim.Font = new System.Drawing.Font("굴림", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(129))); + this.btsim.Location = new System.Drawing.Point(829, 5); + this.btsim.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.btsim.Name = "btsim"; + this.btsim.Size = new System.Drawing.Size(120, 42); + this.btsim.TabIndex = 9; + this.btsim.Text = "Test"; + this.btsim.UseVisualStyleBackColor = true; + this.btsim.Click += new System.EventHandler(this.btsim_Click); + // + // rtMsg + // + this.rtMsg.Dock = System.Windows.Forms.DockStyle.Bottom; + this.rtMsg.Location = new System.Drawing.Point(3, 331); + this.rtMsg.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.rtMsg.Name = "rtMsg"; + this.rtMsg.Size = new System.Drawing.Size(940, 118); + this.rtMsg.TabIndex = 10; + this.rtMsg.Text = ""; + // + // tbCmd + // + this.tbCmd.Dock = System.Windows.Forms.DockStyle.Left; + this.tbCmd.Font = new System.Drawing.Font("굴림", 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129))); + this.tbCmd.Location = new System.Drawing.Point(298, 5); + this.tbCmd.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.tbCmd.Name = "tbCmd"; + this.tbCmd.Size = new System.Drawing.Size(83, 44); + this.tbCmd.TabIndex = 11; + this.tbCmd.Text = "cmd"; + this.tbCmd.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 2; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel1.Controls.Add(this.rtRx, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.rtTx, 1, 0); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 3); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 1; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel1.Size = new System.Drawing.Size(940, 328); + this.tableLayoutPanel1.TabIndex = 12; + // + // panel1 + // + this.panel1.Controls.Add(this.tbmsg); + this.panel1.Controls.Add(this.label5); + this.panel1.Controls.Add(this.tbCmd); + this.panel1.Controls.Add(this.label4); + this.panel1.Controls.Add(this.cmbid); + this.panel1.Controls.Add(this.label3); + this.panel1.Controls.Add(this.btsend); + this.panel1.Controls.Add(this.btsim); + this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom; + this.panel1.Location = new System.Drawing.Point(0, 531); + this.panel1.Name = "panel1"; + this.panel1.Padding = new System.Windows.Forms.Padding(5); + this.panel1.Size = new System.Drawing.Size(954, 52); + this.panel1.TabIndex = 13; + // + // panel2 + // + this.panel2.Controls.Add(this.tbbaud); + this.panel2.Controls.Add(this.label2); + this.panel2.Controls.Add(this.cmbport); + this.panel2.Controls.Add(this.btconnect); + this.panel2.Controls.Add(this.label1); + this.panel2.Dock = System.Windows.Forms.DockStyle.Top; + this.panel2.Location = new System.Drawing.Point(0, 0); + this.panel2.Name = "panel2"; + this.panel2.Padding = new System.Windows.Forms.Padding(3); + this.panel2.Size = new System.Drawing.Size(954, 46); + this.panel2.TabIndex = 14; + // + // label1 + // + this.label1.Dock = System.Windows.Forms.DockStyle.Left; + this.label1.Location = new System.Drawing.Point(3, 3); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(55, 40); + this.label1.TabIndex = 7; + this.label1.Text = "port"; + this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // label2 + // + this.label2.Dock = System.Windows.Forms.DockStyle.Left; + this.label2.Location = new System.Drawing.Point(276, 3); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(55, 40); + this.label2.TabIndex = 8; + this.label2.Text = "baud"; + this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // label3 + // + this.label3.Dock = System.Windows.Forms.DockStyle.Left; + this.label3.Font = new System.Drawing.Font("Arial", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label3.Location = new System.Drawing.Point(5, 5); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(55, 42); + this.label3.TabIndex = 12; + this.label3.Text = "ID\r\n(1)"; + this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // label4 + // + this.label4.Dock = System.Windows.Forms.DockStyle.Left; + this.label4.Font = new System.Drawing.Font("Arial", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label4.Location = new System.Drawing.Point(243, 5); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(55, 42); + this.label4.TabIndex = 13; + this.label4.Text = "CMD\r\n(1)"; + this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // label5 + // + this.label5.Dock = System.Windows.Forms.DockStyle.Left; + this.label5.Font = new System.Drawing.Font("Arial", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label5.Location = new System.Drawing.Point(381, 5); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(55, 42); + this.label5.TabIndex = 14; + this.label5.Text = "DATA\r\n(n)"; + this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // tabControl1 + // + this.tabControl1.Controls.Add(this.tabPage1); + this.tabControl1.Controls.Add(this.tabPage2); + this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControl1.Location = new System.Drawing.Point(0, 46); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(954, 485); + this.tabControl1.TabIndex = 15; + // + // tabPage1 + // + this.tabPage1.Controls.Add(this.tableLayoutPanel1); + this.tabPage1.Controls.Add(this.rtMsg); + this.tabPage1.Location = new System.Drawing.Point(4, 29); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3); + this.tabPage1.Size = new System.Drawing.Size(946, 452); + this.tabPage1.TabIndex = 0; + this.tabPage1.Text = "Test"; + this.tabPage1.UseVisualStyleBackColor = true; + // + // tabPage2 + // + this.tabPage2.Controls.Add(this.btSave); + this.tabPage2.Controls.Add(this.btload); + this.tabPage2.Controls.Add(this.rtCmd); + this.tabPage2.Location = new System.Drawing.Point(4, 29); + this.tabPage2.Name = "tabPage2"; + this.tabPage2.Padding = new System.Windows.Forms.Padding(3); + this.tabPage2.Size = new System.Drawing.Size(946, 452); + this.tabPage2.TabIndex = 1; + this.tabPage2.Text = "Command"; + this.tabPage2.UseVisualStyleBackColor = true; + // + // rtCmd + // + this.rtCmd.Dock = System.Windows.Forms.DockStyle.Fill; + this.rtCmd.Location = new System.Drawing.Point(3, 3); + this.rtCmd.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.rtCmd.Name = "rtCmd"; + this.rtCmd.Size = new System.Drawing.Size(940, 446); + this.rtCmd.TabIndex = 11; + this.rtCmd.Text = ""; + // + // btload + // + this.btload.Location = new System.Drawing.Point(820, 15); + this.btload.Name = "btload"; + this.btload.Size = new System.Drawing.Size(113, 29); + this.btload.TabIndex = 12; + this.btload.Text = "Load"; + this.btload.UseVisualStyleBackColor = true; + this.btload.Click += new System.EventHandler(this.btload_Click); + // + // btSave + // + this.btSave.Location = new System.Drawing.Point(820, 50); + this.btSave.Name = "btSave"; + this.btSave.Size = new System.Drawing.Size(113, 29); + this.btSave.TabIndex = 13; + this.btSave.Text = "Save"; + this.btSave.UseVisualStyleBackColor = true; + this.btSave.Click += new System.EventHandler(this.btSave_Click); + // + // Form1 + // + this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 19F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(954, 605); + this.Controls.Add(this.tabControl1); + this.Controls.Add(this.panel2); + this.Controls.Add(this.panel1); + this.Controls.Add(this.statusStrip1); + this.Font = new System.Drawing.Font("굴림", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129))); + this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.Name = "Form1"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "!!"; + this.Load += new System.EventHandler(this.Form1_Load); + this.statusStrip1.ResumeLayout(false); + this.statusStrip1.PerformLayout(); + this.tableLayoutPanel1.ResumeLayout(false); + this.panel1.ResumeLayout(false); + this.panel1.PerformLayout(); + this.panel2.ResumeLayout(false); + this.tabControl1.ResumeLayout(false); + this.tabPage1.ResumeLayout(false); + this.tabPage2.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.RichTextBox rtRx; + private System.Windows.Forms.RichTextBox rtTx; + private System.Windows.Forms.TextBox tbmsg; + private System.Windows.Forms.Button btsend; + private System.Windows.Forms.ComboBox cmbport; + private System.Windows.Forms.Button btconnect; + private System.Windows.Forms.ComboBox tbbaud; + private System.Windows.Forms.StatusStrip statusStrip1; + private System.Windows.Forms.ToolStripStatusLabel sbPort; + private System.Windows.Forms.Timer timer1; + private System.Windows.Forms.ComboBox cmbid; + private System.Windows.Forms.Button btsim; + private System.Windows.Forms.RichTextBox rtMsg; + private System.Windows.Forms.TextBox tbCmd; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Panel panel2; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.TabPage tabPage2; + private System.Windows.Forms.RichTextBox rtCmd; + private System.Windows.Forms.Button btSave; + private System.Windows.Forms.Button btload; + } +} + diff --git a/sample/Form1.cs b/sample/Form1.cs new file mode 100644 index 0000000..e74cee2 --- /dev/null +++ b/sample/Form1.cs @@ -0,0 +1,216 @@ +using AR; +using ENIG; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace SampleProject +{ + enum messageType + { + rx, + tx, + normal, + error + } + public partial class Form1 : Form + { + + System.IO.Ports.SerialPort dev; + EEProtocol proto; + Dictionary idlist; + public Form1() + { + InitializeComponent(); + this.Text = $"Amkor ENIG Protocol Test (PanID:46A5, CH:17)"; + proto = new EEProtocol(); + proto.OnDataReceived += Proto_OnDataReceived; + proto.OnMessage += Proto_OnMessage; + dev = new System.IO.Ports.SerialPort(); + dev.ReadTimeout = 2000; + dev.WriteTimeout = 1000; + dev.DataReceived += (s1, e1) => + { + var buffer = new byte[dev.BytesToRead]; + dev.Read(buffer, 0, buffer.Length); + proto.ProcessReceivedData(buffer); + }; + + idlist = new Dictionary(); + idlist.Add("ACS", 0); + idlist.Add("AGV1", 10); + idlist.Add("AGV2", 11); + idlist.Add("BUFFER1", 20); + idlist.Add("BUFFER2", 21); + idlist.Add("BUFFER3", 22); + idlist.Add("BUFFER4", 23); + idlist.Add("BUFFER5", 24); + idlist.Add("DOOR", 30); + + this.cmbid.Items.Clear(); + foreach (var item in idlist) + cmbid.Items.Add($"{item.Key}"); + + tbCmd.Text = "FF"; + tbmsg.Text = string.Empty; + } + + private void Proto_OnDataReceived(object sender, EEProtocol.DataEventArgs e) + { + var hexstrRaw = e.ReceivedPacket.RawData.HexString(); + var hexstr = e.ReceivedPacket.Data.HexString(); + var cmd = e.ReceivedPacket.Command.ToString("X2"); + var id = e.ReceivedPacket.ID.ToString("X2"); + AddMessage($"{hexstrRaw}\nID:{id},CMD:{cmd},DATA:{hexstr}", messageType.rx); + } + private void Proto_OnMessage(object sender, EEProtocol.MessageEventArgs e) + { + AddMessage(e.Message); + } + + void AddMessage(string msg, messageType type = messageType.normal) + { + if(this.InvokeRequired) + { + this.BeginInvoke(new Action(() => AddMessage(msg, type))); + return; + } + + if (type == messageType.rx) + { + rtRx.AppendText($"<{DateTime.Now.ToString("HH:mm:ss")} RX> {msg}\r\n"); + rtRx.ScrollToCaret(); + } + else if (type == messageType.tx) + { + rtTx.AppendText($"<{DateTime.Now.ToString("HH:mm:ss")} TX> {msg}\r\n"); + rtTx.ScrollToCaret(); + } + else + { + rtMsg.AppendText($"<{DateTime.Now.ToString("HH:mm:ss")} > {msg}\r\n"); + rtMsg.ScrollToCaret(); + } + } + + private void Form1_Load(object sender, EventArgs e) + { + cmbport.Items.Clear(); + foreach (var item in System.IO.Ports.SerialPort.GetPortNames()) + { + cmbport.Items.Add(item); + } + cmbport.Text = "COM11"; + if (cmbport.Items.Count > 0) cmbport.SelectedIndex = 0; + if (cmbid.Items.Count > 0) cmbid.SelectedIndex = 0; + LoadCmds(); + this.timer1.Start(); + } + + private void btconnect_Click(object sender, EventArgs e) + { + var port = cmbport.Text.Trim(); + var buid = tbbaud.Text.toInt(); + if(dev.IsOpen) + { + dev.Close(); + AddMessage("port closed"); + } + else + { + try + { + this.dev.PortName = port; + this.dev.BaudRate = buid; + dev.Open(); + AddMessage("port opened"); + } + catch (Exception ex) + { + AddMessage(ex.Message, messageType.error); + } + } + + + } + + private void timer1_Tick(object sender, EventArgs e) + { + sbPort.Text = $"{dev.PortName}:{dev.BaudRate} {(dev.IsOpen ? "Open" : "Closed")}"; + } + + private void tbmsg_TextChanged(object sender, EventArgs e) + { + + } + + private void btsend_Click(object sender, EventArgs e) + { + //send to device + var msg = tbmsg.Text.Trim(); + var id = this.idlist[cmbid.Text]; + var cmdHex = this.tbCmd.Text.Trim(); + byte cmd = Convert.ToByte(cmdHex, 16); + byte[] msgBytes = Encoding.ASCII.GetBytes(msg); // 메시지를 byte 배열로 변환 + + var data = proto.CreatePacket(id, cmd, msgBytes); + SendToDevice(data); + } + + void SendToDevice(byte[] packet) + { + if (dev.IsOpen == false) + { + AddMessage("port closed", messageType.error); + } + else + { + dev.Write(packet, 0, packet.Length); + var hexstring = packet.HexString(); + AddMessage(hexstring, messageType.tx); + } + + } + + private void btsim_Click(object sender, EventArgs e) + { + //packet test + var msg = tbmsg.Text.Trim(); + var id = this.idlist[cmbid.Text]; + var cmdHex = this.tbCmd.Text.Trim(); + byte cmd = Convert.ToByte(cmdHex, 16); // 16진수 문자열을 byte로 변환 + byte[] msgBytes = Encoding.ASCII.GetBytes(msg); // 메시지를 byte 배열로 변환 + + var data = proto.CreatePacket(id, cmd, msgBytes); + this.proto.PacketTest(data); + } + string fn = "cmds.rtf"; + private void btSave_Click(object sender, EventArgs e) + { + System.IO.File.WriteAllText("cmds.rtf", rtCmd.Rtf, System.Text.Encoding.Default); + } + + private void btload_Click(object sender, EventArgs e) + { + LoadCmds(); + } + + void LoadCmds() + { + var fi = new System.IO.FileInfo("cmds.rtf"); + if (fi.Exists == false) + { + AddMessage("no cmds file", messageType.error); + return; + } + var data = System.IO.File.ReadAllText("cmds.rtf", System.Text.Encoding.Default); + rtCmd.Rtf = data; + } + } +} diff --git a/sample/Form1.resx b/sample/Form1.resx new file mode 100644 index 0000000..21e3296 --- /dev/null +++ b/sample/Form1.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 134, 17 + + \ No newline at end of file diff --git a/sample/Program.cs b/sample/Program.cs new file mode 100644 index 0000000..b43a18e --- /dev/null +++ b/sample/Program.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace SampleProject +{ + internal static class Program + { + /// + /// 해당 애플리케이션의 주 진입점입니다. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new Form1()); + } + } +} diff --git a/sample/Properties/AssemblyInfo.cs b/sample/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..1394d9c --- /dev/null +++ b/sample/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 어셈블리에 대한 일반 정보는 다음 특성 집합을 통해 +// 제어됩니다. 어셈블리와 관련된 정보를 수정하려면 +// 이러한 특성 값을 변경하세요. +[assembly: AssemblyTitle("SampleProject")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("ATK")] +[assembly: AssemblyProduct("SampleProject")] +[assembly: AssemblyCopyright("Copyright © ATK 2025")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에 +// 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면 +// 해당 형식에 대해 ComVisible 특성을 true로 설정하세요. +[assembly: ComVisible(false)] + +// 이 프로젝트가 COM에 노출되는 경우 다음 GUID는 typelib의 ID를 나타냅니다. +[assembly: Guid("fab31c8a-7dcf-4152-8a82-76f3c10baba4")] + +// 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다. +// +// 주 버전 +// 부 버전 +// 빌드 번호 +// 수정 버전 +// +// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를 +// 기본값으로 할 수 있습니다. +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/sample/Properties/Resources.Designer.cs b/sample/Properties/Resources.Designer.cs new file mode 100644 index 0000000..86d726d --- /dev/null +++ b/sample/Properties/Resources.Designer.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------ +// +// 이 코드는 도구를 사용하여 생성되었습니다. +// 런타임 버전:4.0.30319.42000 +// +// 파일 내용을 변경하면 잘못된 동작이 발생할 수 있으며, 코드를 다시 생성하면 +// 이러한 변경 내용이 손실됩니다. +// +//------------------------------------------------------------------------------ + +namespace SampleProject.Properties +{ + + + /// + /// 지역화된 문자열 등을 찾기 위한 강력한 형식의 리소스 클래스입니다. + /// + // 이 클래스는 ResGen 또는 Visual Studio와 같은 도구를 통해 StronglyTypedResourceBuilder + // 클래스에서 자동으로 생성되었습니다. + // 멤버를 추가하거나 제거하려면 .ResX 파일을 편집한 다음 /str 옵션을 사용하여 + // ResGen을 다시 실행하거나 VS 프로젝트를 다시 빌드하십시오. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources + { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() + { + } + + /// + /// 이 클래스에서 사용하는 캐시된 ResourceManager 인스턴스를 반환합니다. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if ((resourceMan == null)) + { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SampleProject.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 이 강력한 형식의 리소스 클래스를 사용하여 모든 리소스 조회에 대해 현재 스레드의 CurrentUICulture 속성을 + /// 재정의합니다. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture + { + get + { + return resourceCulture; + } + set + { + resourceCulture = value; + } + } + } +} diff --git a/sample/Properties/Resources.resx b/sample/Properties/Resources.resx new file mode 100644 index 0000000..ffecec8 --- /dev/null +++ b/sample/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/sample/Properties/Settings.Designer.cs b/sample/Properties/Settings.Designer.cs new file mode 100644 index 0000000..6f4bb07 --- /dev/null +++ b/sample/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SampleProject.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/sample/Properties/Settings.settings b/sample/Properties/Settings.settings new file mode 100644 index 0000000..abf36c5 --- /dev/null +++ b/sample/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/sample/SampleProject.csproj b/sample/SampleProject.csproj new file mode 100644 index 0000000..ada82a2 --- /dev/null +++ b/sample/SampleProject.csproj @@ -0,0 +1,92 @@ + + + + + Debug + AnyCPU + {FAB31C8A-7DCF-4152-8A82-76F3C10BABA4} + WinExe + SampleProject + SampleProject + v4.8 + 512 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + .\arCommUtil.dll + + + + + + + + + + + + + + + + Form + + + Form1.cs + + + + + Form1.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + {b6fca1b0-c9d1-4159-ab86-25e4bc598c01} + ENIGProtocol + + + + \ No newline at end of file diff --git a/sample/arCommUtil.dll b/sample/arCommUtil.dll new file mode 100644 index 0000000000000000000000000000000000000000..3c26818abd32f912d41820a60b4e8e48b40ae9d4 GIT binary patch literal 192512 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�YE2va*uvRl>DAz_pxlokCel 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