diff --git a/PLibs/PLibs.sln b/PLibs/PLibs.sln index bece1c0..915a15f 100644 --- a/PLibs/PLibs.sln +++ b/PLibs/PLibs.sln @@ -13,6 +13,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeadTailSocketFW", "HeadTai EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApp1", "ConsoleApp1\ConsoleApp1.csproj", "{634E2E96-AFDD-4C4B-8C1B-E068889DA360}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SerialASCIISample", "SerialASCIISample\SerialASCIISample.csproj", "{CFCD4DBF-3AA2-49CB-AEA4-60DDDC0A0A87}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -39,6 +41,10 @@ Global {634E2E96-AFDD-4C4B-8C1B-E068889DA360}.Debug|Any CPU.Build.0 = Debug|Any CPU {634E2E96-AFDD-4C4B-8C1B-E068889DA360}.Release|Any CPU.ActiveCfg = Release|Any CPU {634E2E96-AFDD-4C4B-8C1B-E068889DA360}.Release|Any CPU.Build.0 = Release|Any CPU + {CFCD4DBF-3AA2-49CB-AEA4-60DDDC0A0A87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CFCD4DBF-3AA2-49CB-AEA4-60DDDC0A0A87}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CFCD4DBF-3AA2-49CB-AEA4-60DDDC0A0A87}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CFCD4DBF-3AA2-49CB-AEA4-60DDDC0A0A87}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/PLibs/SerialASCIISample/Program.cs b/PLibs/SerialASCIISample/Program.cs new file mode 100644 index 0000000..3856a10 --- /dev/null +++ b/PLibs/SerialASCIISample/Program.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; + +namespace SerialASCIISample +{ + internal class Program + { + static void Main(string[] args) + { + Console.Write("COM Port: "); + string port = Console.ReadLine(); + + SerailComm serailComm = new SerailComm(port, 9600, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One); + serailComm.MessageReceived += SerailComm_MessageReceived; + serailComm.Open(); + + bool needExit = false; + while (!needExit) + { + Thread.Sleep(1000); + + if (!serailComm.IsOpen) + serailComm.Open(); + } + } + + private static void SerailComm_MessageReceived(object sender, EventMessageArgs e) + { + Console.WriteLine($"[{DateTime.Now.ToShortTimeString()}] {e.Message}"); + } + } +} diff --git a/PLibs/SerialASCIISample/Properties/AssemblyInfo.cs b/PLibs/SerialASCIISample/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..c58fc65 --- /dev/null +++ b/PLibs/SerialASCIISample/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 어셈블리에 대한 일반 정보는 다음 특성 집합을 통해 +// 제어됩니다. 어셈블리와 관련된 정보를 수정하려면 +// 이러한 특성 값을 변경하세요. +[assembly: AssemblyTitle("SerialASCIISample")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SerialASCIISample")] +[assembly: AssemblyCopyright("Copyright © 2024")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에 +// 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면 +// 해당 형식에 대해 ComVisible 특성을 true로 설정하세요. +[assembly: ComVisible(false)] + +// 이 프로젝트가 COM에 노출되는 경우 다음 GUID는 typelib의 ID를 나타냅니다. +[assembly: Guid("cfcd4dbf-3aa2-49cb-aea4-60dddc0a0a87")] + +// 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다. +// +// 주 버전 +// 부 버전 +// 빌드 번호 +// 수정 버전 +// +// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를 +// 기본값으로 할 수 있습니다. +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/PLibs/SerialASCIISample/SerailComm.cs b/PLibs/SerialASCIISample/SerailComm.cs new file mode 100644 index 0000000..5b27847 --- /dev/null +++ b/PLibs/SerialASCIISample/SerailComm.cs @@ -0,0 +1,179 @@ +using System; +using System.Collections.Generic; +using System.IO.Ports; +using System.Text; + +namespace SerialASCIISample +{ + public class SerailComm + { + private StringBuilder _buffer; + private SerialPort _serial; + + private readonly char CR = (char)0x0D; + private readonly char LF = (char)0x0A; + + public bool IsOpen { get { return _serial.IsOpen; } } + + public event EventHandler MessageReceived; + + public SerailComm(string port, int baudRate, Parity parity, int dataBits, StopBits stopBits) : base() + { + _buffer = new StringBuilder(); + + _serial = new SerialPort(port, baudRate, parity, dataBits, stopBits); + _serial.DataReceived -= DataReceived; + _serial.DataReceived += DataReceived; + } + + public bool Open() + { + try + { + _serial.Open(); + return true; + } + catch (Exception ex) + { + if (MessageReceived != null) + MessageReceived(this, new EventMessageArgs(ex.Message)); + + return false; + } + } + + public bool Close() + { + try + { + _serial.Close(); + return true; + } + catch (Exception ex) + { + if (MessageReceived != null) + MessageReceived(this, new EventMessageArgs(ex.Message)); + + return false; + } + } + + private void DataReceived(object sender, SerialDataReceivedEventArgs e) + { + SerialPort serial = sender as SerialPort; + if (serial == null) + return; + + try + { + string received = serial.ReadExisting(); + received = received.Replace(LF.ToString(), ""); + //if (MessageReceived != null) + // MessageReceived(this, new EventMessageArgs(received)); + + _buffer.Append(received); + + string bufferContent = _buffer.ToString(); + int commandEndIndex = -1; + while ((commandEndIndex = bufferContent.IndexOf(CR)) >= 0) + { + string completeCommand = bufferContent.Substring(0, commandEndIndex).Trim(); + _buffer.Remove(0, commandEndIndex + 1); + if (string.IsNullOrEmpty(completeCommand)) + continue; + + HandleCommand(serial, completeCommand); + + bufferContent = _buffer.ToString(); + commandEndIndex = -1; + } + } + catch (Exception ex) + { + if (MessageReceived != null) + MessageReceived(this, new EventMessageArgs(ex.Message)); + + SendSerialMessage(serial, "ERR3"); + } + } + + private void HandleCommand(SerialPort serial, string command) + { + command = command.ToUpper(); + // Read Data + if (command.StartsWith("RD")) + { + string message = "1234.4,234.3,34.2,4.1,1.33,29.5"; + SendSerialMessage(serial, message); + } + // Read Status + else if (command.StartsWith("ST")) + { + string message = "0,0,0,0,1,1"; + SendSerialMessage(serial, message); + } + // Write Data + else if (command.StartsWith("WR")) + { + string req = command.Substring(2, command.Length - 2); + string[] parameters = req.Split('='); + if (parameters.Length != 2) + { + SendSerialMessage(serial, "ERR2"); + return; + } + + switch (parameters[0]) + { + case "LA": + case "SH": + case "EF": + case "CV": + case "SP": + case "TP": + case "LK": + WriteData(serial, parameters[0], parameters[1]); + break; + default: + SendSerialMessage(serial, "ERR2"); + break; + } + } + // Unknown Command + else + { + SendSerialMessage(serial, "ERR1"); + } + } + + private void WriteData(SerialPort serial, string addr, string value) + { + float casted = 0f; + if (!float.TryParse(value, out casted)) + { + SendSerialMessage(serial, "ERR2"); + return; + } + + if (MessageReceived != null) + MessageReceived(this, new EventMessageArgs($"{addr}: {casted.ToString("N2")}")); + + SendSerialMessage(serial, "OK"); + } + + private void SendSerialMessage(SerialPort serial, string message) + { + serial.Write(message + CR + LF); + } + } + + public class EventMessageArgs : EventArgs + { + public string Message; + + public EventMessageArgs(string message) + { + Message = message; + } + } +} diff --git a/PLibs/SerialASCIISample/SerialASCIISample.csproj b/PLibs/SerialASCIISample/SerialASCIISample.csproj new file mode 100644 index 0000000..dd71c3d --- /dev/null +++ b/PLibs/SerialASCIISample/SerialASCIISample.csproj @@ -0,0 +1,45 @@ + + + + + Debug + AnyCPU + {CFCD4DBF-3AA2-49CB-AEA4-60DDDC0A0A87} + Exe + SerialASCIISample + SerialASCIISample + v2.0 + 512 + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + \ No newline at end of file