프로그래밍/C#

[C#] 시리얼통신(RS232) 방법

ss-pro 2020. 9. 17. 22:48
반응형

C#으로 시리얼통신하는 방법에 대해 알아보겠습니다. SerialPort 클래스를 이용해서 시리얼 포트 통신하는법을 살펴보겠습니다.  SerialPort클래스를 사용하기 위해선는 System.IO.Ports 네임스페이스를 추가해야합니다. 
시리얼통신의 경우도 IO통신이기때문에 아래수순으로 이루어집니다.  파일,네트워크 IO통신의경우도 아래순서와 거의 흡사하게 처리되니 해당수순을 기억해두면 좋을것 같습니다. 

1. 통신정보설정
- 시리얼통신시 필요한 포트번호, 보드레이트,패리티비트,데이터비트,StopBit정보를 설정합니다. ex)9600,N,8,1
public SerialPort(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits);

2. 포트오픈 
- public void Open();

3. 데이터수신 
- public int Read(byte[] buffer, int offset, int count);
- public string ReadLine();
- 수신부의 경우는 스레드를 사용하여 데이터를 수신받도록 하겠습니다. 

4. 데이터송신 
- public void Write(byte[] buffer, int offset, int count);
- public void WriteLine(string text);
라인단위로 데이터를 수신받을때 사용하는 함수입니다. 

5. 포트닫기 
- public void Close();//전체소소코드


전체소스코드
System.IO.Ports.SerialPort.GetPortNames() : 시스템상의 시리얼포트정보를 가져옵니다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
//시리얼통신관련 네임스페이스 
using System.IO.Ports;
 
//스레드네임스페이스
using System.Threading;
 
namespace SerialPortApp
{
    class Program
    {
        static SerialPort _serialPort;
        static bool _continue = true;
 
        static void Main(string[] args)
        {
            string[] portNames = GetPortNames();
            StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
            string message;
            int portId;
 
            int baudRate;
            Parity parity;
            int dataBits;
            StopBits stopBits;
 
            _serialPort = new SerialPort();
 
            //1.통신정보설정  
            Console.WriteLine("포트를 선택해주세요.");
            for (int i = 0; i < portNames.Length  ; i++)
            {
                Console.Write("{0}:{1} ", i + 1, portNames[i]);
            }
            Console.WriteLine();
 
            message = Console.ReadLine();
            portId =Int32.Parse(message);
 
            // Set the read/write timeouts
            _serialPort.ReadTimeout = 500;
            _serialPort.WriteTimeout = 500;
            PortSettings(portNames[portId-1], 9600, Parity.None, 8, StopBits.One);
 
            //2.포트오픈
            _serialPort.Open();
            Console.WriteLine("PORT OPEN:{0}", _serialPort.PortName);
 
            //3.데이터수신
            //  수신대기스레드생성
            Thread readThread = new Thread(Read);
            readThread.Start();
 
            //4. 데이터송신
            Console.WriteLine("Type QUIT to exit");
            while (_continue)
            {
                message = Console.ReadLine();
                if (stringComparer.Equals("quit", message))
                {
                    _continue = false;
                }
                else
                {
                    Send(message);
                }
            }
 
            //수신쓰레드종료까지대기
            readThread.Join();
            _serialPort.Close();
 
        }
 
        //포트리스트가져오기
        static string[] GetPortNames()
        {
            return System.IO.Ports.SerialPort.GetPortNames(); 
        }
 
        //포트리스트가져오기
        static void PortSettings(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits)
        {
            _serialPort.PortName = portName;
            _serialPort.BaudRate = baudRate;
            _serialPort.DataBits = dataBits;
            _serialPort.Parity = parity;
            _serialPort.StopBits = stopBits;
        }
 
        //데이터송신
        static void Send(string sendMsg)
        {
            _serialPort.WriteLine(sendMsg);
        }
 
        //데이터수신스레드부
        static void Read()
        {
            string readData = string.Empty;
            Console.WriteLine("Read Ready");
 
            while (_continue)
            {
                try
                {
                    readData = _serialPort.ReadLine();
                    Console.WriteLine("RD:{0}", readData);
                }
                catch (System.TimeoutException)
                {
                }
            }
        }
        
    }
}
 
cs


이제 프로그램을 테스트 해보도록 하겠습니다. 원칙적으로는 두대의 PC가 있어서 테스트가 가능합니다. 두대의 PC가 있는경우에는 두개PC를 시리얼포트를 연결해서 테스트하시면됩니다. 저는  VSPE프로그램으로 가상포트를 생성해서 테스트 해보도록 하겠습니다. 포트1,포트2를 가상으로 생성하고 해당포트를 물리적으로 연결한것 처럼 설정한것으로 하여 테스트 하겠습니다. VSPE프로그램 설정법은  다음링크를 sosopro.tistory.com/11 참고하세요. 포트를 열고 터미널에서 명령을 입력후 전송을 하면 연결된 포트로 데이터가 전송된것을 확인할수 있습니다. 


참고) 
https://docs.microsoft.com/ko-kr/dotnet/api/system.io.ports.serialport?view=netframework-4.6.1&f1url=%3FappId%3DDev15IDEF1%26l%3DKO-KR%26k%3Dk(System.IO.Ports.SerialPort);k(TargetFrameworkMoniker-.NETFramework,Version%253Dv4.6.1);k(DevLang-csharp)%26rd%3Dtrue

반응형