質問: makeWord(high,low); // 上位バイトと下位バイトを合体させてint型データを復元 if( recv_data <10 && counter!=3)Serial.print(0); if(counter!=3){ Serial.print(recv_data); } } counter++; //Serial.print(counter); switch(counter){ case 1: Serial.print("."); break; case 2: Serial.print("."); break; case 3: Serial.print(", "); break; case 4: if(recv_data==0)Serial.print("Sun"); if(recv_data==1)Serial.print("Mon"); if(recv_data==2)Serial.print("Tue"); if(recv_data==3)Serial.print("Wed"); if(recv_data==4)Serial.print("Thu"); if(recv_data==5)Serial.print("Fri"); if(recv_data==6)Serial.print("Sat"); Serial.println(""); break; case 5: Serial.print(":"); break; case 6: Serial.print(":"); break; case 7: Serial.println(""); break; } if(counter==7){ counter=0; } } ``` ### 補足情報(言語/FW/ツール等のバージョンなど) Arduino IDE 1.8.0 Arduino M0 Pro Arduino NANO
回答: こんにちは。 質問の内容が書かれていないので、ソースは呼んでいません。 タイトルから「シリアル通信のデータの先頭をどうやって判別すればよいのか?」だろうと推測して回答してみます。外してたらごめんなさい。 実はこの問題は結構難しいです。恐らくざっくり2種類しかないと思います。 1. タイムアウト パケットは必ず連続して送信し、一定時間以上データを受信できない時に内部カウンタをクリアします。クリア後に届いた最初のデータが先頭です。 シリアル通信では、何かエラーが発生した場合に備えてタイムアウトの実装がほぼ必須ですから新たにロジックを追加しなければならないケースは少ないです。 2. 特殊コード ペイロード内に記録しないコードを決めます。バケット先頭にそのようなコードの一つを割り当てます。 例えば、よく使われるベーシック手順はこの方式です。 この方式はタイムアウトに頼らない点で優れています。ペイロードに使えない値を伝送できるようにするため、それなりの工夫(エスケープするなど)で高速化することもできます。 【追記】 回答を書いている間に質問の内容が書かれてました。フライングしてしまった。すいません。 【質問を読み直して】 ソースもざっとみました。バイナリー・データを送っているので、先に書いた「2. 特殊コード」方式を使うのは難しいですね。かと言って「1. タイムアウト」もタイマの制御が必要になるのでやはり難しいてす。 バイナリー・データを送らないように改造するのが、恐らく簡単です。 今はint型を2バイトでそのまま送っていますが、例えば4ビットづつを8ビットへ拡張して4バイトで送ることが考えられます。4ビットの値が10未満ならオフセット0x30を加え、10以上ならオフセット0x41を加えるとASCIIコードでの16進数表現になります。そして、それを受信側でデコードすることがかのうです。 このような工夫をして送受信することで、例えばベーシック手順のSYNコードなどをペイロード中に発生しないようにします。 そして、送信側はパケット先頭にSYNコードを付加して送り、受信側はSYNコードを受信できるまでデータを1バイトづつ破棄することが考えられます。