ラジコンサーボを動かす

このエントリーをはてなブックマークに追加

 

 今回はラジコンサーボ(ウィキペディア)を動かします。ロボットを作る場合、センサなどと合わせて何かを動かしたい場合、などラジコンサーボを使うことは多いと思います。そこで今回は、ラジコンサーボを動かす基本を学びたいと思います。今回作成後、撮影した動画です。

 

1.今回使用するPICについて

 今回使用するPICは「PIC12F1822」です。

 

2.回路

  今回使用するラジコンサーボは「Tower Pro マイクロサーボ SG90 」です。

 

2.1 PIC

RA2:サーボの信号線

 

2.2 ラジコンサーボ

説明
 オレンジ色  PICからの信号線(注:Hiは3[V]以上)
 赤色  電源 4.6~6[V]
 茶色  グランド

注:ラジコンサーボにより、信号線の位置が異なる場合があるので、注意してください。

 

2.3 電子回路図

 

 

2.4 電子回路の写真

 

 

 

3.プログラム

 

3.1 ラジコンサーボの制御仕様

 今回使用するラジコンサーボを制御するには、決められた周期で信号を送らなくてはいけません。ラジコンサーボは内部に信号と角度の組み合わせを持っています。
例:2[ms]の信号であれば40度といった感じです
 決められた信号をPICで出力することにより、ラジコンサーボを動かしたい角度に回転させることができます。実際の信号は以下のようなパルス信号になっています。

1周期のパルス図

連続したパルス図

このようにパルスの幅を変更する方式をPWM(pulse width modulation)(ウィキペディア)といいます。
 決められた信号を出し続ける限りラジコンサーボはその角度でいようとする特性があります。なので姿勢を保持させたいときなどにラジコンサーボは有効です。ただし保持できる力の上限もあるので、制御対象には注意が必要です。

 さて、ここまででラジコンサーボを制御するためには、パルス出力が必要だということを書いてきました。今回はPICのPWM機能は使わずにパルス信号を出力します。PICのPWM機能を使用したところ、色々と問題が出てしまったため使わないことにしました。

 上の図のように動かすプログラムの概要は以下の通りです。

  1. 1周期は20[ms]
  2. 1~2[ms]の間、1(Hi)の信号を出力する
  3. 20[ms] – 2で出力した時間(1を出力した時間)、この時間の間、0(Low)の信号を出力する
  4. 1~3を繰り返し続ける

3.2 今回使う割り込みについて

 

3.2.1 Timer1によるタイマ割り込み

 Timer1によるタイマ割り込みは、Timer0の方法とほぼ同じなので、こちら(タイマ割り込みについて)を参照してください。
ただし、Timer0と違い、Timer1はサイズが16ビットになっているため、最大値が変わってきます。

タイマ サイズ
 Timer0  00 ~ FF(0 ~ 255)
 Timer1  0000 ~ FFFF(0 ~ 65535)

計算する場合、最大値を変更して計算を行ってください。今回は20[ms]毎に割り込みを発生させたいので、初期値は「25536」とします。25536から加算されていき、65535を超えたとき(65536(実際は0)になったとき)に割り込みが発生します。

 

3.2.2 Timer1のコンペアモードによる割り込み

 コンペアモードを使うと、Timer1の値が、コンペア用のレジスタの値と等しい時に割り込みを発生させることができる機能です。他にも色々な機能がありますが、今回は使用しません。
 コンペアモードを使用して、1(Hi)の信号を送る時間を制御します(下の図のHiの部分)。

 

 

3.3 メインプログラム

3.3.1 初期設定

 今までと同じように以下のように設定します。

OSCCON = 0b01110000 ;    // 内部クロック8MHz

ANSELA = 0b00000000 ;    // すべてデジタルI/Oに割当てる
TRISA  = 0b00001000 ;    // RA3を入力とする
PORTA  = 0b00000000 ;    // ピン状態初期化

 

3.3.2 Timer1とコンペアモードの設定
CCP1CON = 0b00001010 ;   // コンペアモード
T1CON   = 0b00100100 ;   // 分周1/4 クロック同期有効

TMR1IE = 1; // タイマ1割り込み有効
CCP1IE = 1; // コンペアマッチ割り込み有効

TMR1 = TMR1_OFFSET;
next = TMR1_OFFSET + 3000;  // 1.5msec

 

 今回はコンペアモードのソフトウェア割り込みモード(下位4ビットを1010)を使用するので以下のようにします。
CCP1CON = 0b00001010;

 Timer1を以下のように設定します。

 bit  設定値  内容
 bit2 1  内部クロックを使用する
 bit4~5 10  1:4プリスケール
 bit6~7 00  Timer1クロック源

T1CON = 0b00100100;

 Timer1の初期値を以下のように設定します。
TMR1 = 25536;
(サンプルプログラムではdefineを使用して定数にしています)

 

3.3.3 Timer1と割り込みを有効にする
TMR1ON = 1; // タイマ1 開始

TMR1IF = 0;
CCP1IF = 0;
PEIE = 1;
GIE  = 1;    // 全割り込み有効

 

 Timer1を開始する。
TMR1ON = 1;

 Timer1の割り込みフラグをリセットする。
TMR1IF = 0;

 コンペアモードの割り込みフラグをリセットする。
CCP1IF = 0;

 周辺機能割り込みを有効にする。
PEIE = 1;

 全割り込みを有効にする。
GIE = 1;

 

3.3.4 サーボの制御
for(;;)
{
    for(i=0;i<600000;i++)
    {
        // 処理なし(WAIT)
    }

    next = TMR1_OFFSET + 4000;  // 2msec

    for(i=0;i<600000;i++)
    {
        // 処理なし(WAIT)
    }

    next = TMR1_OFFSET + 2000;  // 1msec
}

 

 今回のサーボは以下のような値で制御を行います。

角度 1(Hi)にする時間
 -40度  1[ms]
 0度  1.5[ms]
 40度  2[ms]

注:ラジコンサーボにより、周波数が変わるので制御する対象により値を計算してください。間違った信号を出すとラジコンサーボが壊れる可能性があります。

 今回使用するサーボは、1.5[ms]の間、1(Hi)を出力すると0度に移動します。なので、Timer1の初期値である「25536」に1.5[ms]を加算した値をコンペアレジスタに登録します。
25536 + 3000
(今回の設定では、3000が1.5[ms]になります)
 以上のパルス信号を出し続ける限り、ラジコンサーボは0度を保持し続けます。

 

3.4 割り込み処理について

void interrupt ccp1( void )
{
    // タイマ1割り込み処理
    if( TMR1IF )
    {
        RA2 = 1;

        CCPR1 = next;
        TMR1 = TMR1_OFFSET;   // 20msec毎に割り込み
        TMR1IF = 0; // タイマ割り込みフラグをクリア
    }

    // CCP1割り込み処理
    if( CCP1IF )
    {
        RA2 = 0;
        CCP1IF = 0; // コンペアマッチ割り込みフラグをクリア
    }
}

 

 割り込み処理で出力するパルス信号を制御しています。

3.4.1 Timer1割り込み(TMR1IFが真のとき)

 Timer1の割り込みなので、周期の始まりを意味します。なので、RA2の出力を1(Hi)にし、コンペア割り込みの比較値を設定します。ここでコンペア割り込み用の比較値を設定することで、1周期の間に何度も割り込みを発生させないようにしています。
RA2 = 1;
CCPR1 = next;
 Timer1の割り込みフラグをリセットする。
TMR1IF = 0;

注:今回は決めた数値のみを出力するため行っていませんが、必ずラジコンサーボの仕様に合った最小値と最大値を超えないように設定してください。最悪ラジコンサーボが壊れます。

 

3.4.2 コンペア割り込み(CCP1IFが真のとき)

 コンペアモードの割り込みが発生したので、出力を0(Low)にします。
RA2 = 0;
 コンペアモードの割り込みフラグをリセットする。
CCP1IF = 0;

 

3.4.3 注意

 ラジコンサーボにより回転可能範囲や周波数が変わります。使用すラジコンるサーボに合った信号を出すようにしてください。ラジコンサーボが壊れる可能性があります。

 

3.5 ソースコード

 プログラムの全文を掲載します。

  プログラム

<注意>
本サイトの注意事項を確認してください。
ソースコードや回路図などを使用する場合、上記注意とともに、自己責任でお願いします。

 

   

 

4.動作確認

 サンプルソースでは下記の動画のような動きをします。ラジコンサーボの後ろにあるオシロスコープに出力している信号が表示されています。ただしオシロスコープの表示には少し遅れがあるので、ラジコンサーボの動きとは完璧に同期はしていません。オシロスコープの目盛りの単位は以下の通りです。

目盛りの説明
 横軸  1[ms]
 縦軸  2[V]

 動作は以下の通りです。

  1. 0度に回転
  2. 待ち
  3. 40度に回転
  4. 待ち
  5. -40度に回転
  6. 待ち
  7. 3~6を繰り返す

 本ページ最初の動画と同じ動画です。ここまでの流れを理解してから見ると、後ろのオシロスコープが何を示しているかなどがわかると思います。

 

<更新履歴>

新規作成:2015年4月20日
第2版:2016年9月30日:フォーマット変更(内容の変更はなし)

 

ラジコンサーボを動かす」への4件のフィードバック

  1. こんにちは!
    電子工作はじめたばかりの初心者です。

    サーボの制御が良くわからず、あっちこっちのHPを見て回っていましたが、どれもよくわかりませんでした。
    こちらのページに、まさにやりたいことが載っており、大変助かりました。

    もう少しで、挫折するところでした(*_*;

    どうも、ありがとうございます。

    • お役に立てたようで良かったです。
      今後もYouTubeとサイトで色々掲載したいと考えているので、宜しくお願いします。
      もしご意見などありましたら参考にしたいと思いますので、お気軽にしていただけたらと思います。

  2. こんにちは。
    工作初心者です。
    ソースを手持ちのコンパイラー(HCPICP)で
    上手くコンパイルされません
    コンパイル後のデーターはございませんでしょうか
    ぜひこのプログラムで現在作成中の工作に
    組み込みたいと思っております。

    • 返信が遅くなり申し訳ありません。

      今更かもしれませんが、回答します。
      色々な問題により、実行ファイルの配布は行っていません。

      MPLAB-Xを使用すればそのままコンパイル可能なので、そちらを使うことはできないでしょうか。
      本サイトで簡単ですが使用方法もまとめています。
      (MPLAB-Xは無料で使用できます(2018年12月5日現在))

      使ったことがないのでよくわかりませんが、ちょっと調べたところではHCPICPはPICのF1シリーズに対応していないのではないでしょうか。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)