バイナリでのシリアル通信

Arduino等でPCと通信する際、シリアル通信で自由な文字を制御に使うことができる。 「より速い通信を」、「制御文字とデータが混ざらないようにしたい」等の理由でバイナリ通信したくなることがあるかもしれない。 ここでは、その例を載せておく。




ASCII制御コード


参考: 制御文字(Wikipedia)
バイナリでのシリアル通信を行う際に便利なASCII制御コードを表にまとめた。

文字 10進数 16進数 意味
SOH 1 0x1 通信のヘッダ開始
STX 2 0x2 通信の本文開始
ETX 3 0x3 通信の本文終結
EOT 4 0x4 伝送終了
ENQ 5 0x5 問い合わせ
ACK 6 0x6 異常なし、OK
NAK 21 0x15 異常、問題発生
SYN 22 0x16 同期
ETB 23 0x17 1ブロック分の通信終わり

エラーチェック


通信をしていると、割り込みや通信の問題で誤ったデータを受信してしまうことがあるので、 そのチェック方法を載せる。

チェックサム

例えば一回の通信で送られるデータが以下のようになっている場合、 SOH=1、STX=2、ETX=3なので<SUM>=1+3+2+83+79+83+3=254となる。
SOH 3 STX 83 79 83 <SUM> ETX (1文字1文字(1 byte)はスペース区切り)


パリティチェック

これはそれぞれの文字/データを2進数に変換して各桁のXORをとったもの。(執筆中)

COBS


参考: Arduinoでバイナリ送受信のシリアル通信をするときのパケットの構造
バイナリ通信を行う際、データだけを送受信しているとデータの区切りが分からなくなってしまう。 それを防ぐために考えられたフォーマットである。

具体的には、実データの前と後ろに1つずつ1byteのデータを追加する。 後ろの1byteは0を送って、0がデータの区切れになるようになっている。
最初の1byteは次に0が現れるまでのbyte数を記述している。 またデータ中に0が現れたときは次に0が現れるまでのbyte数に置き換えることで0はデータの区切れのみで現れるようにした方式。

例として0がないデータで4byteの1,2,3,4というデータがあった場合を考える。

  1. まず後ろに0をつける。 1,2,3,4,0
  2. 最初に0が現れるまでのbyte数を追加。 5,1,2,3,4,0

0があるデータで4byteの1,0,0,4というデータがあった場合を考える。

  1. まず後ろに0をつける。 1,0,0,4,0
  2. 次に0が現れるまでのbyte数を追加。 2,1,0,0,4,0
  3. 次に0が現れるまでのbyte数で次の0を置き換え。 2,1,1,0,4,0
  4. 次に0が現れるまでのbyte数で次の0を置き換え。 2,1,1,2,4,0