[시리얼 통신] C#을 활용한 시리얼 통신 모니터링 프로그램 만들기
본문 바로가기
프로그래밍

[시리얼 통신] C#을 활용한 시리얼 통신 모니터링 프로그램 만들기

by 124578 2022. 4. 2.

[시리얼 통신] C#을 활용한 시리얼 통신 모니터링 프로그램 만들기

 

시리얼통신 모니터링 프로그램은 인터넷에 많은 프로그램이 올라와 있습니다. 하지만 이 프로그램을 만드는 것은 결코 어렵지 않습니다. 시리얼 통신 모니터링 프로그램을 C# 프로그램으로 만들어 보는 포스팅을 해 보겠습니다.

1. 시리얼 통신 프로그램 제작

우선 비주얼 스튜디오를 실행하여 winform 기반의 프로젝트를 작성 합니다. 

비주얼 스튜디오 winform 프로젝트 만들기
비주얼 스튜디오 winform 프로젝트 만들기

2. 시리얼 통신 윈폼 화면 작성

시리얼 통신 윈폼 화면을 아래 그림과 같이 작성합니다.

 

시리얼통신 윈폼 화면 작성
시리얼통신 윈폼 화면 작성

위그림과 같이 컴포트 설정, 보레이트, 데이터비트, 패리티 비트, 스톱비트, 흐름제어를 설정하는 부분을 작성합니다.

 

통신설정상태 그리고 컴포트 연결하는 부분을 작성합니다. 

 

통신의 상태를 전송하는 부분도 작성합니다.  전송을 주기적으로 만들기 위한 부분도 작성합니다.

 

통신을 수신하여 보여주는 부분도 작성합니다.

 

아래그림처럼 솔루션 프로젝트가 생성 됩니다

기본 Form1.cs 외에 시리얼 통신을 위한 SerialComm.cs 클래스를 작성 합니다.

 

시리얼 통신 프로젝트 전체 솔루션
시리얼 통신 프로젝트 전체 솔루션

 

Form1.cs 클래스는 프로그램의 주요 기능구현에 대한 클래스 입니다.

SerialComm.cs 클래스에는 시리얼 통신에 대한 코드가 있습니다.

 

3. 코드의 작성

아래와 같이 Form1.cs 프로그램을 작성합니다.

 

- Form1.cs -

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using System.Collections;

namespace SerialMonitor
{
    class SerialComm
    {

        public ArrayList arrSerialbuff = new ArrayList(); // 수신용 List 버퍼 선언
        private SerialPort sp = new SerialPort();// 시리얼 포트 선언
        
        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

        //        Comport 열기

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
        public string Comport_Open(string port, string baud, string databits, string parity, string stop)
        {

            try
            {

                // 시리얼 통신 포트, 보레이트, 데이터 비트, 패리티, 스톱 비트를 설정
                sp.PortName = port;
                sp.BaudRate = int.Parse(baud);
                sp.DataBits = int.Parse(databits);
                sp.Parity = (Parity)Enum.Parse(typeof(Parity), parity);


                sp.StopBits = (StopBits)Enum.Parse(typeof(StopBits), stop);



                // 이미 오픈상태인지 체크하여 아니라면
                if (!sp.IsOpen)
                {
                    // 포트 열기
                    sp.Open();
                }
                // 포트가 열린 상태이면 연결 완료
                if (sp.IsOpen)
                {

                    return "연결완료";
                }
                else  // 포트열기가 열린상태가 아니라면 연결 실패
                {
                    return "연결실패";
                }

            }
            catch (Exception ex)
            {
                throw ex;

            }
        }
        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

        //      수신 처리 

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
        public void RcvSerialComm()
        {
            try
            {
                // 포트가 열린 상태인지 체크
                if (sp.IsOpen)
                {
                    // 시리얼 수신 버퍼에 적재된 byte 개수를 읽어 온다.
                    int nbyte = sp.BytesToRead;

                    // 시리얼 byte개수 만큼 버퍼를 생성한다.
                    byte[] rbuff = new byte[nbyte];

                    // byte개수가 0보다 크다면
                    if (nbyte > 0)
                    {
                        //  수신버퍼에서 버퍼의 지정된 인덱스 부터 개수 만큼 읽어 온다.
                        sp.Read(rbuff, 0, nbyte);
                    }

                    // ArrayList에 적재한다.
                    for (int i = 0; i < nbyte; i++)
                    {
                        arrSerialbuff.Add(rbuff[i]);
                    }



                }
            }
            catch (Exception ex)
            {
                // 수신에러 발생시 
                // ArrayList를 클리어한다.
                arrSerialbuff.Clear();
                //예외를 던지고 종료
                throw ex;
            }

        }

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

        //      포트 상태 체크

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
        public bool IsOpened()
        {

            return sp.IsOpen;
        }

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

        //      수신 개수 읽기

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
        public int RcvCnt()
        {
            return arrSerialbuff.Count;
        }

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

        //     수신버퍼 클리어

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
        public void RcvBuffClear()
        {
            arrSerialbuff.Clear();
        }

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

        //    송신 처리

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
        public void SendSerialComm(byte[] SendComm_Packet, int len)
        {
            try
            {
                if (sp.IsOpen)
                    sp.Write(SendComm_Packet, 0, len);
            }
            catch (Exception ex)
            {
                throw ex;

            }

        }

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

        //    포트 닫기

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
        public void CloseSerialComm()
        {
            try
            {
                if (sp != null)
                    sp.Close();
            }
            catch (Exception ex)
            {
                throw ex;

            }
        }

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

        //    시리얼포트 해제

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
        public void Dispose()
        {

            if (arrSerialbuff.Count > 0)
            {
                arrSerialbuff.Clear();
            }

            if (sp != null)
               sp.Dispose();
        }

    }
}

 

 아래는 SerialComm.cs 프로그램 코드 입니다. 이 클래스에는 시리얼 통신에 대한 송수신 및 컴포트 열기 닫기 기능을 구현해 놓았습니다.

 

- SerialComm.cs -

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using System.Collections;

namespace SerialMonitor
{
    class SerialComm
    {

        public ArrayList arrSerialbuff = new ArrayList(); // 수신용 List 버퍼 선언
        private SerialPort sp = new SerialPort();// 시리얼 포트 선언
        
        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

        //        Comport 열기

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
        public string Comport_Open(string port, string baud, string databits, string parity, string stop)
        {
            try
            {

                // 시리얼 통신 포트, 보레이트, 데이터 비트, 패리티, 스톱 비트를 설정
                sp.PortName = port;
                sp.BaudRate = int.Parse(baud);
                sp.DataBits = int.Parse(databits);
                sp.Parity = (Parity)Enum.Parse(typeof(Parity), parity);


                sp.StopBits = (StopBits)Enum.Parse(typeof(StopBits), stop);



                // 이미 오픈상태인지 체크하여 아니라면
                if (!sp.IsOpen)
                {
                    // 포트 열기
                    sp.Open();
                }
                // 포트가 열린 상태이면 연결 완료
                if (sp.IsOpen)
                {

                    return "연결완료";
                }
                else  // 포트열기가 열린상태가 아니라면 연결 실패
                {
                    return "연결실패";
                }

            }
            catch (Exception ex)
            {
                throw ex;

            }
        }
        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

        //      수신 처리 

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
        public void RcvSerialComm()
        {
            try
            {
                // 포트가 열린 상태인지 체크
                if (sp.IsOpen)
                {
                    // 시리얼 수신 버퍼에 적재된 byte 개수를 읽어 온다.
                    int nbyte = sp.BytesToRead;

                    // 시리얼 byte개수 만큼 버퍼를 생성한다.
                    byte[] rbuff = new byte[nbyte];

                    // byte개수가 0보다 크다면
                    if (nbyte > 0)
                    {
                        //  수신버퍼에서 버퍼의 지정된 인덱스 부터 개수 만큼 읽어 온다.
                        sp.Read(rbuff, 0, nbyte);
                    }

                    // ArrayList에 적재한다.
                    for (int i = 0; i < nbyte; i++)
                    {
                        arrSerialbuff.Add(rbuff[i]);
                    }
                }
            }
            catch (Exception ex)
            {
                // 수신에러 발생시 
                // ArrayList를 클리어한다.
                arrSerialbuff.Clear();
                //예외를 던지고 종료
                throw ex;
            }

        }

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

        //      포트 상태 체크

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
        public bool IsOpened()
        {

            return sp.IsOpen;
        }

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

        //      수신 개수 읽기

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
        public int RcvCnt()
        {
            return arrSerialbuff.Count;
        }

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

        //     수신버퍼 클리어

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
        public void RcvBuffClear()
        {
            arrSerialbuff.Clear();
        }

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

        //    송신 처리

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
        public void SendSerialComm(byte[] SendComm_Packet, int len)
        {
            try
            {
                if (sp.IsOpen)
                    sp.Write(SendComm_Packet, 0, len);
            }
            catch (Exception ex)
            {
                throw ex;

            }
        }

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

        //    포트 닫기

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
        public void CloseSerialComm()
        {
            try
            {
                if (sp != null)
                    sp.Close();
            }
            catch (Exception ex)
            {
                throw ex;

            }
        }

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

        //    시리얼포트 해제

        //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
        public void Dispose()
        {

            if (arrSerialbuff.Count > 0)
            {
                arrSerialbuff.Clear();
            }

            if (sp != null)

                sp.Dispose();
        }
    }
}

 

4. 프로그램 사용법

  1. 프로그램 코드를 위와 같이 작성 후에 코드를 실행 합니다. 
  2. 프로그램을 처음 실행 시키면 Comport 콤보박스에 자동으로 현재 시스템에 존재하는 시리얼 포트를 잡아 표시합니다.
  3. 사용하고자하는 시리얼 포트를 선택한 후 아래의 baudrate(보레이트), Databit(데이터 비트), Parity(패리티 비트), Stop Bit(스톱 비트), Flow Control(흐름제어) 등을 설정합니다.
  4. Connect 버튼을 눌러 시리얼 포트를 열어 줍니다.
  5. 정상적으로 동작이 되면 Connect State가  Connected 상태로 바뀌게 되고 아닌경우에는 Not Connected로 바뀌게 됩니다.
  6. Send Hex 체크박스를 눌러 Hex byte로 전송을 할 수도 있습니다.
  7. Timer 체크박스를 눌러 주기적으로 데이터를 전송 할 수도 있습니다.
  8. 수신 박스에는 통신으로 수신되는 데이터가 표시되며 Show Hex 체크박스를 체크하면 Hex byte 상태로 표시 됩니다.

 

 

 

 

댓글


TOP

TEL. 02.1234.5678 / 경기 성남시 분당구 판교역로