성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] How can I tell whether two programs...
[정성태] The case of the fail-fast crashes c...
[정성태] Creating Docker multi-arch images f...
[정성태] BinaryFormatter removed from .NET 9...
[정성태] Extending the Windows Shell Progres...
[우광현] 와..... 범위를 잡았으니 클라이언트가 해당 범위를 확인해본다...
[정성태] 딱히, 그것 이상으로 더 설명할 내용이 없습니다. 동적 포...
[정성태] If Windows 3.11 required a 32-bit p...
[정성태] What is a hard error, and what make...
[괴물신인] 질문작성자인데 이 글을 이제봤네요 ㄷㄷ 이 글처럼 타입별로 인...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>C# - Arduino IDE의 Serial Monitor 기능 구현</h1> <p> Arduino IDE의 "Tools" / "<a target='tab' href='https://www.sysnet.pe.kr/2/0/11595#serial_monitor'>Serial Monitor (Ctrl+Shift+M)</a>" 메뉴를 선택하면 Serial Monitor 화면이 열리면서, Sketch 프로그램에서 Serial.print...로 출력하는 내용을 확인할 수 있습니다.<br /> <br /> 해당 기능을 C#으로 한 번 구현해 볼까요? ^^ 사실, 단순한 직렬 포트 통신에 불과하기 때문에 이에 관한 예제 코드는 지난 글에서 사용한 것을 재사용하는 것도 가능합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > PC에 연결해 동작하는 자신만의 USB 장치 만들어 보기 ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/11606'>https://www.sysnet.pe.kr/2/0/11606</a> </pre> <br /> 일례로, ESP8266 장치를 USB 케이블로 PC에 연결하면 (전원도 공급하면서) 다음과 같이 장치 관리자에서 COM 포트 및 UART 통신 파라미터를 확인할 수 있습니다.<br /> <br /> <img onclick='toggle_img(this)' class='imgView' alt='esp8266_uart_comm_with_cs_1.png' src='/SysWebRes/bbs/esp8266_uart_comm_with_cs_1.png' /><br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Port: COM4 Bits per seconds: 9600 Data bits: 8 Parity: None Stop bits: 1 Flow control: None </pre> <br /> 그리고, 이 정도의 정보만으로도 이제 Arduino IDE의 "Serial Monitor"를 C#으로 다음과 같이 간단하게 구현할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using System; using System.IO.Ports; using System.Text; class Program { static void Main(string[] args) { foreach (string portName in SerialPort.GetPortNames()) { Console.WriteLine(portName); } <span style='color: blue; font-weight: bold'>SerialPort comPort = OpenCOM(4, 115200);</span> Console.WriteLine(comPort.IsOpen); // True comPort.DataReceived += ComPort_DataReceived; Console.WriteLine("Press any key to exit..."); Console.ReadLine(); comPort.Close(); Console.WriteLine(comPort.IsOpen); // False } private static void ComPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { SerialPort comPort = sender as SerialPort; switch (e.EventType) { case SerialData.Chars: PrintInputBuffers(comPort); break; case SerialData.Eof: break; } } private static void PrintInputBuffers(SerialPort comPort) { int len = comPort.BytesToRead; byte[] buf = new byte[len]; comPort.Read(buf, 0, len); Console.Write(Encoding.UTF8.GetString(buf)); } private static SerialPort OpenCOM(int portNumber, int bps) { SerialPort comPort = new SerialPort(); // 장치 관리자의 Port Settings에 따라, comPort.PortName = $"COM{portNumber}"; comPort.BaudRate = bps; comPort.DataBits = 8; comPort.StopBits = StopBits.One; comPort.Handshake = Handshake.None; comPort.Parity = Parity.None; comPort.Open(); return comPort; } } </pre> <br /> 그런데, OpenCOM의 인자에 9600이 아닌 115200을 주고 있는데요, 그 이유는 해당 기기에서 동작하는 sketch 프로그램의 setup에서 그 속도를 변경한 경우에는 그에 맞춰져야 하기 때문입니다. 즉, 현재 기기는 다음과 같이 초기화를 시켰기 때문에,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > void setup() { Serial.begin(115200); } </pre> <br /> 그에 접속하는 직렬 통신 클라이언트 프로그램도 115200을 사용한 것입니다.<br /> <br /> 이렇게 해서 프로그램을 실행하면, Sketch 프로그램에서 Serial.print...로 출력하는 내용이 C# 콘솔 프로그램 화면에 나옵니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 출력 내용만 보면 재미없으니 ^^ 입력도 수행해 보겠습니다. 실제로 Arduino IDE의 Serial Monitor 창에는 상단에 텍스트 입력 상자가 있어 전송하는 기능도 제공합니다.<br /> <br /> 이를 테스트하기 위해 다음과 같이 간단한 Sketch 프로그램을 기기에 업로드하고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > void setup() { Serial.begin(115200); } int _loopCount; void loop() { _loopCount ++; if (Serial.available()) { String cmd = Serial.readStringUntil('\n'); <span style='color: blue; font-weight: bold'>if (cmd == "get_count")</span> { Serial.write(_loopCount); Serial.flush(); } <span style='color: blue; font-weight: bold'>else if (cmd == "reset")</span> { _loopCount = 0; Serial.write(_loopCount); Serial.flush(); } } delay(1000); } </pre> <br /> C# 프로그램은 다음과 같이 입력을 받아 전송하는 부분을 넣어주면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using System; using System.IO.Ports; using System.Text; class Program { static EventWaitHandle _cmdExecuted = new EventWaitHandle(false, EventResetMode.AutoReset); static void Main(string[] args) { SerialPort comPort = OpenCOM(4, 115200); Console.WriteLine(comPort.IsOpen); // True comPort.DataReceived += ComPort_DataReceived; while (true) { <span style='color: blue; font-weight: bold'>Console.Write("serial> "); string cmd = Console.ReadLine(); if (cmd == "quit" || cmd == "q") { break; } comPort.Write(cmd);</span> <span style='color: blue; font-weight: bold'>_cmdExecuted.WaitOne(1000 * 5);</span> } comPort.Close(); Console.WriteLine(comPort.IsOpen); // False } private static void ComPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { SerialPort comPort = sender as SerialPort; switch (e.EventType) { case SerialData.Chars: PrintInputBuffers(comPort); <span style='color: blue; font-weight: bold'>_cmdExecuted.Set();</span> break; case SerialData.Eof: break; } } // ...[생략]... } </pre> <br /> 다음과 같은 식으로 get_count, reset 명령어를 기기에 전송해 상호 작용할 수 있게 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > serial> get_count _loopCount: 95 serial> reset _loopCount: 0 serial> get_count _loopCount: 5 </pre> <br /> (첨부 파일은 이 글의 예제 코드를 포함합니다.)<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
6372
(왼쪽의 숫자를 입력해야 합니다.)