こんにちは。駆け出しエンジニアのまっきーです。
さて、今回は前回の応用編!ということでサーボモータの制御を行ってみたいと思います。
今回はいろいろと試行錯誤をしたので、その過程も参考にしていただければと思います。
サーボモーターとは

サーボモーター (Servomotor) とはサーボ機構において位置、速度等を制御する用途に使用するモーターである。モーターの種類としては、「電動機」、「油圧モーター」など、特定のモーター形式を示すものではない。しかし、現在は、ロボット用途などに使用される「検出器付の電動機」で、フィードバック制御するものが一般的である。(wikipedia)
サーボモーターは通常のモーターに回転角度を検出する機能がついていて、その信号を通信することができるため、回転角度を制御することが可能だそうです。
今回は、写真と同様の、Micro Servo – SG90を使用します。
下記のセットに付属していたものです。
データシートを見ると、0度~180度まで制御できるそうです。
目的
今回の最終ゴールは、「サーボモータの角度を意図したとおりに制御すること」です
どのように制御するか
サーボモータデータシート(https://osoyoo.com/2017/05/08/micro-servo-mg90-9g/)を確認すると以下のようになっています。

パルスONが1.5msで真ん中(0度)、2msで右側(90度)、1㎳で左側(90度)だそうです。
図にするとこんな感じでしょうか。(適当ですみません。。。)

各値の設定の前に、前回の復習をします。
T = 100us * range
f = 1 / T = 1 / 100us * range
T PWM信号の周期
f PWM信号の周波数
range 階調(1周期を何個に分割するかを表す)
100us 最小変化幅(ソフトウェアの場合は100usで固定でいいと思います)
上の計算式で求められるんでしたね。
データシートより、周波数50Hzとあるので、これを上の式に当てはめてとくと…
range=200となりました。
次に、1㎳~2㎳のパルス波をどのように作るかを考えます。

図より、2㎳の時のrangeは20なので
1㎳も同様に考えrangeは10
つまり、10~20の値で動かせば角度を制御できるはず?
実装
回路図
データシート通りの回路になります。ブレッドボードは使用しません。

プログラム
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#include <stdio.h> #include <wiringPi.h> #include <softPwm.h>//softPWM header #define SERVO 19 int main(void){ double ton = 0;//initial value wiringPiSetupGpio(); //pinMode(LED,OUTPUT); softPwmCreate(SERVO,ton,200); while(1){ for(ton = 10;ton <= 20;ton++){ softPwmWrite(SERVO,ton);//pulse on value delay(300); } } return 0; } |
全然180度制御できてないですね…
改めて考える
いろいろ考えたんですけど、わからなかったので一つずつ値を入力し、順番に角度を見ていくことにしました。
下記のプログラムを実装したところ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include <stdio.h> #include <wiringPi.h> #include <softPwm.h>//softPWM header 忘れずに! #define SERVO 19 int main(void){ double ton = 0;//パルスONの初期値 wiringPiSetupGpio(); //pinMode(LED,OUTPUT); softPwmCreate(SERVO,ton,200); while(1){ scanf("%lf",&ton); softPwmWrite(SERVO,ton); } return 0; } |
5~25の値で0度~180度制御させることができました。
これを踏まえて、改めてプログラムを考えていきます。
再実装
回路図は先ほどと全く同じです。
プログラム
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#include <stdio.h> #include <wiringPi.h> #include <softPwm.h>//softPWM header #define SERVO 19 int main(void){ double ton = 0;//initial value wiringPiSetupGpio(); //pinMode(LED,OUTPUT); softPwmCreate(SERVO,ton,200); /******servo action check******/ /*5~25 while(1){ scanf("%lf",&ton); softPwmWrite(SERVO,ton); } *******************************/ while(1){ for(ton = 14;ton <= 25;ton++){ softPwmWrite(SERVO,ton);//pulse on value delay(300); } for(ton = 14;ton >= 5;ton--){ softPwmWrite(SERVO,ton);//pulse on value delay(300); } } return 0; } |
動画のように、右に行ったり、左に行ったりする180度制御できるようになりました!
考察・まとめ
最初の計算で合っていたと思うのですが、なぜ制御できなかったのかあまり分かりません。
ネットで下記のようなデータシートも見つけました。

この場合は0.5~2.4㎳で制御できると書いてあります。
このデータシートに従うと、納得できるんですが…
とにかく、一つずつ確認することにより、サーボの制御は行うことができるようになったのでいつかは、ハードウェア方式でも挑戦してみたいと思います。
ありがとうございました。
参考書籍(C言語ではじめる RaspberryPi徹底入門)