« 2011年3月20日 - 2011年3月26日 | トップページ | 2011年4月3日 - 2011年4月9日 »

2011年3月27日 - 2011年4月2日の1件の記事

2011年3月30日 (水)

Xbee ZB APIモード汎用モニターのソース公開

 遂にXbeeのAPIモードを使ったリモートATコマンドが動いた。親機から送ったコマンドがリモートの子機に伝えられて子機のLEDが点いたり消えたりする。これでラジコンのための機能は実現した。いやあ今度も最後の一歩が長かった。ローカルのATコマンドが動いてから、リモートを動かすまでに3日もかかっている。

P3303742

やっとのことでリモートATコマンド稼動(3/24/2011)
 リモートATコマンドが動かなかった原因は、今度もわかってしまえば何でもないところだった。親機(マイコンにつけたコーディネーター側のXbee)ではAPIフレームに入れたコマンドが動き、続いてパラメーターの入力の開発にとりかかったころ、戯れにX-CTUでリモートコンフィギュレーションの画面を出してみたら、何と子機のアドレスが画面に現れ、パラメーターの読み書きが出来るようになっているではないか。

 これはXbeeのAPIモードでのリモート環境が正常に動いていることを示している。リモートATコマンドが動かないのは、みなこちらのせいだ。原因究明に力が入る。しかしAPIフレームのフォーマットをいくら調べてみても間違っていない。アドレスは何度見ても正しい。無線なので、中のデータを覗くわけにも行かない。これ以上調べるところがない。

 ただ、気になっていることがひとつある。親子に同一の2バイトのPAN(Personal Area Network)ネットワークアドレスを指定しても、返ってくるレスポンスデータには、必ず0xFFFEというブロードキャストアドレスが所定のエリアに載っている。

 無印のXbeeとXbeeZBでは、このあたりのアドレスの取り扱いが大きく変わっており、マニュアルを読み込んでいないので自信はないが、どうもこの2バイトアドレスは、ネットワークがつながる度にダイナミックに決まっているような感じである。ただしX-CTUでは任意に初期設定ができる。

 だめもとで、送信APIフレームのネットワークアドレスの欄を、返ってきた値と同じ、0xFFFEにして動かしてみた。やったー、ビンゴ!である。リモートにコマンドが届き、レスポンスがNo Errorで戻ってきた。

 やっぱり、おかしい、おかしいと思っていたこの2バイトアドレスが張本人だった。もういちど丁寧にマニュアルを読み込む。ZBでのこのアドレスは、無印Xbeeのときのような所定のPANアドレス(PANID)ではなく、ネットワークが確立する度に、コーディネーター(親)がエンドディバイス(子)に対して振り直すようだ。

 それを無視して一定のPANIDでアクセスしても子供は見つからないと言うことか。そう言えば、ログを調べているうち、一回だけ動いていたのを見つけたことがある。これは最初の通信だったからだろうか? それならどうして指定することが出来る。わけがわからない。

 それはとにかく、今のところ本気でXbeeのネットワークを組む気はないので、とりあえず親機でネットワークアドレスを0xFFFEにしておけば、万事解決である。動けばそれで良い。いやいや、久しぶりに解決したときの爽快感を味わう。体の動きが軽い。

リモートのI/Oピンを動かすのに成功!(3/25/2011)
 興奮が納まって次の課題に取り組む。実は、まだ当面の目的に達していない。動いたのはコマンド問い合わせ(query)だけで、コマンドのあとにパラメーターを指定してデジタルピンなどを動かす設定(modify)機能が動いていない。パラメーター指定はUARTからなのでキャラクターを、APIフレームのためにバイナリに換えなければいけない。

 さらにソフト開発を続ける。これが結構難しい。APIフレームのデータレイアウトはアライメントが無視されているので、4バイトバイナリーなどはうっかり使えない。1バイトづつの処理が必要だ。アスキー文字の16進表示を実際のバイナリデータにするのは、1対2でデータをずらしていかなければならない。簡単には行かない(1バイトのデータを得るのに、2バイト分のキャラクターが必要)。

P3303744

 これで良いと思ってテストしても想定したバイナリが入らず、Invalid Parameterのエラーメッセージではねられる。意地になって、久しぶりのコーディングに夢中になる。手当たり次第にprintfで途中経過を表示させながら、何とかATコマンドの後についた16進数キャラクターをパラメーターのバイナリーにするロジックが完成した(出力側のAPIフレームのパラメーターエリアを固定にして最後からデータを入れていくのがミソだった)。

 パラメーター入力はコーディネーター(親機)の方では正常に動いた。次はいよいよリモートだ。あせる手でエンドディバイス(子機)のXbeeのブレッドボードにLEDをデジタルピンD1につけ、PCに戻って親機の方から子機にデジタルピンを上下するコマンド、ATD14(D1ピンをOFF(4)にする)を入れる。点いた!(LEDをVccにつないでいるので負論理) やった、やった。今度は、ATD13(ON)。消えた。けなげに点いたり消えたりするLEDがいとおしい。撫でてやりたい。よしよし、これでXbeeだけでラジコンを動かす機能は実現した。完成まであともう少しである。

100ミリ秒で制御できれば何とか使えるか(3/26/2011)
 ただ喜んでいるわけにはいかない。LEDの点灯や、消灯は、コマンドを入れて一瞬とは行かず、ほんの少しだが一呼吸おいて動作する。どれくらい遅れているのだろう。ラジコンが動かせるくらいの早さでON/OFFが出来ているのだろうか。 

P3243737

 オシロで時間を測ってみることにする。2現象でPCからマイコンに行くUARTと、マイコンからコーディネーターXbeeに行くUARTの2箇所と、実際のエンドディバイスのXbeeのLEDのON/OFFの間を比較する。PCを起点とするUARTからでは200ms、マイコンからXbeeへのUARTからなら50~100msでピンの制御ができることがわかった。思ったより早い。

 ラジコンのコントロールはタクトスイッチでやるとするなら、PCからのUARTの早さでなく、マイコンからXbeeへのUARTの早さでコントロールできるだろう。100ms以内で動きそうだ。車程度ならそう遅れを感じずに制御できるだろう。

 それにしてもAPIモードは難しい。分からない単語が頻発する。もともと省電力化した複雑なネットワークを意識しているので、盛りだくさんの機能がついている。エンドディバイスもデフォルトで、スリープモードに入るようになっている(制御が始まれば暫く動いているが)。今のところラジコンだけが目的なので、当面このあたりは関係ない。

P3243738

 マニュアルを読んでいると、あまり詳しく設定しなくても、エンドディバイスを兼ねたルーターをいくつも介して、遠方にいるXbeeとメッセージ交換ができるようで興味をそそられるが、暫くはお預けにする。

 こういう性格なので、いちどのめりこむと元へ戻るのに時間がかかる。だいたいXbeeだってモーター制御をやろうとして、ラジコン制御に気が移り、寄り道した完全な道草だ。それよりAPIモードのモニターの完成度をもう少し高めようと思う。今のままではとても人さまに使ってもらえる状態ではない。

汎用的なAPIモニターの制作へ(3/27/2011)
 汎用的なとは言ったものの、現在のプログラムは、PCにつなぐUARTは、ChaNさんのシリアルISPプログラムライターのケーブルを利用した特殊なUARTだし、子機のアドレスはプログラム決めうちでコンパイルしなければ変更できない。とても汎用的とは言えない。

 しかし、ウェブを見ているとXbeeのAPIモードでの取り扱いはみな苦労している。頼りのユーティリティX-CTUはAPIモードになってしまうとコマンドはいちいちフレームを作らないと動かせないからだ。

 X-CTUでは、パラメーターの設定はリモートまで出来るが、ファームに全部の設定をバッチジョブ的に書きこむだけで、ATモードのときのように適当なコマンドを入れて確かめたり、設定を臨時に変えたりすることは出来ない。

 これに対して、今のプログラムは、少なくともコーディネーター配下につながる全てのAPIモードのXbeeに対し、任意のコマンドとメッセージを送ることができる。アドレスをプログラムで換えられるようにするなど、あともう少し機能を追加すれば、みんなの役に立つツールになるのではないかと考えた。道草ついでに少し時間をかけてみることにする。

 そこで、まずAPIモードのもうひとつの方法、Escapeモード(ATAP=2)も実装することにする。今度のラジコンには関係ないが、アナログセンサーなどにXbeeをAPIモードで使うときは、普通のAPIモードでは実用的ではない。フレームのヘッダー文字0x7Eがデータの中に現れたら、そのフレームは目茶目茶になる。 

まあ、APIフレームにはデータレングスがあるので、すべてのソフトが注意深く作られていれば問題ないはずだが、ちゃんと守らない奴が中継する経路のどこかに居るとデータの保全は保証されない。エスケープしておくことに越したことはない。

 この実装は、思ったより簡単に出来た。1バイト送受信の一番フロントにロジックを入れてやれば良い。あとは変更する必要がない。エスケープする文字は、ヘッダーの0x7Eだけでなく、エスケープ文字そのもの0x7Dと、シリアルのフロー制御文字XON(0x11)、XOFF(0x13)まで必要とマニュアルにはある。いまどき、XON、XOFFでフロー制御しているところもなさそうだが、言われるまま全部エスケープする。勢いに乗って、APIモードも動作中に切り替えられるようにする。

 ソフトが出来たのでテストである。まずXbeeの双方をX-CTUでAPIのEscape付きモードに変更する。ビクビクしてX-CTUを動かしたのだが、2ヶともファーム復活をさせられることもなく、writeだけで問題なくEscapeモードになった。だいぶX-CTUの動かし方にも慣れてきたようだ。Escapeモードでも問題なく動いた。よーし、これで一歩、完成に近づいた。すべてキャラクターベースのインターフェース(CUI)だが、あとは64ビットアドレスの入力だ。

Xbee329

汎用モニターひととおり完成(3/28/2011)
 EEPROMにリモートの64ビットアドレスを収容し、プログラムをコンパイルし直さないで、コマンドからの入力でアドレスを設定するルーチンがやっとのことで動いた。8バイトの16進アドレスをキーボードから入力させるロジックは結構面倒である。

 ATOIなどの標準ライブラリには、16進数のキャラクターをバイナリに変換する関数もあるようだが、使い方が難しく、今愛用させて貰っているChaNさんのxatoiにはその機能がない(あることはあるのだが、0xというプリフィックスをつける必要がある)。全部自作するしかない。

 フラッシュに余裕があるとはいえ(まだ5KB少々)、同じようなロジックの繰り返しは避けたい。8バイトをすべて入れさせるのは、キャラクターベースでは間違いやすいので、4バイトづつ分けて2回に入力をさせるようにしたため、これをまとめるのに苦労した。

 Windowsのような画面からの入力に慣れていると、多バイトの入力は気にならないが、CUIでは難しい。昔を思い出しながら、せっせとコーディングする。繰り返される入力の部分は関数に切り出した。このあたりは力仕事に近い。

夜半、ついに完成した。出来たソフトを動かして、一人で満足する。デバッグのための送受信のテストメッセージが延々と出てくるが、むしろこれは残しておいた方が便利かもしれない。現在のAPIフレームモニターの機能は以下の通りである。

コーディネーター及び、リモートのXbeeにAPIモードで任意のコマンドが送れる。
リターン キーでコマンドを確定すると、それぞれ、所定のフォーマットで結果が
戻されてくる。

tABnnn コーディネーター(親機)にABというコマンドを送る。nnnは設定するときの
             パラメーター。コマンドABとnnnの間にブランクを入れない。nnnは、
             8文字(4バイト)までの16進数。右詰めで左の0は省略可能。

rABnnn リモートにあるエンドディバイス(子機)へのATコマンド。仕様は上と同じ。

リモートにはメッセージが送れる。

;ABCDEF    リモートディバイスに;以下のテキストを送る(1パケット40文字まで)。
                  リターンキーがテキスト終了を示す文字なので、リターンキー(0x0D)は
                  送れない。

いくつかの設定用コマンド

d0 d1 Xbeeからの受信APIフレームを、16進表示だけの文字列(d0)にするか、
         一定のレスポンス(5種類)については、アドレスやパラメーターを
         フォーマットして出力する(d1)かを決める。デフォルトはd1。

a1 a2  APIモードにおける、通常APIモード(a1)か、エスケープ付き(a2)かを
     選択する。デフォルトはa2(エスケープ付き)。
     ATモードにはならない(そもそも意味がない)。 

ad    エンドディバイス(子機)の64ビットアドレスを設定する。adだけ入れて
   リターンキーを押すと、現在設定中のアドレスが表示されるので、それを
   参考に1バイトづつブランクを空けて入力する。

   00は0でも良く、上位0は省略できる。上位(Higher)の4バイトと、下位(lower)の
   4バイトを分けて入力する。リターンキーだけのときは変更しない。

       最後に64ビットすべてが表示され確認を求められる。Yかyを入れると
   EEPROMに書かれ、以後はそのアドレスが使われる。

   プログラムの最初にはこの設定が必ず必要である(EEPROMには
   ダミーアドレスが入っている)。なおフューズビットはEEPROMを保存する
   ようにしておくと便利である。 

h       以上のコマンドの簡単な紹介。

 Xbeeからの受信メッセージはdコマンドに従って、画面に表示される。d1を選んでもコマンドレスポンスなど良く出てくるメッセージ以外は、すべて16進コードで表示される。

 なお、このプログラムは、ChaNさんのシリアルISPライターがないとUARTが動作しない。同じ仕様の市販のライターもあるようなので、とりあえずはこのままにすることにした。ソースコードを公開するので、普通のUARTに換えるときは、soft_uart.cを変更してほしい。

 ただ、このISP-UARTはChaNさんのオリジナルUARTソースを大幅に変更して、受信待ちをせず、データをバッファーに蓄える改良が施され、ピンチェンジ割り込みで動くようになっているので、簡単には移植できないかもしれない。そのときはブログにコメントを頂ければ、改良版を作りたいと思っている。

ここに例によってAVRStudioのフォルダーを固めたソース一式を置きます。無印Xbeeも動きますが、色々なところでAPIフレームのフォーマットが異なるので注意が必要です。

「XbeeAPI168.zip」をダウンロード

| | コメント (5) | トラックバック (0)

« 2011年3月20日 - 2011年3月26日 | トップページ | 2011年4月3日 - 2011年4月9日 »