自作センサプロトコル

STX(固定 2 バイト)+ Type + Length + Payload + CRC-16/CCITT という独自バイナリプロトコルを題材にしたサンプル。可変長 Payload の扱いと、CRC を応答へ自動付与する仕組みを試せます。

TCP 9500CRC-16/CCITT長さ前置(補正 +2)ビッグエンディアン

概要

固定スタートバイト+種別+長さ+可変ペイロード+チェックサム、という典型的な独自バイナリセンサを再現します。

可変長 Payload を「長さ元」フィールドで扱う方法、チェックサムを応答テンプレートに自動埋め込みする {crc:Crc16Ccitt} 記法、そして長さフィールドと実バイト数のずれを吸収する「長さ補正」の設定を学べます。

自作センササンプルの構造体ルール
「自動応答」タブ ②バイナリ構造応答:Read 要求に対し {crc:Crc16Ccitt} で CRC を自動付与する 1 ルール

ファイル構成

ファイル内容
sensor-proto/sensor-proto.commsimプロジェクト本体(構造体定義・構造体ルールを含む)
sensor-proto/sensor-proto.commsim-struct構造体定義のみを切り出した可搬ファイル(別プロジェクトへのインポート用)

機器構成

単一の TCP サーバセッション。センサクライアント(CommSim.Sample のシナリオ「センサ」等)が接続して Read 要求を送ります。

センサクライアントテスト対象アプリ
CommSimセンサスタブ(9500)

通信フロー

Read 要求(Type=0x01)に対し、値 100 を載せた Read 応答(Type=0x81)を返します。

  • Client →Read 要求 AA 55 01 01 00 B0 B9Type=01 / ch0
  • ← CommSimRead 応答 AA 55 81 02 00 64 B6 91値 100 + CRC 自動

フレーム内訳

要求例 AA 55 01 01 00 B0 B9 の解釈:

AA 55    : STX(固定スタートバイト)
01       : Type(0x01 = Read)
01       : Length(Payload バイト数)
00       : Payload(チャンネル 0)
B0 B9    : CRC-16/CCITT(先頭からの計算値)

想定プロトコル

先頭 STX に続き、Type・Length・可変 Payload・末尾 CRC。Length は Payload のバイト数を示します。

AA 55STX 2B Type1B 判別 Length1B Payload可変 CRC162B CCITT
フィールド型 / 役割備考
Stxu16固定 0xAA55
Typeu8 / 判別1=Read / 129(0x81)=ReadResponse
Lengthu8 / 長さPayload のバイト数
PayloadhexLength の値だけ読む(可変長)
Crcu16 / チェックサムCRC-16/CCITT(先頭から)

使用する機能

メッセージ構造定義

可変長 Payload(長さ元)・長さ補正・Crc 役割

バイナリ構造応答

{crc:Crc16Ccitt} で CRC を自動付与

設定内容

プロジェクト設定

既定データ形式RawHex(バイナリ HEX)
エンディアンBig
フレーミング方式長さ前置(LengthPrefixed)
共通ヘッダ長 / 長さ ofs / size4B / 3 / 1
長さ基準 / 補正ボディ長 / +2(末尾 CRC 2 バイト分)
長さ補正 +2 は、Length が「Payload のバイト数」を示すのに対し、フレーム末尾に CRC(2 バイト)が付くため、実受信バイト数が Length + 2 になるのを補正しています。ヘッダ/トレーラを持つ独自プロトコルでも、この補正で正しく切り出せます。

構造体定義(Sensor Request)

フィールド名役割備考
Stxu16なし固定値 0xAA55
Typeu8判別1 = Read / 129 = ReadResponse
Lengthu8長さPayload のバイト数
PayloadhexなしLength フィールドの値だけ読む(可変長)
Crcu16チェックサムCRC-16/CCITT(先頭バイトから計算)

バイナリ構造応答

ルール条件応答テンプレート(HEX)
Read(0x01) → 値100 応答(0x81)なし(1 種類)AA 55 81 02 00 64 {crc:Crc16Ccitt}

応答の値(ここでは 100)を変えても、{crc:Crc16Ccitt} が先頭から直前までを自動計算して末尾に付与するため、CRC を手計算する必要はありません。

設定の考え方

設定なぜそうするか
長さ補正 +2Length フィールドが「Payload のバイト数だけ」を示す一方、フレーム末尾に CRC(2 バイト)が付くため。長さフィールドの値と実際の残りバイト数がずれる場合は、長さ補正でその差を吸収する。
Payload を可変長(Length フィールドを長さ元に指定)にするチャンネル数などで Payload 長が変わるプロトコルを 1 つの定義で扱うため。固定長にすると長さ違いのメッセージで分解が崩れる。
応答テンプレートで {crc:Crc16Ccitt} を使う応答の値を変えても CRC を手計算せずに済むから。テンプレートが先頭から直前までを自動計算して末尾に付与する。
構造体ルールを条件なし 1 本にするRead 要求 1 種類 → 固定の値応答なので、フィールド条件で分岐する必要がないため。
開き方:samples/sensor-proto/sensor-proto.commsim を「ファイル」→「ファイルから開く…」(Ctrl+O)。起動後、Read 要求 AA 55 01 01 00 B0 B9 を送ると応答が返ります。

動作確認手順

  1. CommSim で samples/sensor-proto/sensor-proto.commsim を開く(メニューバー「ファイル」→「ファイルから開く…」)。
  2. セッション「センサプロトコル スタブ」の「起動」ボタンをクリックし、待ち受け状態にする。
  3. クライアントから Read 要求 AA 55 01 01 00 B0 B9 を送る(CommSim.Sample のシナリオ「センサ」の「デモ送信」でも可)。
  4. ログペインに受信(Rx)が表示され、フィールド分解(Stx・Type・Length・Payload・Crc)が確認できる。
  5. 同タブに送信(Tx)として AA 55 81 02 00 64 B6 91 が表示される。
HEX を手入力する場合は、送信欄でデータ形式を「RawHex」に設定してから入力してください。

実行ログサンプル

Rx  AA 55 01 01 00 B0 B9
      [Stx=0xAA55] [Type=1(Read)] [Length=1] [Payload=00] [Crc=0xB0B9]
Tx  AA 55 81 02 00 64 B6 91
このサンプルには採取ログ logs/sample-sensor-proto.commsimlog を同梱しています。メニュー「ツール」→「ログビュワーを開く…」で開くと、上記のやり取りを実セッションのログとして確認できます。

← サンプル一覧に戻る