必要な機能と必要なエラーチェックの量に応じて、シリアルプロトコルを記述する方法は多数あります。
ポイントツーポイントプロトコルでよく見られるもののいくつかは次のとおりです。
メッセージの終わり
最も単純なASCIIプロトコルは、多くの場合、\r
または\n
Enterキーが押されたときに印刷されるものであるため、メッセージ文字列の終わりを持っています。バイナリプロトコルは0x03
、他の一般的なバイトを使用する場合があります。
メッセージの始まり
メッセージの終わりを持っているだけの問題は、メッセージを送信するときにすでに他のどのバイトが受信されているかわからないことです。これらのバイトはメッセージの前に付加され、誤って解釈されます。たとえば、Arduinoがスリープから復帰したばかりの場合、シリアルバッファにゴミが残っている可能性があります。これを回避するには、メッセージシーケンスを開始します。あなたの例では^
、しばしばバイナリプロトコルで0x02
エラーチェック
メッセージが破損する可能性がある場合は、エラーチェックが必要です。これは、チェックサムまたはCRCエラーなどです。
エスケープ文字
チェックサムが「メッセージの開始」または「メッセージの終了」バイトなどの制御文字に追加されたり、メッセージに制御文字に等しい値が含まれたりする可能性があります。解決策は、エスケープ文字を導入することです。エスケープ文字は、実際の制御文字が存在しないように、変更された制御文字の前に配置されます。たとえば、開始文字が0x02の場合、エスケープ文字0x10を使用して、メッセージの値 0x02をバイトペア0x10 0x12(バイトXOR制御文字)として送信できます。
パケット番号
メッセージが破損している場合、nackで再送信を要求するか、メッセージを再試行できますが、複数のメッセージが送信されている場合は、最新のメッセージのみを再送信できます。代わりに、特定の数のメッセージの後にロールオーバーする番号をパケットに与えることができます。たとえば、この番号が16の場合、送信デバイスは送信された最後の16個のメッセージを保存でき、破損している場合、受信デバイスはパケット番号を使用して再送信を要求できます。
長さ
多くの場合、バイナリプロトコルでは、受信デバイスにメッセージ内の文字数を伝える長さバイトが表示されます。これにより、正しいバイト数が受信されなかった場合にエラーが発生したかのように、別のレベルのエラーチェックが追加されます。
Arduino固有
Arduinoのプロトコルを考え出すとき、最初の考慮事項は、通信チャネルの信頼性です。ほとんどのワイヤレスメディア、XBee、WiFiなどで送信する場合、エラーチェックと再試行が既に組み込まれているため、これらをプロトコルに入れる意味はありません。RS422で数キロメートル送信する場合は、必要になります。私が含めるものは、あなたが持っているように、メッセージの始まりとメッセージの終わりの文字です。私の典型的な実装は次のようになります。
>messageType,data1,data2,…,dataN\n
データ部分をコンマで区切ると、解析が容易になり、メッセージはASCIIを使用して送信されます。ASCIIプロトコルは、シリアルモニターにメッセージを入力できるため便利です。
バイナリプロトコルが必要な場合、おそらくメッセージサイズを短くするために、データバイトが制御バイトと同じになる可能性がある場合は、エスケープを実装する必要があります。バイナリ制御文字は、エラーチェックと再試行の全範囲が必要なシステムに適しています。必要に応じて、ペイロードはASCIIのままにすることができます。