通信を扱うプログラムは、通信エラーが「当然に起こる」ことを前提に設計するものです。
「たまたま動く」ことを頼りにしてはいけません。ノイズで1バイト欠落したり、余計な1バイトが受信できてしまったとして、その回は仕方がないとしても以降のデータでは復帰できるように、何らかの方法(あなたがよいと思う方法)で、3つのデータが弁別できるようにするべきでしょう。
本題から若干はずれますが(関係なくはない)、
if ( port.available() > 11 ) {
for ( i = 0; i < 3; i++ ) {
data[i] = port.read() + port.read() * 256 ;
}
なぜ12バイト以上のデータの受信を確認したあとで6バイトの受信を行う仕組みになっているのですか?
自己解決にするとのことですがまぁとっかかりだけでも。
D0L D0H D1L D1H D2L D2H D0L D0H D1L D1H ...
とダラダラ並んでいるだけのデータ列では、取りこぼしがあって例えばD0Hが抜けたときに受信側が
(D0L D1L) (D1H D2L) (D2H D0L)
のようなペアで解釈してしまうとデータは滅茶苦茶になって自力では復帰できません。
あるいは、たまたま受信を開始したのが途中からで
D2L D2H D0L D0H D1L D1H ...
と受信していれば、受信側はD0のつもりでD2を(以下順次ズレて再起不能)得てしまうことになります。
要は、通信データ列(だけ)を見てどれが1つ目、2つ目、3つ目のデータか認識できるように考えれば(送受信間の通信の約束=プロトコルを決めれば)いいわけです。
データ間隔が大きく空いているなら、
D0L D0H D1L D1H D2L D2H [間隔]
の間隔時間を測ることによってデータの区切りを知ることができますが、今回は64Hz=15ms周期とのことで、Processingのdraw()繰り返し実行のデフォルト周期(60Hz)との絡みもあって検出は難しいですね
となると、データ列に「位置を知るための特殊なデータ」を埋め込むことで位置を知るという方法が考えられるでしょう。テキストデータであれば、データ本体には登場しない改行コードであるとか','とかをデータ区切りに使うというのはよくあるパターンではありますが、今回はバイナリデータなのでちょっと考える必要があります。
Arduino UNO(ただArudinoとだけいう名前の機種はありません。原則としてArduinoのナニなのかを明示するようにしてください)のADCは10bitですから、高位側のデータは(特に加工していなければ)4以上にはなりません。つまり、4以上のデータが2つ続けば「それは特殊なデータだ」と知ることができるわけです。
例えば、
0xff 0xff D0L D0H D1L D1H D2L D2H
というのが一組のデータという規則にすれば、4以下(前回のD2H)、0xff, 0xffというデータ並びを見つければその次がD0Lという期待はまぁ正当でしょう(単純に0xff 0xffの並びだけを探してしまうと、D0Lが0xffになる可能性があるので誤検出が考えられます)。9600bpsで1byteの伝送に1msかかるとして、64Hz=15.6ms周期に8byte=8msのデータ量ですから収まります。
Processing
1//D0Lの頭出しをするループ(動作チェック等はしていません)
2byte head0,head1;
3boolean found_FF=false;
4head0=0;//仮データ
5while(true){
6 if(port.available()){
7 head1=port.read();//2byte目受信
8 if(found_FF && head1=0xff){ //D2L,0xff,0xffのパターンを見つけた。次はD0L
9 break;
10 }
11 found_FF=(head0<4 && head1==0xff);//4以下-0xffのシーケンス発見
12 head0=head1;//今回の2byte目は次回シーケンスの1byte目
13 }
14}
15//頭出しができているので安心して取得
16if(port.available()>=6){
17 for ( i = 0; i < 3; i++ ) {
18 data[i] = port.read() + port.read() * 256 ;
19 }
20}
のように処理すれば、何らかのズレが発生したときにも次回には修正されることになるかと思いますがいかが。(もちろん送信側にも0xff 0xffを送る処理を追加する必要があります)
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/12/23 12:40
2021/12/23 23:55