ラジコン受信機とマイコンの接続

室内で飛行する模型飛行機の自動制御を企んでいるわけですが、機体外から送られてきた制御情報と、機体に搭載されたセンサから得られた情報を、機体内のマイコンでミキシングすることによって全体のシステムが成立するようなことを考えています。
つまり機体外の情報を一度、機体内のマイコンにとりこむ必要があるのですが、今回は機体外の情報の通信手段としてはラジコンの無線を利用することを考えているので、ラジコンの受信機とマイコンを接続すれば達成できることになります。

ラジコンの受信機は普通、制御する対象の数(チャンネル数)だけ配線があり、そこにパルス(OFF→ON→OFFの信号)が出力されます。このパルスのON時間と制御量は比例関係にあるので、パルスのON時間をマイコンで計測できれば目的が達成されます。
しかしマイコン側でON時間を計るための機能は、残念ながらチャンネル数分ないことがほとんどであるため、なんらかの工夫をする必要があります。今回は6チャンネルの受信機をH8/3694マイコンの2つ分のパルス計測機能(正確にはタイマWのインプットキャプチャ機能、端子はFTIOAとFTIOB)で計ることにしました。

rx2cpu.png
こんな回路でできます。

工夫というのは単純な話で、ラジコン受信機からでてくるパルスは、チャンネルが違えば出力されるタイミングが異なることを利用しました。回路は図のとおりです。

あとはプログラムですが、これは続きをどうぞ。

#define SERVO_CH 6
unsigned short input_pulse[SERVO_CH];

void init_check_pulse(){
    /* タイマWの有効化
     *
     * クロックはφ/2(0.1 us)
     * A => インプットキャプチャ(割り込み)
     * B => インプットキャプチャ(割り込み)
     */
    TW.TCRW.BYTE = 0x10;
    TW.TIOR0.BYTE = 0x74; // A => 立ち上がりエッジのみ検出
    TW.TIERW.BYTE = 0x03;

    /* カウントスタート */
    TW.TMRW.BIT.CTS = 1;
}

#define BIT_IMFA 0x01
#define BIT_IMFB 0x02

inline void check_pulse(unsigned char flag){
    static unsigned char target_ch = SERVO_CH;
    static unsigned short before_count;

    if(target_ch < SERVO_CH){
        // 奇数(1, 3, ...)
        if(target_ch & 0x01){
            if(flag & BIT_IMFB){
                input_pulse[target_ch]
                     = (TW.GRB > before_count) ? (TW.GRB - before_count) : ~(before_count - TW.GRB);
                if(flag & BIT_IMFA){
                    before_count = TW.GRA;
                    target_ch++;
                    return;
                }
            }
        // 偶数(0, 2, ...)
        }else{
            if(flag & BIT_IMFA){
                input_pulse[target_ch]
                     = (TW.GRA > before_count) ? (TW.GRA - before_count) : ~(before_count - TW.GRA);
                if(flag & BIT_IMFB){
                    before_count = TW.GRB;
                    target_ch++;
                    return;
                }
            }
        }
        target_ch = SERVO_CH;
        TW.TIOR0.BYTE &= ~(0x03); // A => 立ち上がりエッジのみ検出
    }else{
        if((flag & (BIT_IMFA | BIT_IMFB)) == BIT_IMFA){
            before_count = TW.GRA;
            TW.TIOR0.BYTE |= 0x03; // A => 両エッジ検出
            target_ch = 0;
        }
    }
}

#pragma interrupt
void int_timerw(){
    unsigned char flag = TW.TSRW.BYTE;
    /* フラグクリア */
    TW.TSRW.BYTE = 0x00;

    /* IMFA, IMFB */
    if(flag & (BIT_IMFA | BIT_IMFB)){check_pulse(flag);}
}

int main(){
    init_check_pulse();
    enableIRQ(); /* 割り込み有効 */
    while(1);
    return 0;
}


これでうまく動いています。

July 15, 2006 02:24 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク

コメント

初めてメール差しあげます。 石貝と申します。
今H8マイコンを使用してRCヘリコプターに近い物を製作しようと思って降りますがモーターを制御するためにH8マイコンでRC受信機からのPWM信号をミキシングしたいのですが送信機側でのミキシング機能ではできません。マイコンでミキシングするしかないようです。製作する物はブラシレスモーターを4つ使用し、4つのプロペラを回転させ浮上する物です。

1.スピードコントローラースティックを上下すると4つのモーター(A,B,C,D)が同じ回転数で上下する
2.エルロンスティックを右に倒すと(A,B)のモーターが同じ回転で制御できる
3.エルロンスティックを左に倒すと(C,D)のモーターが同じ回転で制御できる
4.エレベータースティックを上げると(A)のモーターの回転を制御できる
5.エレベータースティックを下げると(B)のモーターの回転を制御できる
6.ラダースティックを右に倒すと(C)のモーターの回転を制御できる
7.ラダースティックを左に倒すと(D)のモーターの回転を制御できる

細かくスムーズに回転が制御できればと思うのですがモーターは十字に配置します。ちなみにサーボは使用しません。市販のブラシレスコントローラーを制御します。サーボコントロール用PWM信号が4チャンネル分使用できればよいのですが、HPに掲載されたC言語プログラムで使用できるよう詳しく教えていただけませんか。

Posted by: JA2YYN : December 18, 2008 07:51 PM

>石貝さん
書かれていることは信号のch間ミキシングで実現できると思いますが、それはプロポの設定でできるようです。マイコンを使われるより、そちらの方が安全、安価にできると思います。
ここに紹介しているようなマイコンに出番がある場合は、単なる信号のミキシングではなく、信号の記録を取りたいとか、PID制御などの特別な制御を入れたいという場合に限られると思います。

Posted by: fenrir : December 20, 2008 04:48 PM

RCプロポの送信機ではどのメーカーでもスピコンなどのミキシングはないんです それにスティックの倒す方向で(左に倒すとモーターBがコントロール)というように右だけ左だけで個々にコントロールできません
やはりマイコンPICなどで組むしかないようです
http://jp.youtube.com/watch?v=PjZ9RIyY72E&feature=related
http://jp.youtube.com/watch?v=njFsy4wZwFg&feature=related
http://jp.youtube.com/watch?v=Csti6mHZNF4
http://jp.youtube.com/watch?v=Csti6mHZNF4
http://jp.youtube.com/watch?v=UFnS-FHiCiA&feature=related

Posted by: JA2YYN : December 21, 2008 03:37 PM

>石貝さん
ヘリなどに使う他チャンネルのプロポなら、トリム値とミキシング量を変えて対応できるのではないでしょうか。操作するスティックを拘らない必要があるかもしれませんが。
もしマイコンを使ってサーボ信号を取り出す必要があるようでしたら、ここで紹介している内容が6chですので、それを4chにするだけで特に難しいことはないと思います。

Posted by: fenrir : December 22, 2008 12:16 AM

初めてメール差しあげます. 町田と申します.
ブログでのコメントのやりとりを拝見させていただきました.
私も4つのブラシレスモータを使用して,4つのプロペラを制御することによって飛行を行うヘリコプターの製作を考えています.サイズは60cm四方に納まる程度で,重量は重くても1kg程度の機体を考えています.最終的な目標として自律飛行を目指し,機体制御用マイコンにH8/3069の使用を考えています.モータは4つの8bitタイマのPWM信号によりそれぞれ制御し,また,3つの16bitタイマでは,制御周期およびセンサ測定周期の計測を考えています.
H8マイコンを使った制御方法(特に8bitタイマでのモータ制御について問題が無いか),モータやプロペラの選定などについて何かアドバイスを頂けると幸いです.

Posted by: 町田 昇司 : June 12, 2009 01:57 PM

>町田さん
はじめまして、クワッドロータですね。ロータを4つにすると反トルクの影響が打ち消せるので制御が簡単になるそうですね。
知っている範囲で意見を申し上げますと、ロータの回転数を使って制御をすることになると思うので、8bitsタイマ=解像度256で制御に十分なのか気になるところです(最近はラジコンの受信機でも解像度は1024=10bitsくらいありますし)。またロータを回すのにラジコンのスピコンを使う場合、制御入力(PWMのパルス幅)に対して線形にトルクが変化するわけではないので、これも注意が必要だと思います。

Posted by: fenrir : June 13, 2009 05:01 PM

早速のコメントありがとうございます.
制御用マイコンについてですが,以前はH8/3052Fを使用していました.5チャンネルある16bitタイマのうち4つをモータ駆動用に,残りの1つを制御周期(20ms)の計測用に利用していました.ですが,一定の制御周期が計測できない問題(超音波距離センサ用のウェイト関数を1つのタイマで作ったことが影響したかもしれません)が生じてしまいました.1つのタイマでは,この問題を解決することはできないのでしょうか?
制御周期やセンサ測定周期計測用のタイマの割り当てについてアドバイスがあればお願いします.
 また,以前はDCブラシモータをMOSFETを利用した回路で駆動していましたが,ブラシレスモータも何らかの回路を構成することにより動かすことができますか?可能であれば回路の構成や線形特性はどのようになりますか?
 最後になりますが,プロポで操縦する機体をまずは製作しようと考えているのですが,その際に参考となる情報(配線関係やプロポのチャンネル数など)について教えていただけると幸いです.

Posted by: 町田 昇司 : June 15, 2009 04:06 PM

>町田さん
ご質問は特定のマイコンの問題で、原因を推測するのはなかなか困難です。申し訳ないのですが、ご自身で解明されるしか手立てはないと思われます。

参考ですが、僕の周辺では次にあげるサイトがクワッドロータですと人気です。
http://www.mikrokopter.de/ucwiki/en/MikroKopter
ドイツ語がメインのページですが、リンクは英語版をあげておきました。

ブラシレスモータは3相交流を扱うので難しいようですが、コントローラの作り方についての情報は探すと出てきます。僕が個人的に推しているマイコンSilicon LaboratoriesのC8051のアプリケーションノートにソースコード付きで解説があります。
http://www.silabs.com/products/mcu/Pages/SensorlessBLDCMotorRD.aspx
PICでおなじみのMicrochipにもありました。
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en012127

Posted by: fenrir : June 18, 2009 01:12 AM

貴重なご意見,ありがとうございます.
今回教えて頂いた情報をもとに,色々と検討してみます.

Posted by: 町田 昇司 : June 18, 2009 10:11 AM

コメントする