시리얼 통신 패킷용 COBS 디코더도 만들어 보자
할 일
마지막 기사 "시리얼 통신 패킷용 COBS 인코더를 만들어 보자"의 계속입니다.
디코더를 만듭니다.
마지막 기사:
참고
전회와 같이, 이쪽의 기사를 참고로 했습니다. 고마워요.
사용하는 것
전회와 같이, 이쪽의 기사를 참고로 했습니다. 고마워요.
사용하는 것
구현
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바이트 데이터를 저장하고 전송할 수 있습니다.
마지막 기사:
Reference
이 문제에 관하여(시리얼 통신 패킷용 COBS 디코더도 만들어 보자), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/Ninagawa_Izumi/items/7b35d16d8f4ae7fc2fb8
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
//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바이트 데이터를 저장하고 전송할 수 있습니다.
마지막 기사:
Reference
이 문제에 관하여(시리얼 통신 패킷용 COBS 디코더도 만들어 보자), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/Ninagawa_Izumi/items/7b35d16d8f4ae7fc2fb8
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
공용체를 사용하여 2바이트 데이터를 저장하고 전송할 수 있습니다.
마지막 기사:
Reference
이 문제에 관하여(시리얼 통신 패킷용 COBS 디코더도 만들어 보자), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Ninagawa_Izumi/items/7b35d16d8f4ae7fc2fb8텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)