Knowledge | ||||||
プロポをマイコンで制御
2004/10/31 |
プロポをマイコンで制御 いや、KONDOの無線コントロールユニットとかにすれば、こんな苦労は要らないのですが、あの受信機、かなり小さいけど、今のG-Tuneにはまだ大きい…。あれ?今、ロボット王国のホームページチェックしてたら、「フリクションスペーサ」がある〜。いつの間に…。 さってと、話、戻りましてと。フタバプロポに限らず、プロポには「トレーナー機能」というものがついています。これは、以前のTOPICでも紹介しましたが、生徒さんとトレーナさんの2台のプロポをケーブルで接続し、トレーナのプロポで生徒さんの操作を行うものです。このSKYSPORT4、良く見ると正面左上に、小さなボタンがついていますが、これを押している間、ケーブルを経由して別のプロポから操作をすることができます。 また、このトレーナ機能、SKYSPORT4(どのプロポもそうみたいですが)では、生徒さん側もトレーナ側もできるようです。つまり、このSKYPORT4からも信号が出力されているはずなので、Trainer端子を適当にあたって、まずは信号解析してみました。ネットでちょっと「トレーナケーブル」なるものを探してみたのですが、うぅ、トレーナケーブル、意外に高価だったので購入をあきらめました(笑)。というわけで、ピンを直接あたることにしました。 トレーナ信号とは??? 実は、さっきのGoogle検索で、すでにトレーナ信号を解説されているホームページを発見してしまいました。どうも、ラジコンフライトシミュレータソフトのコントローラとして、プロポをそのまま使用するようです。なるほど。それならラジコンと同じ操作感が得られます。 そんなわけで、きっと、このページを見たみなさんも、既に発見されていると思いますので、信号は、試しに見てみる程度にしたいと思います。というわけで、まずはオシロ(のおもちゃ?)をつないで波形を見てみます。この秋月のペン型オシロ、ちゃちだし少々怪しげですが、結構、役に立ちます(でも、もっといいのがやっぱり欲しい〜)。 左が「1マス5msec」です。これを見ると、18msecで信号が繰り返されているのがわかります。で、この部分を拡大したのが右側です。「1マス1msec」です。じゃ、試しにスティックを動かしてみます。左スティックを上下してみました。 上にすると、2番目の山が小さくなり、下にすると、2番目の山が大きくなるのがわかります。他も微妙に動いているような気がしますが、実際のところどうなんでしょう…。電圧(HIGH)ですが、上の絵ですと、「1マス2.5V」ですので、4Vをちょっと切るぐらいですが、もう1つ前の写真を見ると、5Vちょっと切るぐらいです。これは、「グランド」を適当につなげたか、しっかりつなげたかで変化が出てまして、「プロポ操作つき」のデータ収集の場合、どうも端子へのあたりがいいかげんになってしまいまして、こういう結果になってしまいました。 ネットで見つけた情報によると、「LOWになっている部分は0.4msec、山はスティック位置が真中で1.1msecあたりで0.6〜1.6msec程度、操作によって変化、最後に、もう1つ0.5〜0.6msec程度の山があって、全体は常に18msec」とありますが、これで確認はできました。また、それぞれのスティックの信号が短い場合、それ以降の信号は前詰になりますが、全体は18msecのままであるということもわかります。 同じプロポ同士でトレーナ機能が使えるならば、これと同じ信号を、トレーナの入力端子に入れれば動作できるはずです。 どれがどれ?
というわけで、明日はテストプログラムの解説をしたいと思います。 ところで、ONOさ〜ん、また電脳壁新聞、見当たらないんですが…うちだけでしょうか? 追記)うふっ。見つけました。ONOの電脳壁新聞!
| |||||||||||||||||||||||||||||||||||||
2004/11/04 |
というわけで… さて、気になるプログラムですが、今回は、TimerWを使用しました。18msecの基本周期が必要になりますので、TimerWのコンペアマッチクリア機能を使用して作ります。コンペアマッチクリアというのは、あらかじめジェネラルレジスタに値を設定しておき、カウンタがその値になると、自動的にクリアされる仕掛けです。ジェネラルレジスタA(GRA)のみ、この機能を使用することができます。 そして、GRBによってコンペアマッチ割り込みを適宜発生させるようにします。H8/3664のCPUクロックは16MHzですので、1/8周期でカウントアップした場合、2000カウントで1msecになります。下の図で説明しますと、GRAによって、36000カウントでタイマがクリアされるようにしておいて(黄色い線)、GRBによってそれぞれのタイミング(緑色の線)で割り込みをかけます。そして、制御信号(青色の線)が出力されます。 GRBによる割り込み処理内容
長くなったしまったので、ここらで一旦切りまして、明日はいよいよプログラムの解説をします。 ところで、OLMECAの部屋のイカガワさん、Hashioさん、元気〜?今は大学祭とかかなぁ。トレーナ機能はこれであってる???
| |||||||||||||||||||||||||||||||||||||
2004/11/05 |
さて、プログラム解説
TimerWの初期化 また、GRBのコンペアマッチによって割り込みをかけます。よって、初期化プログラムは以下のようになります。 TW.TMRW.BYTE = 0x48; // タイマストップ、モード普通 TW.TCRW.BIT.CCLR = 1; // GRAコンペアクリアあり TW.TCRW.BIT.CKS = 3; // φ/8 TW.TIERW.BIT.IMIEB = 1; // Bコンペアマッチ割り込み有効 数値をDEFINEで定義 #define DDFT_TCNT00180S 36000 // 16MHzで1/8の18msカウントアップ初期値 #define DDFT_TCNT00004S 800 // 信号と信号の間のLOW時間 #define DDFT_TCNT00006S 1200 // スティックLow Low(600us) #define DDFT_TCNT00011S 2100 // スティックCenter(1100us) #define DDFT_TCNT00016S 3200 // スティックHigh High(1600) #define DDFT_SIGNALOUT IO.PDR8.BIT.B2 // トレーナ信号出力端子 #define DDFT_SPOS_HGH 0x01 // スティック位置定義 #define DDFT_SPOS_CNT 0x02 // スティック位置定義 #define DDFT_SPOS_LOW 0x03 // スティック位置定義 グローバルデータ _BYTE GVDbSignalStep; // 信号処理ステップ(0:最初の0.4ms,1:CH0,2:0.4ms,3:CH1...) _BYTE GVDabStickPos[4]; // プロポスティック位置 「GVDbSignalStep」は、TimerW割り込み処理のところで詳しく説明しますが、全体の処理のステップ(最初に0.4msのLOWを出して、つぎにCH0の信号を出して…みたいな処理)を覚えておくための変数です。「GVDabStickPos[4]」の方は、プロポスティック位置相当のデータをキーボードからの入力によって覚えておくためのデータです。 TimerW割り込み処理 void int_timerw( void ) { // GRB コンペアマッチ 信号作成用カウントアップ if( TW.TSRW.BIT.IMFB == 1 ){ TW.TSRW.BIT.IMFB = 0; // 割り込みフラグクリア switch( GVDbSignalStep ){ case 0: // 初期化(0でコンペア) DDFT_SIGNALOUT = 0; // LOWにする。 TW.GRB = DDFT_TCNT00004S; // 最初の0.4msを設定する。 break; case 9: // 最後信号の0.6ms ON。 DDFT_SIGNALOUT = 1; TW.GRB += DDFT_TCNT00006S; break; case 11: // 最後 DDFT_SIGNALOUT = 1; // HIGHにする。 GVDbSignalStep = 0xFF; // 初期値(インクリメントして0になる) TW.GRB = 0; // 初期化する。 break; default: if(( GVDbSignalStep & 0x01 ) != 0 ){ // 奇数ならば信号出力 DDFT_SIGNALOUT = 1; switch( GVDabStickPos[(GVDbSignalStep/2)] ){ case DDFT_SPOS_HGH: TW.GRB += DDFT_TCNT00006S; break; case DDFT_SPOS_CNT: TW.GRB += DDFT_TCNT00011S; break; case DDFT_SPOS_LOW: TW.GRB += DDFT_TCNT00016S; break; default: TW.GRB += DDFT_TCNT00011S; break; } } else{ DDFT_SIGNALOUT = 0; TW.GRB += DDFT_TCNT00004S; } break; } GVDbSignalStep++; } } いきなりちょっと長いですが、「GVDbSignalStep」というグローバル変数を使用して、これを、0〜11に変化させることでCASE文の中を飛ばしています。昨日の処理の表と見比べてみてください。この「GVDbSignalStep」とう変数の数値と、昨日の表の項目番号は一致しています。 昨日の表をよく見るとわかるのですが、「9」と「11」を除いた奇数の時には「スティックに応じた位置の出力」、偶数の時は「0.4ms」の出力の処理になります。おっと、よくみると「case 0:」は不要な感じですね〜。すいません、余分なものをいれてしまいました。 後は、これにキー入力処理をいれたら出来上がりです。ご参考、実験用ということで、完成プログラムはここです。 さて、これを使えば…オリジナルで作ったコントローラパッドからの入力をマイコンで受け、それをプロポのスティック位置として出力することができそうです。おっと、最後になりましたが、実験される時は、「プロポ左上のボタンを押す」ことをお忘れなく。
|
SISO-LAB Knowledge