반응형
예제로 배우는 C# 프로그래밍
C# 엑셀 프로그래밍
C# Access DB 사용
C# MySQL DB 사용
C# Oracle 사용
C# MongoDB 활용 예제
C# SQLite 사용
C# SQL MARS 활용
C# SQL SP 에러 처리
C# SMTP 메일 발송
단일 프로세스 실행
.NET Serialization
.NET Reflection 1
.NET Reflection 2
C# 동적 컴파일
병렬처리 데드락 실험
.NET 구성 파일 사용
C#에서 IE 컨트롤하기
Regex 기초
Regex 활용
이메일 주소 체크
C# 위치 데이타 처리
C# YouTube API
시리얼포트 기초
시리얼포트 비동기
C# 로깅 : Trace
C# 로깅 : log4net
C#에서 PDF 사용
C# 서비스 프로그램
C# P/Invoke 사용
C# Impersonation
https://www.csharpstudy.com/Practical/Prac-serialport.aspx
시리얼 포트 기초
시리얼 포트 (Serial Port, 직렬 포트)는 한 번에 하나의 비트 단위로 정보를 주고 받을 수 있는 직렬 통신의 물리적 인터페이스로서 다양한 주변 기기와의 통신에 사용한다. 시리얼 포트는 일반적으로 RS-232 표준을 따르는 하드웨어로서 모뎀이나 직렬 마우스, 바코드 리더, 디지탈 측정 장비 등 다양한 주변 기기를 시리얼 포트에 연결하여 사용할 수 있다.
.NET 에서 시리얼포트를 사용하기 위해서는 System.IO.Ports 네임스페이스 안의 SerialPort 클래스를 이용하면 된다. SerialPort 클래스를 사용하는 절차는 크게 다음과 같이 5단계로 나눌 수 있다.
(주: 아래의 1~2단계는 SerialPort 객체를 생성하면서 동시에 포트 셋팅을 지정할 수도 있기 때문에 하나로 볼 수도 있다.)
1) SerialPort 클래스 객체 생성
2) (Optional) SerialPort 포트 셋팅
3) 시리얼포트 오픈
4) 시리얼포트에서 데이타 읽거나 쓰기
5) 시리얼포트 닫기
아래 예제처럼 SerialPort 객체를 아무 파라미터 없이 생성하면 디폴트 COM 포트 셋팅을 사용한다. (디폴트 포트 셋팅은 COM1 포트, 9600 BaudRate, 8 DataBits, None Parity, 1 StopBits 를 사용한다)
.NET 에서 시리얼포트를 사용하기 위해서는 System.IO.Ports 네임스페이스 안의 SerialPort 클래스를 이용하면 된다. SerialPort 클래스를 사용하는 절차는 크게 다음과 같이 5단계로 나눌 수 있다.
(주: 아래의 1~2단계는 SerialPort 객체를 생성하면서 동시에 포트 셋팅을 지정할 수도 있기 때문에 하나로 볼 수도 있다.)
1) SerialPort 클래스 객체 생성
2) (Optional) SerialPort 포트 셋팅
3) 시리얼포트 오픈
4) 시리얼포트에서 데이타 읽거나 쓰기
5) 시리얼포트 닫기
아래 예제처럼 SerialPort 객체를 아무 파라미터 없이 생성하면 디폴트 COM 포트 셋팅을 사용한다. (디폴트 포트 셋팅은 COM1 포트, 9600 BaudRate, 8 DataBits, None Parity, 1 StopBits 를 사용한다)
예제
// 1. SerialPort 클래스 객체 생성 (디폴트로 포트 셋팅 사용)
SerialPort sp = new SerialPort();
// 2. 시리얼포트 오픈
sp.Open();
// 3. 시리얼포트에서 한 라인 읽기
string data = sp.ReadLine();
// 4. 시리얼포트 닫기
sp.Close();
시리얼 포트에서 데이타 읽기
시리얼 포트에서 데이타를 읽어오는 코드는 위의 기본 절차들을 따르면 된다. 일반적으로 실무에서 시리얼포트 통신을 위해서는 비동기 방식을 사용하지만, 여기서는 가장 간단한 예제를 들기 위해 시리얼 포트를 열고 동기적으로 데이타를 읽어 오는 코드를 살펴본다. 아래 예제는 COM5 포트를 열고, 한 라인의 데이타를 읽어 오는 코드이다. 이어 코드는 시리얼포트에서 읽은 한 라인을 출력하고 COM5 포트를 닫게 된다.
시리얼포트에서 데이타를 읽는 메서드는 여러 가지가 있다. 즉, 한 바이트만 읽어오는 ReadByte(), 한 글자를 읽어오는 ReadChar(), 여러 바이트들을 읽어오는 Read(), 한 라인을 읽어오는 ReadLine() 등이 있다.
시리얼포트에서 데이타를 읽는 메서드는 여러 가지가 있다. 즉, 한 바이트만 읽어오는 ReadByte(), 한 글자를 읽어오는 ReadChar(), 여러 바이트들을 읽어오는 Read(), 한 라인을 읽어오는 ReadLine() 등이 있다.
예제
using System;
using System.IO.Ports;
namespace SerialApp
{
class Program
{
static void Main(string[] args)
{
// 1. SerialPort 클래스 객체 생성 (COM5 포트를 사용)
SerialPort sp = new SerialPort("COM5");
// 2. 시리얼포트 오픈
sp.Open();
// 3. 시리얼포트에서 한 라인 읽기
string data = sp.ReadLine();
Console.WriteLine(data);
// 4. 시리얼포트 닫기
sp.Close();
Console.WriteLine("Press Enter to Quit");
Console.ReadLine();
}
}
}
시리얼 포트에 데이타 쓰기
시리얼 포트에 데이타를 쓰는 코드는 위의 데이타를 읽는 코드와 거의 유사한데, 차이점은 읽기 메서드 대신 쓰기 메서드를 사용한다는 점이다. 여기서는 가장 간단한 예제로 시리얼 포트를 열고 동기적으로 데이타를 쓰는 코드를 살펴본다. 아래 예제는 COM6 포트를 열고, 한 라인의 데이타를 쓰고 COM 포트를 닫는 코드이다.
시리얼포트에서 데이타를 쓰는 메서드는 문자열을 Newline 없이 쓰는 Write() 메서드와 한 라인을 쓰는 WriteLine() 등이 있다.
시리얼포트에서 데이타를 쓰는 메서드는 문자열을 Newline 없이 쓰는 Write() 메서드와 한 라인을 쓰는 WriteLine() 등이 있다.
예제
using System.IO.Ports;
namespace SerialWrt
{
class Program
{
static void Main(string[] args)
{
// 1. SerialPort 클래스 객체 생성 (COM6 포트를 사용)
SerialPort sp = new SerialPort("COM6");
// 2. 시리얼포트 오픈
sp.Open();
// 3. 시리얼포트에서 한 라인 쓰기
sp.WriteLine("Hello World");
// 4. 시리얼포트 닫기
sp.Close();
}
}
}
시리얼 포트 셋팅 옵션
SerialPort 객체를 생성할 때, 혹은 객체를 생성하고 포트를 오픈하기 전에 해당 포트에 대한 셋팅을 설정할 수 있다. 자주 사용하는 포트 셋팅 옵션으로는 포트명(PortName), BaudRate, 데이타비트(DataBits), 패러티(Parity), 스톱비트(StopBits) 등이 있는데, BaudRate,DateBits,Parity,StopBits 등의 셋팅들은 시리얼 통신을 하는 양쪽 포트에서 동일하게 설정해야 한다.
아래 예제는 SerialPort 객체를 생성한 후, 여러 포트 셋팅 옵션들을 지정하는 예이다. 많은 경우 디폴트 포트 셋팅 옵션을 많이 사용하므로 이러한 옵션들은 필요할 때만 설정하면 된다.
아래 예제는 SerialPort 객체를 생성한 후, 여러 포트 셋팅 옵션들을 지정하는 예이다. 많은 경우 디폴트 포트 셋팅 옵션을 많이 사용하므로 이러한 옵션들은 필요할 때만 설정하면 된다.
예제
// 1. SerialPort 클래스 객체 생성
SerialPort sp = new SerialPort();
// 2. SerialPort 포트 셋팅 설정
sp.PortName = "COM6";
sp.BaudRate = 9600;
sp.DataBits = 8;
sp.Parity = Parity.None;
sp.StopBits = StopBits.One;
// 3. 시리얼포트 오픈
sp.Open();
시리얼포트 비동기 처리
시리얼포트 통신을 통해 데이타를 처리하기 위해서는 동기적인 방식보다 비동기적인 방식이 효율적인 경우가 대부분이다. 즉 시리얼포트 읽기나 쓰기를 별도의 작업쓰레드에서 실행하게 하여 메인쓰레드가 주변기기 통신에 묶여 있지 않게 하는 것이다.
시리얼포트에서 비동기적으로 데이타를 읽기 위해서 간단하게 사용하는 방법의 하나로 DataReceived 이벤트 핸들러를 사용하는 방법이 있다. 즉, 데이타가 시리얼포트에 도착했을 때, DataReceived 이벤트핸들러에 지정된 코드가 실행되게 된다. 아래 예제는 DataReceived 이벤트핸들러를 사용하여 COM5 포트로부터 데이타가 도착하면 이를 콘솔에 출력해 주는 간단한 샘플이다.
시리얼포트에서 비동기적으로 데이타를 읽기 위해서 간단하게 사용하는 방법의 하나로 DataReceived 이벤트 핸들러를 사용하는 방법이 있다. 즉, 데이타가 시리얼포트에 도착했을 때, DataReceived 이벤트핸들러에 지정된 코드가 실행되게 된다. 아래 예제는 DataReceived 이벤트핸들러를 사용하여 COM5 포트로부터 데이타가 도착하면 이를 콘솔에 출력해 주는 간단한 샘플이다.
예제
using System;
using System.IO.Ports;
namespace SerialDataRec
{
class Program
{
static void Main(string[] args)
{
// COM5 포트 사용
SerialPort sp = new SerialPort("COM5");
// DataReceived 이벤트 핸들러 지정
// 시리얼포트에 데이타가 도착하면 실행
sp.DataReceived += (sender, e) =>
{
SerialPort port = (SerialPort)sender;
// 현재까지 도착한 데이타 모두 읽기
string data = port.ReadExisting();
Console.WriteLine(data);
};
// 시리얼 포트 열기
sp.Open();
// Enter 누를 때까지 프로그램 계속 실행
Console.WriteLine("Press Enter to quit");
Console.ReadLine();
// 시리얼 포트 닫기
sp.Close();
}
}
}
시리얼포트 작업쓰레드 활용
시리얼포트 통신에서 이벤트 핸들러를 사용하지 않고 직접 작업쓰레드를 생성해서 처리할 수도 있다. 아래 예제는 간단한 콘솔 채팅 프로그램으로 한편으로 시리얼포트 읽기를 위한 작업쓰레드를 생성하여 계속 루프를 돌며 읽기 작업을 처리하고, 다른 한편으로 메인쓰레드에서 시리얼포트에 데이타를 쓰는 작업을 할 수 있게 한 것이다. (주: 이 예제는 MSDN에서 제공하는 코드를 간결하게 Refactoring 함과 동시에 약간의 버그를 수정한 것이다)
예제
using System;
using System.IO.Ports;
using System.Threading;
using System.Threading.Tasks;
namespace SerialChat
{
class Program
{
static void Main(string[] args)
{
if (args.Length < 1)
{
Console.WriteLine("Usage: SerialChat {portName}");
Console.WriteLine(" Ex: C> SerialChat COM3");
return;
}
string portName = args[0];
// 시리얼포트 열기
SerialPort sp = new SerialPort(portName);
sp.Open();
// 읽기 작업쓰레드: Read from serial port
var cancel = new CancellationTokenSource();
var readTask = Task.Factory.StartNew(() =>
{
while (!cancel.IsCancellationRequested)
{
string readMsg = sp.ReadLine();
if (readMsg.ToLower() == "quit")
{
Environment.Exit(0);
}
Console.WriteLine(readMsg);
}
}, cancel.Token);
// 메인쓰레드: Write to serial port
while (true)
{
string sendMsg = Console.ReadLine();
if (sendMsg.ToLower() == "quit")
{
sp.WriteLine(sendMsg);
cancel.Cancel();
break;
}
sp.WriteLine(sendMsg);
}
// 시리얼포트 닫기
sp.Close();
}
}
}
반응형
댓글