読者です 読者をやめる 読者になる 読者になる

ZigBeeによるセンサネットワークを作った時のメモ

ZigBeeで複数台のモジュールから高頻度に情報を送信するネットワークを作ったので、その時のノウハウをまとめる。ZigBeeのやりとりにはXBee ZBシリーズを利用。2.4GHzのZigBeeを利用するXBeeモジュール。主要各国の規制をクリアしているのでグローバルに安心して使える。

概要

通信するモジュールは全8台でPCに繋がる受信機を2台用意し、1:4を2セット配置した。当初は1:8だったのだが、XBeeがネットワークから離脱することが多かったためにそのような仕様に。受信機はXBee-PRO ZB。送信側のモジュールはXBee ZBを利用。

[asin:B011URI6F2:detail]

通信の仕様としては、100msに1度加速度センサと現在の電圧の情報をモジュールから受信機側に送る。1回あたり24Byteになってた。このうちデータは加速度センサのXYZそれぞれが1Byteずつと電圧の1Byteの4Byteである。

モジュール側

モジュール側はXBeeとセンサ、Arudinoから構成されている。Arduinoがセンサ情報を読み取り、XBeeAPIモードでXBeeに送信要求を送る、のが基本の動作。
XBee側の設定はファームウェアはRouter APIで、その他の特徴的な設定はNW=1、JV=1で、ネットワークがなかったら再接続し、その際は全チャンネルをスキャンするという設定。明示的に設定しないとチャンネル変更されても他チャンネルをスキャンしないので。

ArduinoXBeeのやりとりにはxbee-arduinoライブラリを利用した。自分でバイトを作ったりしなくてよくなり、かなり実装は楽に。オススメ。google codeからgithub移行してるんだけど、ドキュメントがまだgoogle codeに残っているので、どちらのリンクも置いておく。
https://code.google.com/p/xbee-arduino/
https://github.com/andrewrapp/xbee-arduino

ArduinoからXBeeへは、

  1. データの送信リクエスト TxRequest
  2. 電圧のリクエスト
  3. ネットワークの接続状況のリクエスト

の3種類をシリアル通信で送っている。XBeeからArduinoへはそれぞれのリクエストに対するレスポンスが3種類返ってくる。
また、ArduinoからXBeeへはリセット端子を接続していて、3のレスポンスから、ネットワークが接続されずに一定時間経過した時、強制的にリセットをかけている。シリアル通信からコマンドでXBeeに対しソフトウェアリセットをかけることは出来るのだが、意図した動作にならなかった(再接続されなかった)ので、ハードウェアリセットをかけている。

受信機側

XBeeファームウェアはCoordinator API。PCとの接続は秋月の「XBee USBインターフェースボードキット」を利用してUSBでつなげている。このキットは普通にXBeeの開発に便利で重宝した。安いし。
XBee USBインターフェースボードキット: 組立キット 秋月電子通商 電子部品 ネット通販
PC側でのXBeeとのやりとりは、openFrameworksで実装した。oFにはXBeeのライブラリとかなかったので、自分でAPIモードのXBeeとシリアルでやりとりするコードを書いた。実はこのときに書いた記事がこれ。しょっちゅうフリーズさせていたので……。
miso-engine.hatenablog.com
XBeeからPCに来るデータは1種類のみで、「ZigBee受信パケット」というものだ。これにはデータそのものと、送信元ZigBeeの全世界的にユニークな64bitのアドレスがあるので、どのセンサからのデータなのかがわかるという仕組み。この複数台のセンサの情報をどう管理するかというところで色々大変だったが、一般化出来るノウハウという感じでもないので割愛。

その他ノウハウ・注意点

1. 高頻度なデータのやり取りにはRouterを使う

ZigBee規格ではそれぞれのZigBeeはCoordinator, Router, End Deviceの3つの役割のどれかを担う。このうちCoordinatorはネットワークに1台は必ず必要なネットワークを構成する親機になる。残りのRouterとEnd Deviceがそこにぶら下がるのだが、この2つの違いはEnd Deviceがいずれかの1台のRouterかCoordinatorに対して繋がる形でネットワークに参加するのに対し、Routerは他の複数台のRouterと繋がりネットワーク自体を作っていく存在であることだ。
今回の用途ではメッシュネットワークはいらないので子機側はEnd Deviceにしてネットワークを作ってみたところ、ことXBeeに関してはEnd Deviceは完全にスリープして使うことが前提*1のようであり、スリープしない状態のEnd Deviceを複数台をネットワークに入れて使うとネットワークの安定性が著しく悪かった。そこで単純にEnd DeviceをRouterにしたところ、ものすごく改善した。つまり、スリープさせる必要がない高頻度なデータのやり取りではRouterを使うべきであるようだ。

2. ネットワークの安定性の改善

2-1. ネットワークの参加要求

「ネットワークの参加要求」はZigBeeネットワークに対して高負荷のようであり、これが出されたタイミングでネットワークが不安定化することが多かった。ネットワークから外れたモジュールは今回のやり方では再接続を試みる。その結果さらにネットワークが不安定化し全体としていつまでたっても安定しない、というようなことも起きた。ネットワークから落ちたらすぐ復帰してほしかったので、1:8から1:4にすることで対策したが、すぐ復帰しなくてもよいなら再接続までのタイミングを長く取るなどの対策もあるかと。

2-2. チャンネルの混雑

ネットワークから離脱するのはチャンネルが混んでいる時のようでWi-Spyという製品を使って電波状況を監視してチャンネルを変えたりした。チャンネルの変更は受信機側(1:4の1側)のモジュールのチャンネルに関するビットマスクの設定を変えることで可能。

3. XBeeのリセット

ピンによるハードウェアリセット、コマンドからのソフトウェアリセット、ネットワークリセット(そのモジュールのみと、ネットワーク全体の2種類がある)と様々なリセットがあるので、自分の意図した状態を作れるのがどのリセットか見極めて実装する必要があった。

4. 秋月のXBeeピッチ変換基板

最終的には使ってないのだが、モジュール側のプロトタイプで秋月のXBeeピッチ変換基板を使っていたが、電圧レギュレータが内蔵されているため、3.3Vをそのまま電源のところに入れると少し低い電圧になることに注意。
XBee用2.54mmピッチ変換基板: 半導体 秋月電子通商 電子部品 ネット通販

検証していないこと

1. 800MHz帯のモジュール

2.4GHz帯はやはり混んでおり、チャンネルの変更が必要になった。最初から混んでない帯域をできれば使いたい。

2. ZigBeeではないXBee

今回の用途においてメッシュネットワークは不必要だったので、ツリー型のネットワークを構成可能なZigBeeではない独自プロトコルに対応したXBeeにするべきだったかもしれない。ZigBeeにおいてツリー型のネットワークは出来ると書いてあったが、XBeeではいかんせん明示的に作る方法がわからなかった。

本について

オライリーCQ出版から出ている。どちらも買った。

XBeeで作るワイヤレスセンサーネットワーク (Make: PROJECTS)

XBeeで作るワイヤレスセンサーネットワーク (Make: PROJECTS)

初心者はオライリーの方をざーっと読むとよい。1冊の本を通して仕様を理解していくという形になっているためわかりやすい。シリアル通信におけるプロトコルなどを丁寧に解説していて助かった。
CQ出版の方はやはりトランジスタ技術誌の読者層向けなのでレベルが高い。チュートリアル的な記事もあるが、電波状況に関する話や到達距離の検証の記事等は役に立った。ただ、Digi社が出しているマニュアルの翻訳的な内容も多く、マニュアルのほうが公式なので信頼性がおけると考えると買う必要あるのだろうかという面も。
また、この2冊は方向性は違うものの被っている内容は多く、2冊とも買う必要性は薄い。

その他リソース

XBeeのDigi社によるマニュアル「Product Manual: XBee / XBee-PRO ZB modules」。日本語のページからだと辿りつけないんだよね。
http://www.digi.com/products/xbee-rf-solutions/modules/xbee-zigbee#resources
ZigBeeXBeeについてガガッと概要を知りたいならここ。ググると1番上に出てくる。
ボクにもわかるZigBee方式 XBee (ボクにもわかる地上デジタル 地デジ方式編)

*1:設定もスリープしない設定がない。ただ、これはポートによるスリープの制御を選ぶとスリープさせないことが可能で、今回はそれでスリープさせなかった