Arduino + XBeeシールド + XBee で勝手にリセット

Arduino + XBee ZB S2C で遊んでて、時々勝手に Arduino がリセットするので何故だ、ということで。

結論を先に書くと、XBee のハードフロー制御動作と XBee シールドの回路の影響で、フロー制御がかかるとリセットしますよというお話。


環境は

状況としては、こちら(XBeeのリセットとXBee shieldの回路について - Arduinoを使い倒すページ)と似てるけれども、 XBee のリセットにつられて Arduino が落ちるのではなく、データをガンガン送信してる最中に突然 Arduino が再起動するという感じ。

先人の話があるので、シールドの回路図(DFR0015)を調べると、XBee 12番ピンの DIO7/~CTSトランジスタを介して Arduino 側のリセット信号線に繋がっている状態。

となると、 DIO7/~CTS がなにかのはずみで HIGH になっている模様。
XBee のピン設定で DIO7 がどうなっていたかを確認すると、「CTS flow control [1]」になっている状態 (XBee AT D7 コマンド参照。ちなみにデフォルト値)。

つまり、起きている事象としては

  1. ArduinoXBee にがんがん送る
  2. XBee の送信バッファがいっぱい
  3. XBee はフロー制御をかけようと CTS 信号を落とす
  4. 負論理なので12番ピンがHIGHに
  5. Arduino にリセット信号どーん。再起動〜

ということな模様。なるほど、「R3 外せ」ってそういうことね。
スイッチかジャンパピンになっていればいいのにねーとか思いつつ。

XBee はハードフロー制御しか対応していないので、真面目に対応しようと思うと、

  • R3 外す
  • XBee 12番ピンを Arduino の適当な Din に繋ぐ
  • Arduino のソフト側でその Din が Low なのを確認しつつ送信するように対応する

という改造が必要そう。


秋月電子で扱っているもう一つのXBeeシールドArduino公式版)のほうは、回路図を見る分にはCTSArduino側に繋がっていないのでこの問題は起きないはず。
DFRobotのシールドでも、XBeeの設定を変更して DIO7 を Disable か Low 固定にすれば大丈夫かと。

ただし、フロー制御が一切無いのでがんがん送ったときに何がおきるか、という危険性はありますが。
(いや、ちゃんと 0x8B Transmit Status 確認しながら送信すればソフトフロー制御相当か?はっ、自分の実装がクソというオチ!?)