시리얼 통신 패킷용 COBS 인코더 만들기

COBS가 두근두근하고 싶다

할 일



시리얼 통신으로 나름의 양의 데이터를 단시간에 보내려고 했을 때, 텍스트가 아닌 바이너리로 흘리는 것이 경량 쾌속입니다.
그러나 Arduino의 Serial.write() 는 바이너리 데이터를 많이 흘릴 뿐이므로, 수신측에서 데이터의 단락을 판단시키는 곳에 한 궁리가 필요합니다.
(패킷 사이즈가 커도 좋은 경우에는, 개행 기호로 간단하게 단락 판별을 시킬 수도 있습니다.1/1000초 단위로 조금 긴 데이터를 교환하고 싶을 때 등에는 역시 바이너리 송신이 도움이 됩니다. )

COBS(Consistent Overhead Byte Stuffing)는 1 패킷의 데이터 중에 0x00이 1번밖에 출현하지 않도록 하는 데이터 변환 방법입니다.
이것을 수중에서 (자신도 알 수 있듯이) 구현해 보겠습니다.
이번에는 인코더를 만듭니다.

참고



이쪽의 기사를 참고로 했습니다. 매우 공부가 되었습니다. 고마워요.

사용하는 것


  • Arduino
  • Arduino IDE 등

  • COBS의 원리



    우선 데이터를 1바이트씩 배열에 저장해 갑니다.
    그 때, 배열의 시작 부분에 1 바이트를 추가해, 다음에 0x00이 나타날 때까지의 데이터의 개수를 카운트해 대입합니다. 다음에 0x00이 나타난 배열 번호의 데이터에는, 그 다음의 0x00이 나타날 때까지의 카운트를 대입합니다. 이것을 반복해 나가는 것으로, 데이터에 나타나는 0x00을 모두 1 이상의 수치로 옮겨놓을 수가 있습니다. 데이터의 마지막만을 0x00으로 해, 스타트 비트/스톱 비트로서 이용해 가는 구조입니다.
    예를 들어 데이터 중에 한 번도 0x00이 나타나지 않는 패킷의 경우, 처음의 카운터는 데이터의 마지막 꼬리의 배열 번호를 나타내게 됩니다.
    원래의 데이터의 전후에 1바이트씩, 합계 2바이트 밖에 늘어나는 뛰어난 방식입니다.

    구현



    흐르고 싶은 시리얼 데이터를 준비합니다.
    여기에서는 wikipedia 데이터 사례 가 성립하는지 어떤지를 살펴봅니다.

    가능한 한 규모가 작아지도록 만들고 있습니다. 1 패킷 당의 시리얼 데이터의 길이는 254 바이트가 상한이 됩니다.

    Arduino
    //1バイト型で作っているため、データ配列の最大長は254(カウントできる最大値)
    uint8_t source_data[] = {11, 22, 00, 33}; //送信したいデータの配列。書き換えて動作テスト。
    uint8_t cobs[sizeof(source_data) + 2]; // COBSに変換した送信データの配列(上記に2バイト追加)
    
    void setup() {
      Serial.begin(115200);//シリアルモニター表示
      delay(500);
    }
    
    void loop() {
      //配列をCOBSの方式で処理する
    
      uint8_t count = 0; //次にsource_data[i]に0x00が出るまでの配列番号をカウント
      int mark = 0; //最後に0x00が出たsource_data[i]の配列番号をキープ
    
      for (int i = 0 ; i < sizeof(source_data) + 1; i++) {
    
        //現在チェックしているsource_data[i]の中身が0x00ではない場合
        if (source_data[i] != 0x00) {
          cobs[i + 1] = source_data[i]; //チェックした値をそのままcobs配列に書き込む
          count ++;//前回0x00が出たsource_data[i]の配列内のカウント値を+1
        }
    
        //現在チェックしているsource_data[i]の中身が0x00だった場合
        else {
          count ++;//前回0x00が出た配列のカウントを+1
          cobs[mark] = count;//前回0x00が出たcobs配列にカウント値を書き込み確定
          mark = i + 1; // 現在のcobs配列を0x00が出た配列としてキープ
          count = 0 ;//0x00が出た配列のカウントをリセット
          cobs[mark] = count; //今回0x00が出たcobs配列にカウント値を書き込む
        }
      }
    
      //末端処理
      cobs[mark] = count; //前回00が出た配列にカウント値を改めて書き込む
      cobs[sizeof(source_data) + 1] = 0; //終端に00を代入する
    
      //変換した結果を表示
      for (int i = 0 ; i < sizeof(source_data) + 2; i++)
      {
        Serial.print(cobs[i]); Serial.print(",");
      }
      Serial.println();
      delay(1000);
    }
    

    동작 확인



    source_data[]의 배열 데이터를 Wikipedia 사례처럼 변경해 보세요.
    의도대로 결과가 출력된다고 생각합니다.


    틀리면



    죄송합니다!

    다음 일



    COBS 디코더를 만듭니다.

    다음 기사:

    좋은 웹페이지 즐겨찾기