サーボがどのようなモーターかを知るため、制御面の特徴をDCモーター(模型工作でお馴染みのマブチモーターなど)と比較してみます。
SG-90というサーボが安価で入手性がよく、趣味の電子工作ではポピュラーです。
メーカー:Tower Pro Pte. Ltd.
商品にはサーボホーン(サーボの軸に取り付ける十字型や円形のプレート)と固定用のネジが付属しており、すぐに工作に使えます。
データシートは、パルス出力に関する記述が異なるものがいくつか見つかりますが、
秋月の商品ページにあるものが正しそうです(下図)。
Arduino他、メジャーなプロトタイピング環境には大抵サーボ用のライブラリがあります。 サーボを動かすにはそれらを利用するのが簡単です。または制御プログラムを自前で用意します。動かし方の要点は下記の通りです。
サーボの端子はVCC,GND,Signalの3つです。マイコンからSignal端子へパルスを送り、サーボを動かします。 パルスはマイコンのPWM出力を利用するか、タイマー・カウンタ機能を利用してソフトウェア的に生成します。
パルスのデューティ比でサーボの回転角が決まります。
サーボは動作範囲の真ん中を「0°」と表現し、±60°程度の範囲で使用するのが一般的です。
※動作範囲の広さが売りのサーボもあります。
SG-90は±90°の範囲で動作します(サーボホーンが180°動く)。ただし、個体によるばらつきがあります。
サーボを動かすには、角度に応じたデューティ比でパルスをサーボへ送り続けます。
サーボは目的の角度に達した後、パルスを受信してもそれ以上は動きません(ジ、ジ、ジ、と音が出ることはあります)。
逆に、パルスを十分な回数送出しないとサーボが目的の角度に達しません。
基本的にサーボはマイコンから非同期で制御します。サーボがいつ動き始めるか、いつ止まったか、現在何度かを知る方法はありません。 ※一応データシートから、1パルスでxx度回転する「だろう」ということを計算できますが、あてになりません。
サーボは動作範囲(SG-90なら-90°~+90°)のうち、「いま何度かに関係なく、+30°の位置へ動いて」
「いま何度かに関係なく、-45°の位置へ動いて」という絶対的な位置(角度)で制御します。
サーボは、「いま何度か分からないけど、そこから25°右回転して」という相対的な制御には向いていません。
※角度の変化量を累積して現在の位置(角度)を把握するようにプログラムを組めば、相対的な制御を行うことができます。
プラ板と両面テープを駆使し、シーソーを作りました。センサーを載せた板がサーボによって傾きます。
※初めはバネが付いていました(写真:右)。 ところがサーボで押し下げるとバネの力で装置がたわみ、正しく動いているか分かりにくかったのでサーボに吊す形にしました(写真:左・中)。 結果、リフトのようなものになってしまいましたが、「シーソー」で通します。
加速度センサーから得られる傾斜角と、出力側サーボの回転角は比例しません。サーボホーンの動きは円運動だからです。 従って、傾斜角から計算によって回転角を求めるのではなく(その方法だとサーボホーンの長さを変えたらプログラムの修正が必要)、 サーボを動かしながら随時傾斜角を見て、水平になった時点で止めています。
この装置では2個のサーボを異なる方法で制御しています。
ボリュームで右のサーボを動かすと、真ん中のセンサーが水平になるよう、左のサーボが動く。一応狙い通りの動きはできてるんだけど、シーソーがたわんで上手く動いてるように見えない(^^; バネ使わずに作り直そう。 pic.twitter.com/leys4oeTJ6
— 『昼夜逆転』工作室 (@jsdiy) 2019年5月17日
マイコンとサーボ間の配線をまとめるため、サーボ接続用の基板を作りました。 電解コンデンサは470uF。USBコネクタは電源供給のためです(ピンソケットからも給電可)。
マイコンはATmega88を使用しています。上位互換のATmega328Pでも動作します。
ボリュームはマイコンのADCピンに接続しています。
加速度センサーとデバッグ表示用のLCDはI2Cでマイコンに接続しています。
MPU6050の6軸のうち、加速度センサーのX軸の回転角のみ使用しています(装置への取り付け方向の都合で)。
サーボ2個はマイコンの汎用IOピンに接続しています。ソフト的にH/Lを出力し、パルスを生成しています。
サーボは他の部品より電流を食います。2個なら5V/1.5A以上のACアダプタ等を用意した方がよいと思います。
入力側サーボによりシーソーが傾いたら、水平になる方向へ出力側サーボを動かし、
水平を通り過ぎたら出力側サーボを逆回転し、また通り過ぎたら逆回転し…。
逆回転の度に変化量を小さくし、だんだん水平に近付ける。
このプログラムではそのような制御をしています。
出力側サーボの変化量の初期値が小さければ(例えば1°)、シーソーはなめらかに水平に近付きます。
ただし、シーソーの傾きが大きいほど水平になるまで時間がかかります。
初期値が大きいと(例えば10°)、シーソーは何度も水平を通り過ぎ、ガタガタと水平に近付きます。
その代わりシーソーの傾きが大きいとき、水平になるまでの時間は短縮されます。
シーソーの傾きの大きさによって変化量の初期値を変える方法も考えられますが、
初期値を与えるタイミングを判断する処理が複雑になりそうです。
※入力側サーボの回転速度と回転角を監視する必要がある。
マイコンのタイマー・カウンタ機能を利用し、メインループとは非同期に、複数のサーボを見かけ上同時に動かす。
このプログラムではそのような制御をしています。
1回の割り込みで1個のサーボにパルスを送ります(Lo状態からHi、続けてLoを出力)。
SG-90のパルス期間は20ms、Hi時間は最大2.4ms(-90°から+90°へ動かすとき)なので、仮に3.3ms毎に割り込みを掛ければ6個のサーボを制御できることになります。
※パルス出力の処理時間を無視すれば、20ms / 2.4ms = 8.3個制御可能。現実的に6個とすれば、20ms / 6個 = 3.3ms以内で1個処理する。
実際にはマイコンの動作クロック(精度と速さ)やプログラムの組み方により、必ずしもこの通りになりません。 しかしSG-90のパルス期間には許容範囲があり、20ms以上/以下でも動作するので(限度はある)、この方法で動作しています。
<------ パルス期間 20ms -----> : : +-----+ +-----+ サーボ1 ---+ +-----------------------+ +---------------------- : +---+ +---+ サーボ2 ---------+ +-------------------------+ +------------------ : +-------+ +-------+ サーボ3 -------------+ +---------------------+ +---------- : : <- Hi時間の合計 -> ←20ms以内であること
サーボの実験装置と制御プログラムを作成しました。サーボの動かし方がだいぶ分かるようになりました。 「動く電子工作」ができるようになりました。工作の幅が広がって楽しい!