APIフレームのデータレイアウトはアライメントが無視されているので、4バイトバイナリーなどはうっかり使えない。1バイトづつの処理が必要だ。アスキー文字の16進表示を実際のバイナリデータにするのは、1対2でデータをずらしていかなければならない。簡単には行かない(1バイトのデータを得るのに、2バイト分のキャラクターが必要)。Parameterのエラーメッセージではねられる。意地になって、久しぶりのコーディングに夢中になる。手当たり次第にprintfで途中経過を表示させながら、何とかATコマンドの後についた16進数キャラクターをパラメーターのバイナリーにするロジックが完成した(出力側のAPIフレームのパラメーターエリアを固定にして最後からデータを入れていくのがミソだった)。パラメーター入力はコーディネーター(親機)の方では正常に動いた。次はいよいよリモートだ。あせる手でエンドディバイス(子機)のXbeeのブレッドボードにLEDをデジタルピンD1につけ、PCに戻って親機の方から子機にデジタルピンを上下するコマンド、ATD14(D1ピンをOFF(4)にする)を入れる。今度は、ATD13(ON)。けなげに点いたり消えたりするLEDがいとおしい。よしよし、これでXbeeだけでラジコンを動かす機能は実現した。完成まであともう少しである。100ミリ秒で制御できれば何とか使えるか(3/26/2011)ただ喜んでいるわけにはいかない。LEDの点灯や、消灯は、コマンドを入れて一瞬とは行かず、ほんの少しだが一呼吸おいて動作する。どれくらい遅れているのだろう。ラジコンが動かせるくらいの早さでON/OFFが出来ているのだろうか。オシロで時間を測ってみることにする。2現象でPCからマイコンに行くUARTと、マイコンからコーディネーターXbeeに行くUARTの2箇所と、実際のエンドディバイスのXbeeのLEDのON/OFFの間を比較する。PCを起点とするUARTからでは200ms、マイコンからXbeeへのUARTからなら50~100msでピンの制御ができることがわかった。ラジコンのコントロールはタクトスイッチでやるとするなら、PCからのUARTの早さでなく、マイコンからXbeeへのUARTの早さでコントロールできるだろう。100ms以内で動きそうだ。車程度ならそう遅れを感じずに制御できるだろう。それにしてもAPIモードは難しい。分からない単語が頻発する。省電力化した複雑なネットワークを意識しているので、盛りだくさんの機能がついている。エンドディバイスもデフォルトで、スリープモードに入るようになっている(制御が始まれば暫く動いているが)。今のところラジコンだけが目的なので、当面このあたりは関係ない。マニュアルを読んでいると、あまり詳しく設定しなくても、エンドディバイスを兼ねたルーターをいくつも介して、遠方にいる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ビットアドレスの入力だ。汎用モニターひととおり完成(3/28/2011)EEPROMにリモートの64ビットアドレスを収容し、プログラムをコンパイルし直さないで、コマンドからの入力でアドレスを設定するルーチンがやっとのことで動いた。8バイトの16進アドレスをキーボードから入力させるロジックは結構面倒である。ATOIなどの標準ライブラリには、16進数のキャラクターをバイナリに変換する関数もあるようだが、使い方が難しく、今愛用させて貰っているChaNさんのxatoiにはその機能がない(あることはあるのだが、0xというプリフィックスをつける必要がある)。全部自作するしかない。フラッシュに余裕があるとはいえ(まだ5KB少々)、同じようなロジックの繰り返しは避けたい。8バイトをすべて入れさせるのは、キャラクターベースでは間違いやすいので、4バイトづつ分けて2回に入力をさせるようにしたため、これをまとめるのに苦労した。Windowsのような画面からの入力に慣れていると、多バイトの入力は気にならないが、CUIでは難しい。昔を思い出しながら、せっせとコーディングする。繰り返される入力の部分は関数に切り出した。このあたりは力仕事に近い。夜半、ついに完成した。出来たソフトを動かして、一人で満足する。デバッグのための送受信のテストメッセージが延々と出てくるが、むしろこれは残しておいた方が便利かもしれない。現在のAPIフレームモニターの機能は以下の通りである。・コーディネーター及び、リモートのXbeeにAPIモードで任意のコマンドが送れる。キーでコマンドを確定すると、それぞれ、所定のフォーマットで結果が戻されてくる。コーディネーター(親機)にABというコマンドを送る。nnnは設定するときのパラメーター。コマンドABとnnnの間にブランクを入れない。nnnは、8文字(4バイト)までの16進数。右詰めで左の0は省略可能。リモートにあるエンドディバイス(子機)へのATコマンド。・リモートにはメッセージが送れる。リモートディバイスに;以下のテキストを送る(1パケット40文字まで)。リターンキーがテキスト終了を示す文字なので、リターンキー(0x0D)は送れない。一定のレスポンス(5種類)については、アドレスやパラメーターをフォーマットして出力する(d1)かを決める。APIモードにおける、通常APIモード(a1)か、エスケープ付き(a2)かを選択する。デフォルトはa2(エスケープ付き)。ATモードにはならない(そもそも意味がない)。エンドディバイス(子機)の64ビットアドレスを設定する。adだけ入れてリターンキーを押すと、現在設定中のアドレスが表示されるので、それを参考に1バイトづつブランクを空けて入力する。00は0でも良く、上位0は省略できる。上位(Higher)の4バイトと、下位(lower)の4バイトを分けて入力する。リターンキーだけのときは変更しない。最後に64ビットすべてが表示され確認を求められる。Yかyを入れるとEEPROMに書かれ、以後はそのアドレスが使われる。プログラムの最初にはこの設定が必ず必要である(EEPROMにはダミーアドレスが入っている)。フューズビットはEEPROMを保存するようにしておくと便利である。以上のコマンドの簡単な紹介。Xbeeからの受信メッセージはdコマンドに従って、画面に表示される。d1を選んでもコマンドレスポンスなど良く出てくるメッセージ以外は、すべて16進コードで表示される。このプログラムは、ChaNさんのシリアルISPライターがないとUARTが動作しない。同じ仕様の市販のライターもあるようなので、とりあえずはこのままにすることにした。ソースコードを公開するので、普通のUARTに換えるときは、soft_uart.cを変更してほしい。このISP-UARTはChaNさんのオリジナルUARTソースを大幅に変更して、受信待ちをせず、データをバッファーに蓄える改良が施され、ピンチェンジ割り込みで動くようになっているので、簡単には移植できないかもしれない。そのときはブログにコメントを頂ければ、改良版を作りたいと思っている。ここに例によってAVRStudioのフォルダーを固めたソース一式を置きます。無印Xbeeも動きますが、色々なところでAPIフレームのフォーマットが異なるので注意が必要です。APIモードにはまる(2011.03.25)メカトロニクスの第一歩、モーター制御に踏み出す(2011.03.12)Xbeeワイヤレス電力ロガー親機のソース公開(2009.11.21)コメントこれまではGatewayからPythonで書いた怪しいものに頼っていたので、フレームを直接見れる仕組みが簡単に提供されたのは大変助かります。>実は、あのソースはコメントに大きな間違いがあり、XbeeのUART>接続が違っています。何も考えずにRXピンにXBeeのDOUTを、TXピンにDINを接続していましたが、確かにソースのChip図は違いますね。小生も慌て者ですが怪我の功名でした。引っ掛かったのはシリアルスピードで9600bpsでは化け々。図(xbee329.jpg)を見て38400bpsにして正常に表示されました。GPIO版にも期待しています。役に立ったというメールが一番うれしいですね。苦労した甲斐がありました。ご報告ありがとうございました。実は、あのソースはコメントに大きな間違いがあり、XbeeのUART接続が違っています。GPIOでのUARTが動くようになったので、そのとき一緒に修正する予定ですが。くAVR環境の整備がほぼ完了し、公開戴いた「汎用モニタ」の利用試行に漕ぎ着けました。実はarduinoでは一寸遊んだことがありましたが、生AVRは未体験で、大昔(8086以前)はProprietary、最近はPIC弄りばかりでAVRもCで動かせるならと、高を括っておりましたが今回は戸惑いました。所長の第一回ブログのままのISPケーブルを作成し、AVRstudio&WinAVRのインストールと一気に環境作成し、漸くXBeeAPIモニタ稼動まで辿り着きました。素晴らしく便利に使えそうで公開大感謝です。(まだ一部だけしか試せていませんが)PS.昨日秋葉原での部品集めに際して、所長の前々作(?)リニアPCMプレーヤーも作ってみようと、その部品も集めてきました。課題としてVRが残っていますが)2号機デザインのスケルトンをワイヤリングで挑戦する目論み|充電回路は外出し予定です。コメントありがとうございます。Xbeeにお詳しいのですね。こちらは1対1の簡便なリモートコマンドの環境が作りたいだけでしたので、不勉強でした。