본문 바로가기
개발일지

시리얼 통신(Serial Port)

by 태운콩즙 2024. 10. 10.
728x90
반응형

시리얼 포트를 사용해 스케너로 바코드 읽기

시리얼 통신을 이용해 스케너 로 바코드를 읽는 윈폼 예제를 만들어 보았다

기본적인 형태는 이렇게 만들었다

COM 포트를 설정 할 수 있는 콤보 박스

연결 , 해제 버튼

상태 레이블

송수신 창 과 보내기 버튼

serialPort1 컨트롤

using System.IO.Ports; // 시리얼통신을 위해 추가

우선 네임스페이스 를 선언 해주고

 private void Form1_Load(object sender, EventArgs e)
 {
     comboBox_Port.DataSource = SerialPort.GetPortNames(); // 연결 가능한 시리얼 포트 이름을 가저오기
 }

Form1 이 실행되면 DataSource, GetPortName을 통해 연결 가능한 시리얼 포트 이름을 COM포트 설정 콤보박스에 가져온다

연결하기 버튼을 눌렀을 때, 설명 및 포트 연결

        private void button_Connect_Click(object sender, EventArgs e)
        {
            if (!serialPort1.IsOpen)
            {
                serialPort1.PortName = comboBox_Port.Text; // 콤보 박스의 선택된 COM 포트명을 시리얼 포트명으로 지정
                serialPort1.BaudRate = 9600; // 보레이트
                serialPort1.DataBits = 8;
                serialPort1.StopBits = StopBits.One;
                serialPort1.Parity = Parity.None;
                serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived); // 수신 이벤트 헨들러

                serialPort1.Open();// 포트 열기

                label_Status.Text = "OK";
                comboBox_Port.Enabled = false; // COM포트 설정 콤보박스 비활성화
            }
            else 
            {
                label_Status.Text = "The port already exists.";
            }
        }

위에 BaudRate 는 스케너 혹은 하드웨어 별로 상이하니 확인해보고 변경을 해주면 된다

그리고 쓰레드 충돌을 피하기 위해 Invoke 를 넣어주고

 // 시리얼 통신 수신 시 쓰레드 충돌을 피하기 위함
 private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) 
 {
     this.Invoke(new EventHandler(MySerialReceived));
 }

데이터 수신을 한다

 private void MySerialReceived(object s, EventArgs e)
 {
     
     // 시리얼 포트에 수신된 모든 데이터를 바이트 배열로 읽어오기
     int bytesToRead = serialPort1.BytesToRead;  // 버퍼에 남아 있는 바이트 수를 확인
     
     byte[] buffer = new byte[bytesToRead];      // 남아 있는 바이트만큼 배열 생성
     serialPort1.Read(buffer, 0, bytesToRead);   // 버퍼에서 데이터를 읽음

     // 바이트 배열을 문자열로 변환 
     string receivedText = Encoding.ASCII.GetString(buffer);  // 문자열로 변환

     string originar = receivedText;
     // 구분자로 데이터 나누기
     string[] split_data = originar.Split(new string[] { "구분자" }, StringSplitOptions.None);

     
     // 디코딩 이후 특정 문구 변경
     Console.WriteLine("Decoded ASCII String: " + receivedText.Replace("\\구분자","@"));

     
     

     foreach (string data in split_data)
     {
         // 각 RichTextBox에 데이터를 담아서 출력
         if (split_data.Length >= 6)
         {
             richTextBox1.Text = split_data[0];  
             richTextBox2.Text = split_data[1];  
             richTextBox3.Text = split_data[2];  
             richTextBox4.Text = split_data[3]; 
             richTextBox5.Text = split_data[4]; 
             richTextBox6.Text = split_data[5]; 
         }
     }

    
 }

바코드를 스케너로 읽게되면 바이트형식으로 받아서 문자열로 변환을 하고 구분자를 기준으로 각각의 박스에 넣어주었는데 구분자를 확인하기 위해 디코딩을 해주었고 그 구분자를 특정 문구로 변환해 확인을 해주었다

        private void button_Send_Click(object sender, EventArgs e) // 보내기 버튼 클릭시
        {
            serialPort1.Write(textBox_Send.Text); // 텍스트 박스의 텍스트를 시리얼통신으로 송신
        }

        private void button_Disconnect_Click(object sender, EventArgs e) // 통신 연결 끊기 버튼
        {
            if (serialPort1.IsOpen) // 시리얼 포트가 열려있으면
            {
                serialPort1.Close(); // 시리얼 포트 닫기

                label_Status.Text = "closed";
                comboBox_Port.Enabled = true;   // COM 포트 설정 콤보박스 활성화
            }
            else // 시리얼 포트가 닫혀있으면
            {
                label_Status.Text = "The port is already closed";
            }

        }

    }
}

나머지 버튼 기능들

728x90
반응형

'개발일지' 카테고리의 다른 글

영업 관리 프로그램 예제  (0) 2024.11.05
DNS (Dns 클래스)  (0) 2024.10.11
SpringLegacy Project -2-  (0) 2024.02.07
SpringLegacy Project -1-  (0) 2024.02.06
SpringLegacy -2-  (1) 2024.02.05