ロボットを構成するサーボモーター
 |
サーボモーターは、PWM(パルス幅変調)の信号指令により指定角度位置に移動するデバイスです。あるパルス幅(停止点、例えば1ms)より狭ければ正回転、広ければ逆回転するのがサーボモーターです。
下記の図で、1msと書かれている幅(Duty Cycle)が角度情報になります。SG90の資料はこちら
|
 |
BrainPadの上部に出力ピンがあります。左側がサーボモーター用で右側がDCモーター用です。
ピンのすぐ上部左側に~と印字されているところが信号線で、ここで用いるSG90の場合はオレンジの色です。-がグラウンド(接地)で茶色の線、真ん中の+は電源で赤の線になります。接続を間違えないでください。
|

この指令の値は各サーボモーターによって異なります。従って、BrainPad.csには取りあえずの数値が入っているだけで、そのまま使っても正しく動作するとは限りません。以下の部分をソースファイルから探してください。
BrainPad.csのこの部分を探す |
public static void SetPosition(int position) {
if (position < 0 || position > 180) throw new ArgumentOutOfRangeException("degrees", "degrees must be between 0 and 180.");
Stop();
output.Period = 20000;
output.Duration = (uint)(1000.0 + ((position / 180.0) * 1000.0));
Start();
}
|
ここで用いるSG90の場合は、Duty Cycleが0.5~2.4msですので、正確には
500.0 + ((position / 180.0) * 1900.0)
この式の単位はμ秒です。
となりますが、個体差もあるので、実際に測定するのが良いでしょう。取りあえずそれらしく動かすだけならば、この式を用いてください。
以上の作業を行った上で、以下のサンプルプログラムを動かしてください。ただし、本当に180度動くかどうかはサーボモーターの仕様で決まります。
プログラム |
void main()
{
BrainPad.Display.Clear();
int step = 5;
BrainPad.ServoMotor.SetPosition(0);
BrainPad.ServoMotor.Start();
while (true)
{
for (int i = 0; i < 180; i += step)
{
BrainPad.ServoMotor.SetPosition(i);
CPU.delay(30);
}
for (int i = 180; i > 0; i -= step)
{
BrainPad.ServoMotor.SetPosition(i);
CPU.delay(30);
}
}
}
|
1
2
3 関係ないが、ディスプレイを消去
4 5度ずつ移動させる予定
5 サーボモーターの初期位置(移動はしない)
6 サーボモーター動作開始
7 永久ループ
8
9 0度からstep(5度)刻みで180度まで移動する予定
10
11 サーボモーターを移動させる
12 推定移動時間
13
14 逆方向に回転させる
15
16
17
18
19
20
|
サーボモーターを光量メーターにする
CdSで測定した光量をサーボモーターで指示させてみます。
暗くすると左に回るようにします。
光量メータ |
void main()
{
BrainPad.Display.Clear();
BrainPad.ServoMotor.SetPosition(0);
BrainPad.ServoMotor.Start();
while (true)
{
int light = (int)((1-BrainPad.LightSensor.ReadLightLevel()) * 180);
BrainPad.ServoMotor.SetPosition(light);
CPU.delay(100);
}
}
|
1
2
3 ディスプレイ消去
4 ゼロの位置に設定
5 サーボ始動
6 永久ループ
7
8 光量測定値を角度にする
9 サーボモーターに動作指令
10 100ms待つ
11
12
|
拡張コネクタにサーボモーターをつなぐ
BrainPadではボードの上部のピンの一つしか利用できません。ここでは、サーボモーターを複数利用できるように別のServoMotorクラスを利用します。
接続は、下図の拡張コネクタのところのPWMと書いてあるところが利用できます。しかし、ほかのデバイスとの兼ね合いで必ずしも使えるとは限りません。ここでは、E9の場所のPWM6を用います。
従ってサーボモーターの信号(オレンジ)はE6、+電源(赤)はE15、-(黒)はE16に接続します。
下図はBrainPadに印刷されている文字とは異なりますが、回路的にはこのようになっています。
拡張サーボモーターを光量メーターにする
ここで用いるSG90の場合は、0.5msが最小パルス幅、2.4msが最大パルス幅であるから、設定は以下のようにします。単位はμsです。
ServoMotor(CPU.E9, 500u, 2400u);
拡張サーボ光量メーター |
void main()
{
BrainPad.Display.Clear();
BoeBotLib.ServoMotor sv = new BoeBotLib.ServoMotor(CPU.E9, 500u, 2400u);
sv.Start();
while (true)
{
int light = (int)((1 - BrainPad.LightSensor.ReadLightLevel()) * 180);
sv.SetPosition(light);
CPU.delay(100);
}
}
|
1
2
3 ディスプレイ消去
4 サーボモーターの設定、E9から信号が出る
5 サーボモーター動作開始
6 永久ループ
7
8 光量測定値を角度にする
9 角度位置に行かせる
10 時間待ち
11
12
|
サーボモーターを回転させる
基本的にサーボモーターの目的から言って回転するはずはありません。しかし、位置検出をさせないなどの改造を行えば、
それは可能になります。
このように改造したモータの特性は以下のグラフのような特性になります。

大体のスピードの直線性を利用するプログラムを作ってみます。それには、特性グラフの肩に当たる最低及び最大のスピードのパルス幅と停止位置のパルス幅を求める必要がありますが、ここでは、停止位置のみ正確に求め、後は体感的に設定してみます。本当は測定装置で求めるべきです。これらの値はサーボモーターによって異なります。
以下のプログラムは、パルス幅が900μsから1000μsの間にあるはずとあたりをつけています。実際にはこの間にあるとは限りませんので、この値を変更する必要があります。
停止位置を求めるプログラム |
private void main()
{
uint step = 5;
BoeBotLib.ServoMotor sv = new BoeBotLib.ServoMotor(CPU.E9);
sv.Start();
while (true)
{
for (uint i = 900; i <= 1000; i += step)
{
sv.SetSpeed(i);
Debug.Print(i + " ");
CPU.delay(500);
}
for (uint i = 1000; i >= 900; i -= step)
{
sv.SetSpeed(i);
Debug.Print(i.ToString());
CPU.delay(500);
}
}
}
|
1
2
3 カウント幅
4 E9のPWMを用いる
5 PWM開始
6 永久ループ
7
8 900μsから1000μsまで
9
10 パルス幅の変更
11 VisualStudio側に表示
12 500ms待つ
13
14 1000μsから900μsまで
15
16 パルス幅の変更
17 VisualStudio側に表示
18 500ms待つ
19
20
21
|

VisualStudioの右下の出力の部分に表示されます。サーボモーターが止まった時に表示されている数字が停止するパルス幅です。
ここでは、正回転を920μs、停止点950μs、逆回転を980μsとしていますが、各モーターによって異なっても不思議はありません。各自チェックしてください。正回転、逆回転は正確である必要はありません。move()メソッドの引数の単位はパーセントです。100は正回転で最速、-100は逆回転で最速となります。
正逆回転スピードチェック |
private void main()
{
BrainPad.Display.Clear();
int step = 5;
BoeBotLib.ServoMotor sv = new BoeBotLib.ServoMotor(CPU.E9, 920u, 950u, 980u);
sv.Start();
while (true)
{
for (int i = -100; i <= 100; i += step)
{
sv.move(i);
CPU.delay(500);
}
for (int i = 100; i >= -100; i -= step)
{
sv.move(i);
CPU.delay(500);
}
}
}
|
1
2
3
4 5%ずつスピードを変化させる
5 拡張コネクタのE9にサーボモーターを繋げる
6 +方向100%スピードの幅920μ秒、停止950μ秒
7 -方向100%スピードの幅980μ秒で、信号スタート
8
9 -100%のスピードから+100%のスピードで回転予定
10
11 指定のスピードで回転させる
12
13
14 逆シーケンス
15
16
17
18
19
20
|