【送信エラー時のリトライ手法】
リトライの処理方法は色々、トライ&エラーで確かめながら、最も衝突時の回避率の高かった設定を選択した。具体的には、送信側でパケットデータを送る際に衝突等で送信エラーが発生した際、乱数に従った時間を待って、リトライすることにより、【長い時間衝突し続ける】事を割けることを試みた。そのリトライを効率的にするために、serRetries関数への設定は、短い時間間隔で一回だけリトライする形にとどめた。(250us x 1回のみ)。乱数によるリトライは、もっと長い時間(1msec~10msec)待った後で行う形にして、最大10回トライしている。
色々試してみたが、やはり4台以上の送信機を非同期で動作させ続けた場合、衝突によるものと思われる送信エラーは皆無にはなっていない。更なる検証と回避策を立てる必要があるが、とりあえずペンディングとしておく。後日、再検討したい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
// // send RF packetdata to the host, display error on LCD if failed void send_packet(char c) { // int before, after; // before = millis(); uint8_t retry_cnt = 0; bool ok = false; radio.stopListening();// First, stop listening before writing data do { ok = radio.write( &txd8, sizeof(PAYLOAD_8)); // no retries in the function delay (random(1, 10)); // longer wait, since reties in the function is maximum 4msec retry_cnt ++; } while ((ok == false) && (retry_cnt < 10)); if (ok == false) { error_cnt ++; lcd.setCursor(4, 1); //lcd.print(c); lcd.print("NG"); lcd.print(error_cnt); } else { // lcd.setCursor(3, 1); lcd.print(c); lcd.print(" ");//lcd.print(retry_cnt); } radio.startListening(); // after = millis(); // Serial.println(after - before); } |
【実験の様子】
3台の送信機に、Arduino Unoからそれぞれランダムなパルスを送り、そのカウント数と温度情報を送信している時の様子。(右上の一台は、ユニバーサル基板を使ったプロトタイプ)