Xbee APIモードのラジコン制御成功
モーター制御をするはずだったのが、XbeeのAPIモードに寄り道し、XbeeのAPI汎用モニターをでっちあげてしまった。そのついでに、これまで気になっていたUARTの改善にはまりこんでしまう。完全な「寄り道の寄り道」である。
ソフトUARTをC言語化する(4/1/2011)
Xbee自体が道草だったのだが、さらに迷路である。このISP-UARTは、最初ChaNさんが作られたもので、ISPシリアルライター(AVRSP)でプログラムを書き込んだ後ケーブルをつなぎかえる必要もなく、そのままの状態でUARTに使えるというのがウリである。
AVRに取り組んですぐ、ChaNさんのオリジナルUARTソース(アセンブラー)に、受信が割り込みで動くようにC言語でロジックを追加した。この改修で、UARTは入力待ちで止まらないので(入力があるとフラグを返す関数を使う)、モニター代わりに当研究所では殆どのシステムに入れてある。
デバッグが済めばUARTを使わないシステムでは完成後はずせばよい(フラッシュに余裕のある時は結線をはずすだけ)。中の変数を簡単に出力でき、プログラムをLEDなどでデバッグするより格段に効率が良いので、大変重宝している。
ただ、前から不満が残っていた。それは、ソースコードに、ChaNさんのアセンブラールーチンが残っていて、使うたびに、アセンブラーのファイル(.S)とUART本体のファイル(.C)の2つをインクルードしなければならないことである。それと以前、アセンブラーの部分をすべてCに換えようとして、うまくいかずあきらめて残した経緯がある。それ以来、何となくわだかまりが残っている。
ISPのラインを使わず(MOSI/MISO/SCK)、通常のGPIOで、このUARTが使えるようにしたことはあるが、このASMルーチンは残したままであった。ISP-UARTは、通常のUARTと違い、ISPのプログラム書き込みの関係か、UARTのデータラインが正論理(スタートビットがHigh)になっており、このときはこれを負論理に置き換えただけである。
アセンブラーで書いた部分をC言語に出来なかったのは、時間遅れを正確に把握できず、受信がどうしても安定しなかったためと記憶している。しかし、あのころに較べたらオシロもロジアナもあるし、開発環境は格段に進歩している。丁度良い機会なので、XbeeのAPI汎用モニターをより汎用化するため、GPIOのC言語だけのUARTを作ってしまおうと決意した。
意気込みは良かったが、やっぱり今度も、四苦八苦した。送信は何とか動くようになって、マイコンからのオープニングメッセージが出るようになったが、PCからのデータ受信が難しい。キーボードからの1文字だけの入力なのだが、どうしても正しい文字を受け取れない。
やっぱり、ロジックアナライザーの出番が必要になった。GPIOでボーレートに従ってピンの入力を調べるところへ、ロジアナに信号を送るプローブピン(ピンをトグルするステートメント)を入れ、時間を測った。UARTはどんなに早くても1ビット数十から数百μsの世界だが、AVRのクロックは4Mhzでも1/4μsで少々プローブを入れても影響は殆どない。コンパイルし直してロジックアナライザーを動かす。
これでGPIOの動きが一目瞭然になる。これが一番強力なデバッグ法だ。これができなくて前は挫折したのだ。画面を注意深く検討する。うーむ、想定どおりのタイミングでデータを読み込んでいるぞ。正しくデータをとっているようだな。ビットを数える。ちゃんとスタートビット、ストップビットをカウントしている。チャートで見る限りは正しい文字を得ているはずだ。それなのに出力がおかしい。
わかってしまえば、馬鹿馬鹿しくなるほど簡単な間違いなのだが、この段階でも原因はつかめなかった。デバッグというのはこういうものだ。一生懸命、タイミングを調べていたが、ロジアナで見る限り、データを採取するタイミングは間違っていない。最初、割り込み直後の待ち時間が長すぎて、全体が後ろにずれていたが、これを補正してコンパイルしなおしても正しいデータはとれない。とすると原因はここではない。
採集した1バイトデータがこのあとおかしくなっていることになる。1バイトデータはシフトレジスター的に1ビットづつ移動しながらデータを取る。ふーむ、前もこんなことがあったような....もしかして出来上がったデータを最後にさらに回してはいないかい。あ、あ、あ、やっぱりここでもやっていた。
いやあ、時間がかかった。これはdo whileのように終了条件を後にしても解決しない。8ビットのデータを得ながら、8回シフトすれば、データは1ビットずれる。出力する側をシフトするのでなく、マスクする側をシフトするようにロジックを変更する。
よーし、受信も問題なく動くようになった。C言語での割り込みのオーバーヘッドはやはり思った以上にASMよりかなり大きかった。ASMではビットレートの半分くらいをスタートビットから待っていたが、この部分はCでは殆ど必要がないくらいだった。クロック4Mhzで14μsもかかっている(38.4kbpsで1ビット26μs)。一旦読み込みが始まれば割り込みを経由しないので、ほぼ想定どおりの待ち時間でまわっている。
CPUクロックが4Mhzとかなり低い(たまたまこの水晶しかなかっただけだが)のでクロックを上げたときには、もう少し補正する必要があるかもしれない。
それにしてもChaNさんのコーディングは何時見ても実に素晴らしい。このUARTの送信の部分のアセンブラーコードなどは惚れ惚れする。UARTのスタートビットとストップビットの追加は、普通なら別のステップを用意するところを、10回のループをまわしているだけで実現している。
スタートビットは、まずCOMという命令でデータを反転させ(このUARTは正論理なのでこれが必要)、ついでにこのときできたキャリービットをスタートビットに使う。そして最後のストップビットは、シフトの空振りで出来るゼロビットで実現だ。送受信とも命令数は10あるかないか。
皮肉なことにフラッシュサイズは、全部Cにしたら数十バイト増えてしまった。要するにこれだけ苦労して必要なファイル数をひとつ減らしたに過ぎない。まあ、これで全部自前のコードになったというつまらないプライドは満足させることができた。
タクトスイッチを使ったXbeeのデジタル出力が実現した(4/5/2011)
それはともかく、Xbeeのラジコン制御である。ラジコンだけなら、面倒な汎用モニターの大部分(キーボード入力文字をデコードする部分)のコードは不要である。どうしようか迷ったが、ラジコン制御のロジックも今のAPI汎用モニターに組み込んでしまうことにする。
汎用モニターもまだ修正するところがあるだろうし、ソースをひとまとめに管理していた方が楽だ。すべての処理はイベントドリブンで動いているので、どちらもオーバーヘッドになることはない(ifのところだけ)。フラッシュにも余裕がある。
モーターにひとつづつタクトスイッチを割り当て、スイッチの押下でモーター起動、離すと停止するコマンドを送ることにする。前進、後進の切り替えは、スナップスイッチで別のピンを設定する。
このピンを見ながら、それぞれのモータードライバーの2本の制御線のどちらかをONにすればラジコン側は、4本の出力ピンだけで前後進、左右転回ができる理屈である。
まず手始めに、一方のモーターの前進部分だけを実装する。モータードライバーへの供給電圧と、XbeeのVccが違うのに気がついて、最初はLEDを使う。
タクトスイッチのチャタリングは、これまでのインタバルタイマーの時間を20msから5msに短縮(プリスケールを1024から256に)し、ピンチェンジ割り込みをスイッチポートに設定し、割り込みが起きてから5ms待つことで防止する。
大した作業量ではない。ほどなくスイッチを押すとLEDが点灯し、離すと消えるという機能が実現した。心配していたが、応答速度は、想定していた通り、100ms内外に納まる。 最初は通信が確立していないので、1秒位待つ時があるが、その後は、殆ど変わらない。 UARTからメッセージが滝のように流れるが、これはXbeeからのレスポンスデータなので、タクトスイッチのレスポンスには影響がない。子供のように子機を遠くに離してLEDが点いたり消えたりするのを楽しむ。
遂に、XbeeのAPIモードを使ったラジコンの操縦に成功(4/7/2011)
LEDで成功したので、いよいよモータードライバーへの接続である。子機のXbeeの電源はレギュレーターで3.3Vにしているが、モーターは大きなレギュレーターがないのでリチウム電池そのままで、この間にはレベルシフターが必要になってきた。XbeeからいきなりモータードライバーTA7291Pにつなぐのも心配だったので丁度良い。手持ちの2SC1213などのトランジスタでバッファーをブレッドボードに組んだ。とりあえず前進のみの2つ。
Xbeeを載せたブレッドボードは落ちないようにモーターの上にマジックテープで仮止めし、電池フォルダーもモータードライバーのサブ基板のすきまに放り込んだ。急回転するとどちらも落ちそうだが、早く動くところを見たいので激しい手抜きである。
試運転に入る。胸が高まる。スイッチを入れるとき少し暴れてモーターが動くがすぐに納まる。Xbeeは最初の通信が確立するまで秒単位待たされる。
タクトスイッチ2つを同時に押すと直進、どちらかを止めると回転。おおー、操縦できる。快調快調。コマンドの遅れも殆ど感じない。機械は、電池と制御ボードを背中に載せた不細工な自走車だし、ラジコンで動くことなどいまどき驚く話でも何でもないが、すべて手作りでここまで動かしているという感動で胸が一杯になる。
この感激を分かってもらうのは、これはやはり動画でないと面白くない。携帯で動画を撮ることを思い立つ。苦心して携帯を固定し、何シーンか撮ったが、やはり操縦と撮影を一人でやるのは大変だ。何とか出来たムービーを、ブログのビデオ共有サイトに送ってはみたもののもう少し良い画を撮りたい。(現在動画サイトの閉鎖により見えません)
それに、今は前進だけで、後進できないので一旦障害物に当たると戻れない。リモコンはPC横の大きなブレッドボードに作ってあるので移動できない。やらなければならないことが急に増えた。
少しまともな動画を撮る(4/08/2011)
携帯電話で撮った動画は、まあ、動いていることをみなさんにわかってもらうだけのレベルで満足できる結果ではなかった。負け惜しみになるが、もともとはライントレーサーにしてみようと思っていた車体をXbeeを見て浮気してしまっただけのことである。 この程度で止めれば良いものを、やりだしたら止まらない性格である。後進機能と、リモコン機のポータブル化につきすすむ。PC横の大きなブレッドボードに設置した親機を、ミニブレッドボード2つに移し、リモコンとして持ち運べるようにする。
ラジコン車の方は、4つのトランジスタをミニブレッドボードに詰め込んで、後進もできるように実装した。後進のロジックは大分前にもう作ってある。リモコン機が出来た。電源は単3二つのバッテリーケースを持ちながら移動する。後進も想定どおりスナップスイッチの切り替えで順調に動いた。家族にビデオをとってもらうため居間に持ち込む。猫2匹が早速重大な関心を寄せる。
家族に撮影を頼んで、居間で動かす。猫がいても面白いので、猫を入れて撮影する。始めは恐る恐る見て いた猫も次第に慣れて来て、容赦のない猫パンチを浴びせ、ジャンパーが飛んで操縦不能になるところまでの画がとれた。少しは笑っていただけるかもしれない。
ひと時の興奮から醒めて冷静になって考えた。ラジコンだけでは今さら何も珍しくも何ともない。XbeeZBのAPIモードでマイコン使わないで制御していることなど、わかる人でもなければ、誰も感心してくれない。やっぱりライントレーサーにいくしかないか。
以下に、ISPピンでなく普通のI/Oピン(PC5,PC4)でUARTを動かすバージョンのXbeeAPIモード汎用モニターのソースと回路図ファイルをAVRStudioのフォルダーに入れたものを置きます。ChaNさんのASMソースを使ったものも入っています。コンパイルのときに選んでください。ISPピンで動くソースは、save_org_uartフォルダーにあります。
| 固定リンク
| コメント (0)
| トラックバック (0)
最近のコメント