やること
前回記事「シリアル通信パケット用の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バイトデータを格納、送信できるようにします。
前回記事: