■ホビーロボット部品の製造・販売 
  モータコントローラ、センサ、音声、画像、無線モジュールなど、
■ホビーロボット制作記事のページ (各種マイコン、PCとの接続事例)
■特殊メイク、特殊材料の販売 ※特殊メイクのコーナーはこちらに移りました。
Top(お知らせ) 製品紹介 使い方とサンプルプログラム 通信販売 リンク ロボット掲示板 会社案内
 Easy Robotics for all enthusiastic people!!!  ---HOBBY ROBOT PARTS SHOP ASAKUSAGIKEN---   Since 2003...

A33F RCサーボの駆動
はじめに

 
ここではRCサーボの駆動について説明します。これにはTIMERと割り込み機能を使いますので、前のページを読んでいない方はまず前のページを読んでください。

 

 ※このページで紹介する内容はあくまでも一例です。個別の作成のご相談ご質問はお答えできませんのでご了承下さい。このページと同じ内容についてのご質問についてはロボット掲示板にてお願いいたします。

 ※以下の情報は2007年12月現在のものです。ご注意ください。


 ※このページではC言語の基本的な部分を理解している方向けに書いてあります。また、何回かMPLABの操作を行った方を対象にしています。それ以外の方はまず基本編を読んで下さい。



RCサーボの概略

 RCサーボはラジコン用の玩具サーボで、もともとは車や飛行機のラジコン用のものでしたが、最近はロボットの関節として使われており、ラジコンメーカーからロボット専用のものも出ています。

 RCサーボにはマイコン、モータ、減速ギア、位置センサ(ポテンショメータという)で構成されており、信号によって止まる角度を変えます。

 ラジコン用では90度の範囲までしか回転しないものがあります。また、デジタルとアナログという2つの形式があります。デジタルは信号をデジタルで処理しますので止まる位置などが比較的正確です。アナログはサーボをアナログ制御しますので価格が安いというメリットがあります。デジタルの場合は規定よりも超えた信号を入力すると、超えた部分は無視したりサーボのパワーが自動で切れたりしますが、アナログの場合は限界以上に回転しようとして破損の原因となったりします。

 ラジコン未経験でロボットを作る方に多いのに、電源の問題があります。RCサーボの駆動電源は4.8Vか6V(又はその間)のものが多いのですが、単に6Vを加えたから動くというものではなく、一般的な電子回路よりも大きな電流が流れますので

 1)電源ラインの経路が細すぎる、燃えたりする

 2)電源にアルカリ乾電池などの内部抵抗が大きいものを使い、6Vを作っても動かない

 というのがあります。2)はニッカドやニッケル水素、もしくはリチウムポリマーのようなラジコン用のバッテリを使うことで解決します。また、ACアダプタなどを使う場合は、100Vからとっているから十分に電流が流れるだろう、と勘違いする場合が多いのですが、ACアダプタの方がバッテリなどよりも電流は流せませんので注意して下さい。ロボットの実験などで使うAC電源は無線機用の強力なものが必要です。筆者は無線用の30Aが出力できるものを使用しています。

 RCサーボについては書籍やインターネットなどでいろいろと情報が公開されていますので検索してみてください

 RCサーボは浅草ギ研でも販売しています。


RCサーボの動作仕様

 RCサーボからは線が3本でています。ほとんどの場合は3本が接着された3並列線になっています。また、コネクタは2.54mmピッチ(端子間の距離をピッチという)のメスになっています。

 信号線 :パルス状の信号を入力する。白、青、黄色、オレンジの色が多い。
 電源線+:モータと基板の電源+。3並列の真ん中の線。色は赤が多い
 電源線−:GND。黒か茶色が多い。

 パルスは大体15〜20mS周期の0.5〜2.5mS幅のHIGHパルスを加えます。パルスの幅によって回転する位置が変わります。
 
 下は一般的なサーボの駆動仕様を図にしたものです。あくまでも一般的なものであり、機種によってはことなる場合があるので注意して下さい。特に、パルスに対する回転位置と回転方向はバラバラです。あくまでも目安として下記がありmす。
 <-あくまで一例です。


 前回は一定の間隔でLEDを点灯/消灯しました。つまり、一定の間隔で、決められた幅のHIGHのパルスを作ることも同じやりかたで実現できます。つまり、TIMERと割り込みを使います。

 パルス信号の生成時の注意ですが、サーボによっては信号入力端子が「オープンドレイン」になっているものがあります。オープンドレインの機器とマイコンを接続する場合には「プルアップ(信号線を抵抗でHIGHに接続する)」する必要があります。たとえば、近藤科学社製のロボット用サーボはオープンドレインになっていますので注意して下さい。つまり、普通にマイコンの端子を信号線につないでも、マイコンからHIGHを出力しても信号線がHIGHになりません。オープンドレインについては検索してみてください


A33F-EXの説明

 RCサーボは先に説明したとおり、3種類の端子があります。ということで、RCサーボ用に3種類の端子を用意したオプションボードを用意しました。端子はプルアップされていないので注意して下さい。A33F-EXはRCサーボ用のポートが30個あります。また、その他にDCモータなら4つ、ステッピングモータなら2つを駆動するドライバICも搭載されています。

 取り付け方法についてはA33Fのページを参照してください。



A33F-EX2の説明

 A33F-EX2はサーボポートが32個あり、全てオープンドレイン入力サーボ対応となっています。DCモータドライバは付いておりません。

 取り付け方法についてはA33Fのページを参照してください。


RCサーボの駆動プログラム

 以下、A33F-COREにA33F-EX1が接続された状態として説明します。A33F-EX2の場合も基本的には同じです。
 


<使用するタイマーの選定>

 使用するタイマですが、番号が小さい方のタイマは特殊機能と連携する場合がある(例えば、出力比較モジュールはTIMER2を使用する、など、)ので、なるべく大きい番号の方からつかっていくことにします。


<パルスと割り込みの関係>

 まず、周期20mSでパルス幅が1.5mSのパルス、つまりサーボを中心位置にするパルスを考えて見ます。時間の測定はパルス周期とパルス幅の2つが必要になります。よって、ここではパルス周期をTIMER9、パルス幅をTIMER8で計測することにします。

 動作としては、パルス周期20mSで発生する割り込みプログラムが起動したら、パルス幅を測定する割り込みを有効にすればパルスの始まりと終りを測定できることになります。

 


<タイマーの解像度>

 TIMER8とTIMER9は2つを合わせて32ビットのタイマーとしても使用できますが、RCサーボの駆動程度でしたら16ビットタイマーで十分だと思われます。


<20mSを考える(TIMER9)>

 前ページのように、Tcy(タイマのクロック源:Fcy(CPUクロック)と同じ)を36.85MHzで動作させるとします。プリスケーラなしで、一秒間に36,850,000カウントされますので、20mSだと1/50で737,000カウントとなります。これでは16ビットでカウントできないので、プリスケーラで分周を考えます。

 1/1:737,000カウント
 1/8:92,125カウント
 1/64:11,515.625カウント
 1/256:約2,878.9カウント

 ということで16ビットでカウントできる最大数値の65535以下の、1/64か1/256となります。今回は1/64で11,516カウントで約20mS(プラスアルファ)という周期にします。


<パルス幅を考える(TIMER8)>
 パルス幅は0.5mS〜2.5mSで可変となります。プリスケーラなしだと0.5mSで18,425、2.5mSで92,125カウントとなります。

プリスケーラ 0.5mS 2.5mS
1/1 18,425 92,125
1/8 2303.125 11,515.625
1/64 287.89062 1,439.4531
1/256 71.972656 359.86328

ということで、1/8だと16ビットで収まり、かつ解像度も11515−2303=9212段階となります。


<サーボパルスを出力する端子>

 これはどこでも良いのですが、とりあえず、はじめのテスト用として一番端にあるG6端子を選びました。
 下はG6端子、マイコン的にはRG6端子の拡大です。手前側がRG6につながっており、真ん中の列がサーボ用電源コネクタの+、奥の列がGNDつまりサーボ用電源の−側です。逆側にもサーボ用のポートの列がありますが、逆がわはこの逆の配置になりますので注意して下さい。(基板上に白字で位置が書いてありますのでそれを参考にして下さい。)
 


 ということで書いてみたのが次のプログラムです。(右クリックで対象を保存)

 RCServo1.c

 まずはメインから解説します。行65〜73はいままでと変わらない部分なので説明を割愛します。
 行74でRG6を出力に設定してます。
 行76〜80はTIMER9の設定でプリスケーラは1/64、比較レジスタには11516を入れて、割り込みを有効にすると20mS間隔で割り込みが発生するようにしています。
 行82〜84はTIMER8の設定です。TIMER8はパルス幅を作るので、TIMER9割り込み内で起動させます。プリスケーラは先に計算したとおり、1/8に設定しています。
 
 行90でTIMER9割り込みをスタートさせています。
 行92〜98はLEDを3回点滅させています。いままでのプログラムでよくこれが出てくるのですが、このように「確実に動くことがわかっているプログラム」を開始時に入れることにより、デバックの手間が減ります。特に、一番初めにプログラムを転送して動かす時には思いもよらないバグがひそんでいる可能性がありますので、デバック実行する瞬間はLEDをよく見て3回点滅しなかったらすばやくデバックを停止させる準備をしておくと、被害が少なくてすみます。
 パルスのHIGH/LOWは全て割り込み内で処理されるのでmainの関数内では設定以外は特にすることはありません。今回はservoPosというグローバル変数を作り、これをサーボ位置にします。TIMER8の値は0.5mSで2303、2.5mSで11515なので、2303+servoPos でパルス幅を作り、servoPosを0〜9212に変化させることで0.5mS〜2.5mSを作ることができます。今回はservoPosが4606つまり0.5mSと2.5mSの中間位置、つまり1.5mSで固定のパルス幅の設定となっています。この時、RCサーボは中心位置に止まるはずです。

 次は割り込み部分です。ここは先の<パルス幅と割り込みの関係>のところの図そのままです。とにかく20mSごとにRG6はHIGHになって、そこから設定された時間になるとTIMER8割り込みが発生してLOWになるというものです。
 


 さて、実際にサーボを駆動したいところですが、サーボのように大きな電流を使う機器を使う場合には、極力事故がないようにしたいものです。ということで、できれば、サーボをつなぐまえに、本当に意図したとおりのパルスが出ているかをオシロスコープなどで観察した方がよいでしょう。
 

 実行すると、1.5mSのパルス幅が20mS間隔で出力されました。
 


 安全に動きそうな感じなので、今度はサーボをつないでみます。
 
 すると、意図したとおりに中心位置に回って止まりました。手で多少曲げようとしても中心位置を保持しつづけます。

 さて、どうやら上手くうごいていそうなので、今度はサーボの位置を動かしてみます。サーボの位置はservoPosの値を変えることによって動きます。今回使っている写真のサーボは、パルス幅の仕様が0.6mS〜2.4mSというものなので、その範囲で動かすような値をセットしてみます。先ほどのプログラムのmain関数のwaile(1)ループの中を次のように変えてみてください。
 
 実験の結果、左右に90度づつ回転しつづけました。尚、この実験は、サーボによっては回転範囲外になる可能性があるので、このように極端な数値変化ではなく、使いたいサーボを中心位置からじょじょに曲げていってどのぐらいが限界かをたしかめて下さい。アナログサーボは仕様以上にまわろうとするものもあり、過電流が流れて非常に危険です。この場合、最悪はサーボが燃えます。ロボットを作っているとサーボが燃えることが本当によくあるので注意して下さい
 デジタルサーボの場合は、範囲外のパルス幅を入力するとサーボが停止する場合があります。たとえば、オプションボードをA33F−EX2にして近藤のデジタルサーボを駆動してみると、値460は無反応になりますので、一見、サーボが中心位置から動いていないように見えます。*近藤サーボの場合は信号入力線がオープンドレインの場合が多いので、EX2でないと動かないものもあるので注意。


ゆっくり回転させてみる

 RCサーボの最高回転速度はサーボによって違います。サーボの仕様に速度があるので確かめてみてください。逆にゆっくり動かすのはプログラムで制御できます。

 サーボは20mS間隔(又はサーボの仕様の間隔)で自分の位置を制御しつづけます。ということは、時間をかけて少しずつパルス幅を変えれば見た目上ゆっくり動くことになります。

 では、10秒かけて90度を回転させるプログラムを考えて見ます。今回使用したサーボは0.6mSで90度、1.5mSで中心位置になります。ということは値は460〜4606になり、この変化を10秒かけて行えばよいことになります。(この計算はサーボによって違いますので注意して下さい。)
 <-サーボによってパルス幅と角度は違います。注意。

 サーボの位置制御周期が20mSなので、20mS近い間隔で値を変化させてもあまり意味はありません。ということで例えば100mSごとにすこしづつ位置を変えてそれを100回行って10秒とします。変化量は4606−460=4146で、これを100で割ると約41となりますので、100mS毎に41変化させると10秒で90度変化になります。

 今度はwhile(1)のループを次のように変えてみてください。
 
 実行の結果、10秒で90度曲がりました。しかし、この値では少々動きがギコちない感じでしたので、もっと少ない変化量にしてみます。
 
 思い切って10倍の解像度(ループ回数も10倍)にしてみました。さっきよりはスムーズに動くようになりました。
 



複数のサーボを動かすには?


<まず8個を考える>

 サーボ周期は20mSで、パルス幅は2.5mSが最大です。ということは、20mSを2.5mSづつ分割すると、8個のサーボを駆動することができます。つまり、TIMER9の割り込み周期を2.5mS周期にして、TIMER9割り込みが発生する度に、HIGHにする端子を変えればよいことになります。

 


<やってはいけないパターン>

  パルス発生のパターンは上以外でもいろいろあるかと思いますが、やってはいけないパターンに、「同時に沢山を立ち上げる」というのがあります。サーボは動き始めに非常に大きな電流が流れます。よって、パルスを一斉にONにするようなプログラムを作ると、バッテリや電源のサーボへの供給が追いつかずに、意図しない動きになることがありますので注意して下さい。ということで、とりあえず8個のサーボを動かすには上の図のパターンが最良だと思います。


<実際のプログラム>

 各サーボを動かすところを各フェーズとします。0番サーボを動かすところは0番フェーズ...というようにします。2.5mS周期でTIMER9割り込みを発生させ、各フェーズでパルスをONにする端子を変えるというプログラムを作りました。(右クリックで対象を保存)


 RCServo2.c


 まず、サーボの個数が8個になったので、位置情報を表す変数も8個になります。配列の方が扱いやすいので配列で宣言しました。また、フェーズを表すのはphaseという変数を用意しました。数値の設定やフェーズの変化は関数間にまたがる処理なのでグローバル変数で宣言します。(配列、グローバル変数については基本編で解説してます)
 


 次にmain部です。サーボの信号出力が8個になりましたので8個の端子を出力に変えています。尚、dsPIC33Fでは初期設定は入力(1)に設定されていますので、出力にするには必ず各TRISレジスタを設定する必要があります。行142〜行149の部分です。尚、適当に全部0に設定すればよい、と思うかも知れませんが、出力に設定した端子が、なにかの拍子で電圧が出ているものに触ると問題が起きますので注意して下さい(出力同士をつなげるのは電子回路ではNG)。そういう理由で初期設定は入力になっています。
 行161〜164でサーボの位置とフェーズ番号の初期設定をしています。
 
 その他は以前と同じです。while(1)ループでは8個のサーボに対して1秒ごとに位置を変えるプログラムにしています。

 次は割り込み部です。パルス立ち上げと立ち下げ部は別な関数にしていますが、ほとんど前と同じです。
 
 フェーズは8回実行したら元にもどす必要があります。行124〜125でフェーズ変化を制御しています。

 パルス立ち上げ部の別関数は次のようになっています。引数でフェーズを受け取り、該当する端子を操作しています。尚、端子はA33F-EX1の端子の並び順にしています。
 


 ということで実行してみましたが、8個の端子でサーボが動いていることを確認できました。main関数の中で、任意のタイミングでservoPos[?]の変数の該当する番号の値を変えれば、その端子のサーボが動きます。


<8個以上を考える>


 TIMERは他にもあります。上のプログラム例ではTIMER1がwaitを作り、TIMER9が周期を作っています。各サーボのパルス幅はTIMER8で8個のサーボを担当しています。例えばあと3個のタイマーを使ってTIMER8の役割を与えれば、タイマー4個x8=32個のサーボを動かすことができることになります。

 この部分は作っていませんが、各自実験してみてください。尚、注意点として、先にも挙げたとおり、なるべく同時起動は避けるようにしましょう。TIMER8の役割が複数になると、同時起動のタイミングも出てきます。実験の結果、同時2個ではほとんどの状況(サーボの種類、(サーボ用)電源)で問題なく動きました。


<端子配列の注意>


 RCサーボを動かす場合はオプションボードのA33F-EX又はA33F-EX2を使うことになりますが、A33F-EXの方はいくつかの端子がDCモータ駆動(又はステッピングモータ駆動)端子と共通になっています。以下の端子はDCモータ駆動時にはRCサーボ駆動には使えませんので注意して下さい。

基板上の表示 DCモータ端子と共通
D4 OC5(RD4)
D5 OC6(RD5)
D6 OC7(RD6)
D7 OC8(RD7)




おわりに

 次は出力比較モジュールを使ってPWM制御でDCモータを動かしてみます。


2007年12月3日

 
(C)Copylight 2003. 有限会社浅草ギ研 | 通信販売の法規(訪問販売法第8条)に基づく通信販売業者の表示