본문 바로가기

Embedded System/Arduino Board

[Arduino] Packet 통신: Comportmaster를 활용한 Packet 수신(17)

반응형

 


 

안녕하세요.

아두이노를 이용해 외부 장치와 통신을 하거나 데이터를 수신할 때, 패킷 구조를 잘 이해하고 데이터를 처리하는 방법이 중요합니다. 이번 포스트에서는 아두이노에서 6바이트 패킷을 수신하고, 헤더와 체크섬을 통해 데이터의 유효성을 확인하는 방법을 소개하겠습니다. 


0. ComportMaster 설치 및 다운 & ComportMaster란?

https://semicircuit.tistory.com/entry/%EC%8B%9C%EB%A6%AC%EC%96%BC-%ED%86%B5%EC%8B%A0-Comport-Master%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-%EC%84%A4%EC%B9%98%EB%B0%A9%EB%B2%95-%EB%B0%8F-%EB%8B%A4

 

1. 패킷에 대한 이론적인 내용은 아래 참조해주세요
https://semicircuit.tistory.com/entry/%ED%8C%A8%ED%82%B7-%ED%86%B5%EC%8B%A0-%ED%8C%A8%ED%82%B7%ED%86%B5%EC%8B%A0-%EC%8B%9C%EC%8A%A4%ED%85%9C%EC%97%90%EC%84%9C%EC%9D%98-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%84%EC%86%A1

 

2. 아두이노에서 패킷 송신하는 내용은 아래 참조해주세요

https://semicircuit.tistory.com/entry/Arduino-Packet-%ED%86%B5%EC%8B%A0-Comportmaster%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-Packet-%EC%86%A1%EC%8B%A018

 

 

 

 

 

 

 

 

 

 

※1.  패킷 구조 설명 

우리가 사용할 패킷은 가장 단순한 구조의 총 6바이트로 구성되어 있습니다. 각 바이트의 역할은 다음과 같습니다.

  • 헤더 (Header, 1바이트): 패킷의 시작을 나타내는 값입니다. 여기서는 0xF2로 정의되었습니다.
  • 데이터 (Data, 4바이트): 실제 전송할 데이터입니다.
  • 체크섬 (Checksum, 1바이트): 패킷의 끝을 나타내며, 수신된 데이터가 올바른지 확인하는 값입니다. 여기서는 0xF3으로 정의됩니다.

 

※2. 소스코드 및 동작

위의 패킷구조와 같은 형태로 패킷을 수신하는 코드를 실행해 보겠습니다.

1. 소스코드

1. 6개의 바이트(=1개의 패킷)가 채워지지 않는 경우 아무런 동작을 하지 않습니다.

2. 6개의 바이트(=1개의 패킷)가 채워졌으나 Header와 Tailer가 다른 경우 "Invaild packet received!"를 띄웁니다.

3. 패킷의 Header와 Tailer가 적합한 신호가 들어올 경우 데이터 값을 "Data: D1 D2 D3 D4"형태로 출력합니다.

17_Packet_Receive_Comportmaster.ino
0.00MB

 

 

// 헤더와 체크섬 상수 정의
const byte HEADER = 0xF2;
const byte CHECKSUM = 0xF3;

void setup() {
  Serial.begin(9600);  // 시리얼 통신 초기화
  Serial.println("Send 6byte packets (Header:0xf2 Tailer:0xf3)");
}

void loop() {

  byte packet[6];  // 6바이트 패킷을 저장할 배열


  if ( Serial.available() > 0 && Serial.peek() != HEADER) { // 버퍼의 맨앞이 헤더가 오지 않는 경우 지속적으로 버퍼 초기화
    Serial.read();
    Serial.println("Improper Header, buffer cleared ");
  }
  

  if (Serial.available() >= 6) {
    // 6바이트 읽기
    for (int i = 0; i < 6; i++) {
      packet[i] = Serial.read();
    }

    // 헤더 확인
    if (packet[0] == HEADER && packet[5] == CHECKSUM) {
      // 데이터(4바이트) 출력
      Serial.print("Data: ");
      for (int i = 1; i < 5; i++) {
        Serial.print(packet[i], HEX);
        if (i < 4) Serial.print(" ");  // 데이터 간 공백 추가
      }
      Serial.println();
    }
    else{
      Serial.println("Improper Tailer, buffer cleared ");
    }
  }
  
}

 

 

※3. Wiring (배선 연결) & ComportMaster Setting

단순하게 아두이노와 PC와 케이블로 연결합니다. (USB to TTL 필요없습니다.)

 

ComportMaster의 세팅을 다음과 같이 해주세요. (Send안의 데이터는 예시입니다.)

**Deviced의 COM번호는 장치관리자 또는 아두이노IDE -> Tool(툴) ->포트에서 확인하여 각자 PC에 적합한 포트 찾아주세요(아래 동작 동영상 참조)

- 바이트 6개가 채워져야 1개의 패킷으로 인식합니다. 그전까지는 반응이 없습니다. 1번째 Send를 다중 send하여 테스트해보겠습니다.

- 2번째 Send와 3번째 Send처럼 (오른쪽전송방식)Hex로 바꾼상태에서 값 앞에 0x를 붙히는 것(0xF2)과 붙히지 않는것(F2) 모두 가능합니다. 2번째와 3번째 send를 통해 테스트해보겠습니다.

- 기본적으로 Hex형태로 Header와 CheckSum을 필터링하고 Data를 다루기에 ASCII로 보내게 되면 원할한 수신이 불가능합니다. 2번째와 4번째 send를 통해 테스트해보겠습니다.

- 5번째 send의 경우 Tailer(Checksum)이 코드상에서 설정해 놓은 0xF3가 아닌 0xF4입니다. 이럴 경우 유효한 데이터로 인식하지 않을 것입니다. 5번째를 send를 통해 테스트해보겠습니다.

 

 

 

 

※4. 동작

Comport Master와 아두이노를 연결하여 위의 코드를 실행해 보겠습니다.

 

 

 

 

2.  동작 확인

- 바이트 6개가 채워져야 1개의 패킷으로 인식합니다. 그전까지는 반응이 없습니다. 1번째 Send를 다중 send하여 테스트해보겠습니다. => Header와 1번째 send의 내용이 인식하여 필터링을 하지는 않고 버퍼에 저장되지만 6개의 바이트가 버퍼에 들어간다면 Tailer가 f3가 아닌 f2임에 따라 잘못된 Tailer(CheckSum)으로 인식합니다.

 

- 2번째 Send와 3번째 Send처럼 (오른쪽전송방식)Hex로 바꾼상태에서 값 앞에 0x를 붙히는 것(0xF2)과 붙히지 않는것(F2) 모두 가능합니다. 2번째와 3번째 send를 통해 테스트해보겠습니다. => 둘다 동일하게 원하는 데이터를 잘 보내는 것을 확인할 수 있습니다.

 

 

- 기본적으로 Hex형태로 Header와 CheckSum을 필터링하고 Data를 다루기에 ASCII로 보내게 되면 원할한 수신이 불가능합니다. 2번째와 4번째 send를 통해 테스트해보겠습니다. => ASCII로 보낸 경우 데이터 형식에 따른 문제가 발생합니다.

 

 

- 5번째 send의 경우 Tailer(Checksum)이 코드상에서 설정해 놓은 0xF3가 아닌 0xF4입니다. 이럴 경우 유효한 데이터로 인식하지 않을 것입니다. 5번째를 send를 통해 테스트해보겠습니다. => Tailer(CheckSum)가 맞지 않아 문제가 발생합니다.

 

 

 

 

 

이상으로 아두이노에서 Comportmaster에서 보내는 시리얼 패킷 데이터를 수신하는 방법에 대한 설명을 마치겠습니다.

다음 포스트에서 패킷 데이터를 송신하는 방법에 대해 다루겠습니다.

감사합니다.

 

반응형