■リモート制御の電源タップ、1号機を作ってしばらく運用していたのだけど、2号機のテストをしているうちに閉塞してしまうようになった。1号機のファームウェアが複数デバイスとの通信が行きかうメッシュネットワーク内での動作に対応しきれていないということもあるし、ハードウェアがフィールド運用の中での状況に対応しきれていないということもあると思う。
テストしていて気付いたのはエンドデバイスからの送信の不安定さだった。エンドデバイスからコーディネーターへのPAN参加はできているし、コーディネーターからのブロードキャストも受信できているけど、エンドデバイスからコーディネータへの送信がなかなかできない。PAN参加後にしばらく待たないとエンドデバイスからコーディネーターへの送信が受け付けられず、XBee-ZBモジュールが閉塞してしまうようなのだけど詳細は不明。XBeeからAVRへ送信される信号をUSB-UARTデバイスを経由してフェッチしてみると、キャラクタコードの先頭ビットが常に1で、そのあとに本来のデータを読み込んでいる様子。どうもスタートビットを読み出してしまい、フレームエラーを発生させているらしいのだけど、理由がわからない。
AVRとXBeeを結ぶために取り回しているUARTの送受信線をプルアップしたけれど状況はあまり変わらず。CSTのフローコントロールを有効にしても意味がなく、ただ、コーディネーターからの送信に対する応答が、デバイス起動後しばらくすると有効になり、比較的安定することがわかったのでハードウェアの改修はとりあえず一段落ついたと判断した。結局プルアップしただけですけど。環境ノイズで異常動作していたと考えるしかない。
ファームウェアの方はコマンド受信ルーチンを改良。XBee-ZBのメッシュネットワーク環境下では送信データが途中で途切れることが多い。コマンド文字列の終端は0x0dと決めたのだけど、終端が出てこないとデバイスは永遠に受信待ちとなって閉塞しかねない。そこでデバイス側で受信待ちの制限時間を設けて自発的にコマンド受信を打ち切るようにした。
世間的には単に「タイムアウトを設定した」というだけですが。
ただ、タイムアウト設定で問題になるのは、コマンド送信途中で発生する遅延に弱いことで、タイムアウト判定後に続きのコマンドを読み込んでしまい、次に受信するコマンドの前に前回送信したコマンドの後半がゴミのように残ることになる。そうならないようにロジックを直した。
コマンド送信側も工夫が必要でした。コマンド送信-受信のサイクルを間断なく続けるとタイムアウトが発生しやすくなるようなので、連続操作時には送信-受信シーケンスの後に1秒ウェイトを入れると安定して通信が持続するようです。