CAFE

[.NET]Tip & Tech

VB 시리얼 통신

작성자보노보노|작성시간15.05.06|조회수3,364 목록 댓글 0

그전에 먼저 VB 6.0을 다루어 본 적이 있던 사람들은 VB.NET이 친근하면서도 낮선느낌이 있습니다.

VB.NET 2005는 분명 VB 6.0의 대를 잇고 있지만 다른 느낌도 강했습니다.. 버젼상으로도 8.0에 해당하며 닷넷 프레임워크로 넘어오면서..

VB 6.0에서 쓸 수 있던 프로그래밍 방식이나 컨트롤이 변경 돼 VB 6.0에 익숙한 많은 개발자들이 VB.NET으로 완전히 못 넘어오는 걸로 알고 있습니다.

(아무래도 일단 당장 개발을 해야하는데 VB.NET으로 넘어오기에 시간적 여유가 부족한 듯)

 

 물론 VB는 닷넷 프레임워크 이후 변화가 있었지만 기본은 다르지 않기에...

저도 6.0 책 펴놓고 MSDN 뒤져서 일주일만에 프로젝트에 필요한 프로그램을 만들었을 정도로..

비주얼 베이직이란 언어 자체가 상대적으로 쉽고 강력하며 동급 다른 언어에 비해 빠른 시간에 응용프로그램을 작성 할 수 있습니다.

 

# 연습용 시리얼 통신 프로그램

 

알림!

 참고로 이 포스트는 응용프로그래밍에 정말 꽝!인 하드웨어 공부를 하는 학생들을 위하여 작성된 일종의 강좌이자 팁 입니다.

또한 이 포스트를 작성한 저 또한 프로그래밍 실력이 하위수준이므로 어설프고 부족하더라도 너그러이 봐주시고 양해바랍니다.

 

 

 위 그림을 보면 알겠지만 정말 허술한(;) 구성을 가진 단지 시리얼 데이터를 딱 1바이트씩 받아서 레이블에 출력해주는 프로그램입니다.

 송신하는 이벤트도 없고 오로지 수신만 하도록 되어있지만..

MSDN이나 시리얼 관련 .NET 클래스를 참조하시면 어렵지 않게 송신 이벤트도 작성이 가능합니다.

 

아마도 초보분들은 MSDN을 많이 접하시고 원하는 것을 잘 찾아보는 능력이 필요하다고 말씀 드릴 수 있겠습니다!

 

경고! 경고!

실은 이 프로그램은 검증을 못 해봤습니다. -_-;

아.. 작동은 하겠지요.. 라고만 말씀 드릴 수가 있겠습니다. 조금 무책임 합니다. -_-;

 

먼저 VB.NET 소스 설명에 앞서.. MCU 하드웨어 측 설정은 시리얼로 컴퓨터와 연결해주시면 되고 대략 아래와 같이

주기적으로 순차적인 1바이트 데이터를 보내주면 됩니다.

 

아래의 소스?는 CCS-C의 기준이지만..

다른 MCU 쓰시는 분들은 시리얼 통신으로 8비트 변수하나 만들어서

그냥..  1초마다 시리얼로 전송 시켜주세요~

RS232 속도는 원하시는대로.. 전송 시켜주시고 비주얼 베이직과 맞춰주시면 됩니다.

 

   .. 중간 생략 ..

    int cnt;       // 카운트용 변수

    while(true)

    {

           delay_ms(1000);

           puts(cnt++);          // 약 1초에 한번씩 1바이트 데이터를 보낸다.

    }

}

 

대충 시리얼 통신이 정상적으로 된다고 하면...  0 ~ 255란 값이 약 1초마다 시리얼 통신으로 보내어 지게 되고,

어플리케이션 측에는 레이블에 0 ~ 255까지 숫자가 계속 출력 되어야 합니다.

 

많은 분들이 제대로 했는데도 안된다.. 싶으시면.. 직접 자체 검증 들어가겠습니다. ㅜ. ㅜ

 

하드웨어 세팅이 모두 끝났으면 VB.NET 소스를 살펴보기전에 먼저

Form의 컨트롤들의 위치나 이름 등을 위 그림 처럼 설정되어 있음을 확인하세요.

 

현재 그림엔 보이진 않지만. lblMessage란 이름을 가진 레이블도 폼 중간에 존재하고 있습니다.

 

알림!

소스내의 분홍색 또는 회색 글은 설명글로 소스와 전혀 관계 없습니다.

그외 파란색, 녹색(주석), 빨간색(문자)은 실제로 코딩 할 때 비주얼베이틱 소스 에디터 창에 보이는 색입니다.

또한 이 프로그램은 MSDN에서 어느 중국인 개발자가 예제로 올려 놓을 것을 참고하여 작성 된 것임을 밝힙니다.

 

 VB 6.0에서는 COM 컨트롤이 있어서 그 컨트롤을 활용하여 시리얼 통신을 구현했지만

그 컨트롤은 닷넷에서 없어졌고 새로이 SerialPort라는 컨트롤이 생겼습니다다.

그러나 아래의 소스에서는 컨트롤을 놓고 쓰는게 아닌 시리얼 포트 클래스를 직접 불러와서 쓰는 방식을 취하고 있습니다.

 

< VB.NET Form1.vb 소스 >

Public Class Form1

    Dim WithEvents serialPort As New IO.Ports.SerialPort

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _

                                              Handles MyBase.Load

        For i As Integer = 0 To My.Computer.Ports.SerialPortNames.Count - 1
            cbbCOMPorts.Items.Add(My.Computer.Ports.SerialPortNames(i))
        Next

        btnDisconnect.Enabled = False

    End Sub

 

Form1_Load 이벤트는 폼1이 뜰 때 즉, 프로그램이 시작될 때 수행되는 초기화 루틴으로 보면 됩니다.

_ (언더바)가 줄 끝에 있는 것은 한줄에 코드를 넣어서 보기가 힘들 때 일종의 줄바꿈 할때 쓰는 것으로 컴파일러는 줄이 바뀐 것이라 인식하지 않습니다.

폼 로드 이벤트 안에는 현재 내 컴퓨터에서 사용이 가능한 시리얼 포트를 검사하여 리스트에 추가하는 작업을 보여주고 있습니다.

 

    '***************************************************************************
    '** 시리얼 연결 버튼 클릭 이벤트
    '***************************************************************************

    Private Sub btnConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _

                                                       Handles btnConnect.Click

        If serialPort.IsOpen Then
            serialPort.Close()
        End If

        Try
            With serialPort
                .PortName = cbbCOMPorts.Text      '포트네임.. 직접 COM1, COM2 지정해주어도 된다.
                .BaudRate = 9600                            '2400 4800 9600 .. .. 115200 통신속도 지정
                .Parity = IO.Ports.Parity.None
                .DataBits = 8
                .StopBits = IO.Ports.StopBits.One
                .Encoding = System.Text.Encoding.ASCII      'System.Text.Encoding.Unicode
                .ReadBufferSize = 16                                     '설정 전의 기본값은 4096
                .WriteBufferSize = 16                                    '출력버퍼 사이즈

            End With

            serialPort.Open()

            lblMessage.Text = cbbCOMPorts.Text & " 에 연결되었습니다."

            cbbCOMPorts.Enabled = False

            btnConnect.Enabled = False
            btnDisconnect.Enabled = True

        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try

    End Sub

 

시리얼 연결 버튼을 눌렀을 때 발생하는 이벤트로 먼저 COM 포트를 콤보박스에서 선택해야 한합니다.

그렇지 않으면 Catch ex As Exception 예외 상황이 발생하여 해당 에러에 관한 메세지가 출력됩니다..

주석을 잘 참고하면 시리얼 포트 관련 설정을 할 수 있다는 것을 확인 할 수 있으며, 인코딩은 아스키코드인지 유니코드인지 선택할 수 있고

MSDN을 참고하면 더 많은 인코딩 방식을 볼 수 있습니다.

그리고 위의 소스의 경우 읽기 버퍼를 적게 조절했습니다.

그 이유는 MCU측에서 전송되어진 데이터를 PC측에서 미처 처리하지 못하면 버퍼에 계속 누적됩니다. 너무 누적되면..

최신 데이터를 보여주지 못하기 때문에.. 읽기 버퍼량을 줄였는데..

보통 수십바이트는 되어야 그렇고.. 보통 1바이트에.. 넉넉한 전송 시간이면.. 상관이 없습니다.

그리고 연결과 동시에 사용되지 않을 버튼은 Enabled를 False로 처리하여 클릭하지 못하도록 하였습니다

 

    '***************************************************************************
    '** 시리얼 연결 해제 버튼 클릭 이벤트
    '***************************************************************************
   Private Sub btnDisconnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
        Handles btnDisconnect.Click
        Try
            serialPort.Close()
            lblMessage.Text = serialPort.PortName & " 에 연결이 해제되었습니다."

            cbbCOMPorts.Enabled = True
            btnConnect.Enabled = True
            btnDisconnect.Enabled = False

        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    End Sub

 

 시리얼 포트 연결을 해제하는 이벤트입니다. 또한 연결하는 버튼을 다시 사용할 수 있도록 Enabled 값을 True로 바꾸어 놓았습니다.

 

    Private Sub DataReceived(ByVal sender As Object, ByVal e As _

                                                System.IO.Ports.SerialDataReceivedEventArgs) _
                                                Handles serialPort.DataReceived

        lblReceiveData.Text = serialPort.ReadByte

        'DiscardInBuffer  '직렬 드라이버의 수신 버퍼에서 데이터를 삭제합니다.

    End Sub

End Class

 

시리얼 데이터가 수신되었을 때 수행되는 이벤트로 일종의 인터럽트?로 보시면 되구요.. 1바이트 수신된 값을 lblReceiveData에 출력해줍니다.

DiscardInBuffer는 수신 버퍼의 데이터를 모두 삭제할 때 쓰는데, 다량의 데이터를 수신 했을 시 VB.NET이 미쳐 처리하지 못하면 계속 버퍼에 데이터가 쌓이고 최신 데이터를 갱신, 출력 못하고 버퍼에 있는 데이터를 우선 출력해줍니다.

 

만약 최신 데이터를 유지해야하는 경우 예를 들면, 무선자동차의 속도 데이터를 수신하는 중이라고 할 때 속도와 같이 수시로 변하는 데이터는 최신 값이 유지 출력 되어야 하겠지요? 이럴 때는 일종의 꼼수로 버퍼 데이터를 삭제 해주면 최신 값을 유지 할 수 있습니다.

 

그리고 위의 소스에는 포함되어 있지 않지만,

시리얼 데이터를 전송 하는 명령어를 쓸 수 있는데 보통은 아스키코드 값으로 전송이 되어집니다.

 

제가 이걸 첫 프로그래밍할 당시 MSDN의 중국인이 만든 것은 채팅 프로그램이라.. 아스키코드 전송만 있고..

HEX 값을 보내는 방법 그리고 연속으로 데이터를 보낼 줄 몰라서 헤메었는데 열심히 MSDN을 보고 연구한 결과?

아래와 같이 하면 되는 것을 알았습니다.

 

           serialPort.Write(spdData, 0, 4)

 

여기서 spdData는 반드시 배열변수이어야 합니다. 비록 1바이트라고 할지라도.. 배열 변수를 만들어 주셔야 합니다.

MSDN을 참고하시면 알겠지만.. 문자열, 배열 hex, 배열 char 만이 SerialPort.Write() 메서드로 쓸 수 있습니다.

 

끝에 4라는 것은 4바이트를 전송한다는 것이고, 중간엔 오프셋인데.. 어디서 부터 전송을 시작할꺼냐? 정도 되는 듯 합니다.

 

위의 명령으로 spdData(1) ~ spdData(4)까지 순서대로 HEX 값을 전송합니다.

위의 명령으로 spdData(0) ~ spdData(3)까지 순서대로 HEX 값을 전송합니다.

 

실은 위에 둘 중하나인데.. 헷갈립니다. 아래가 맞을꺼라.. 예상만 하고 있습니다. -_-;

자세한 사항은 MSDN을 참고 해주세요^^

 

수신하는 방법과 전송하는 방법 모두 숙달 되시면.. 데이터를 프로그램에서 맛있게? 요리? 하시면 됩니다.


[출처] [VB] VB.NET으로 간단한 시리얼 통신 프로그램 작성해보기.. (LK임베디드) |작성자 머나아리

[제2출처] http://cafe.naver.com/joljakhe/261 | (no1) 내손으로 만드는 로봇

다음검색
현재 게시글 추가 기능 열기

댓글

댓글 리스트
맨위로

카페 검색

카페 검색어 입력폼