1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

シリアル通信パケット用のCOBSデコーダも作ってみる

Last updated at Posted at 2021-07-10

SS 192.png COBSがふにおちたい その2

やること

前回記事「シリアル通信パケット用のCOBSエンコーダーを作ってみる」の続きです。
デコーダーを作ります。

前回記事:

参考

前回同様、こちらの記事を参考にさせていただきました。ありがとうございました。

使うもの

  • Arduino
  • Arduino IDE など

実装

COBSのデコーダーを作ります。
下記のスクリプトでは
・もとのデータを表示
・エンコードしたデータを表示
・それをデコードのためにトリミングしたデータを表示
・上記に0x00を入れて元のデータを復元したデコード結果を表示
という順に作業をしています。

Arduino
//1バイト型で作っているため、データ配列の最大長は254

//↓送信したいデータの配列。データを書き換えてテストできます。(uint8_t型の値のみ)
uint8_t source_data[] = {00, 00, 185, 00, 33, 00, 44, 00, 00, 55, 00, 00, 200, 222, 130, 566, 60, 00}; //適当な数字

uint8_t cobs[sizeof(source_data) + 2]; // COBSに変換した送信データの配列(上記に2バイト追加)
uint8_t received_data[sizeof(source_data)]; //受信後にデコードしたデータを入れる配列。

void setup() {
  Serial.begin(115200);//シリアルモニター表示
  delay(500);
}

void loop() {

  // **** 元のデータの表示 ****
  Serial.print("Source Data   :   ");
  for (int i = 0 ; i < sizeof(source_data) ; i++)
  {
    Serial.print(source_data[i]);
    Serial.print(",");
  }
  Serial.println();

  // **** 配列を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の末端処理
  cobs[mark] = count; //前回0x00が出た配列にカウント値を改めて書き込む
  cobs[sizeof(source_data) + 1] = 0; //終端に0x00を代入する

  //エンコーダーで変換した結果を表示
  Serial.print("Encorded Data : ");
  for (int i = 0 ; i < sizeof(source_data) + 2; i++){
    Serial.print(cobs[i]); Serial.print(",");
  }
  Serial.println();

  // ** COBSから元のデータを復元するデコーダー **

  //先頭と末尾をトリムしたデータを作成する(0x00はまだ代入していない)
  for (int i = 0; i < sizeof(received_data); i++) { //全パケットをデコード結果用の配列に取り込む(先頭と末尾を除く)
    received_data[i] = cobs[i + 1];
  }

  //先頭と末尾をトリムしたデータの表示
  Serial.print("Trimmed Data  :   ");
  for (int i = 0 ; i < sizeof(received_data); i++) {
    Serial.print(received_data[i]); Serial.print(",");
  }
  Serial.println();

  //該当する場所に0x00を代入する処理
  int i = 0;
  while ( i <= sizeof(received_data)) {
    i = i + cobs[i];
    received_data[i - 1] = 0;
  }

  //0x00を代入したデコード結果の表示
  Serial.print("Decorded Data :   ");
  for (int i = 0; i < sizeof(received_data); i++) {
    Serial.print(received_data[i]); Serial.print(",");
  }
  Serial.println(); Serial.println();
  delay(1000);
}

動作確認

デフォルトではシリアルモニタに下記のような結果を出力します。

Source Data : 最初のデータ
Encorded Data: COBSにエンコードしたデータ
Trimmed Data: デコード用にCOBSの先頭と末尾をトリミングしたデータ
Decorded Data: 0x00を代入して元のデータを再現したもの

source_data[]の中の配列データを書き換えたり要素数を増やしたりして挙動を確認できます。

まちがっていたら

すみません!

つぎやること

共用体を使って2バイトデータを格納、送信できるようにします。

前回記事:

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?