Arduinoで制御できるものはいろいろとありますが、電子工作用途で何か動くものを作ろうと思えばまず思い浮かぶのがサーボモーターだと思います。
サーボモーターはDCモーターの一種となりますが、回転する角度を制御出来ることからラジコンのステアリングやアームの関節部分、歩行ロボットの脚などに使うことが出来ます。
サーボモーターの制御にはPWM(Pulse Width Modulation)というパルス幅変調という制御方法が使われています。
一定周期内のHIGHの時間(パルス幅)を変えることにより制御する方法となり、サーボモーターの角度制御やLEDの点灯照度を制御したり、モーターの回転数を制御したりとデジタル信号を使いアナログ的な動作をさせることも出来ます。
そしてサーボモーターの制御にはこのPWM制御が使われています。
前回、デジタル入出力ピンを使いPWM信号を作りサーボモーターを動かすことによりその動作原理について理解できたかと思います。
そしてArduinoにはサーボモーターを動かすための「Servoライブラリ」という便利な標準ライブラリが用意されているのでPWMについてあまり意識することなくサーボモーターを動かすことも出来ました。
今回はこれまでやってきたアナログ入力ピンからジョイスティックの動きを取得してそれに連動させサーボモーターを動かしたり、シリアルモニタからArduinoを介してPCからサーボモーターを動かしたりしてみたいと思います。
目次
サーボモーターをジョイスティックやシリアルモニタから動かしてみる!
今回の目標
前回、サーボモーターの動作原理についてご紹介しました。
サーボモーターは、PWM(Pulse Width Modulation)と呼ばれるパルス幅変調方式によって制御されます。
Arduinoを勉強していく上でPWMはよく登場する重要な項目となります。
PWMに関してこれまでanalogWrite関数を使いデューティー比を指定することによりLEDの点灯照度の制御やRGB(フラカラー)LEDの点灯などで使ってきました。


そしてサーボモーターも同様にこのPWM制御によって動かしています。
パルス1周期の中にあるHIGHの時間の割合(パルス幅やデューティー比)を変える事によりサーボモーターの回転する角度を指定して動かすといったものです。
実際にはArduinoにはサーボモーターを制御する専用ライブラリとして「Servoライブラリ」が標準で用意されており、PWMについてあまり意識しなくてもライブラリが代わりにこの部分を計算(処理)してくれるので比較的簡単に動かすことが出来ます。
前回、PWM制御の動作原理そしてServoライブラリを使って複数のサーボモーターを動かすところまでやってみました。

今回はその応用編として、これまでやってきたジョイスティックからの値をアナログ入力ピンから取得しサーボモーターを連動させ動かしたり、またシリアルモニタ(PC)からArduinoを介してサーボモーターを動かしてみたいと思います。
これまでやってきた事と組み合わせ、いろいろな方法でサーボモーターを動かせるようになるまでが今回の目的となります。
Servoライブラリを使った一連の流れ
Arduinoでサーボモーターを制御するにはServoライブラリという便利なライブラリが標準で用意されています。
前回の復習となりますが、Servoライブラリを使った一連の流れをまず見ておきます。
Servoライブラリを使ってサーボモーターを動かすこのような回路&スケッチを作ってみました。
1秒間隔でサーボモーターを0度→90度→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 | // Arduino入門編⑯ Servoライブラリを使いサーボモーターを動かす // https://burariweb.info #include <Servo.h> // Servoライブラリの読み込み Servo myservo; // Servoオブジェクトの宣言 const int SV_PIN = 6; void setup(){ myservo.attach(SV_PIN); // サーボモーターをD6に割り当てる } void loop(){ myservo.write(0); // サーボモーターを0度の位置まで動かす delay(1000); myservo.write(90); // サーボモーターを90度の位置まで動かす delay(1000); myservo.write(180); // サーボモーターを180度の位置まで動かす delay(1000); } |
[スケッチ]→[ライブラリをインクルード]へと進むとライブラリの一覧が表示されます。
そこから[Servo]を選択するとスケッチ内に#include <Servo.h>と入りライブラリが使えるようになります。
Servoライブラリを使ってサーボモーターを動かす手順はこのような流れになります。
#include <Servo.h>
サーボ名(myservo)は任意の名前でOKです。
サーボモーターを繋ぐピン(端子)を指定します。
デジタル入出力ピンD0-D13までとアナログ入力ピンA0-A5まで使うことが出来ます。
角度を指定して(またはパルス幅)サーボモーターを動かします!
ここまでは前回の復習となります。
ジョイスティックを使ってサーボモーターを動かしてみる
サーボモーターの動かし方が分かったところで、これまでArduino入門編記事としてやってきた事と組み合わせて動かしてみたいと思います。
まずはジョイスティックを使って動かしてみます。
X軸方向・Y軸方向のアナログ値の読み取りに加え、センタークリック機能によりスティックを押し込むことによりON/OFFの判定も出来る2軸タイプのアナログジョイスティックを使ってサーボモーターを制御してみたいと思います。
ジョイスティックの内部構造は簡単で、X軸(横方向)とY軸(縦方向)にそれぞれ可変抵抗器が使われ、スティックにはプッシュスイッチが内蔵されているものとなります。
こちらもこれまでの復習となります。
アナログタイプのジョイスティックを使うには、内蔵されている可変抵抗器の電圧変化をアナログ入力ピン(A0-A5)に入力しA/D変換により0-1023までの範囲の数値としてArduinoに取り込みます。(10bitの分解能)
そしてプッシュスイッチによるON/OFFの判定にはデジタル入出力ピンを使いますが、こちらはプルアップして使う形となります。
ジョイスティックの使い方に関してはこちらを参考にして下さい。

これまでやってきた事を組み合わせてこのような回路&スケッチを作ってみました。
X軸(横方向)とY軸(縦方向)に対応したサーボモーターがジョイスティックに連動して動きます。
そしてスティックを押すと両サーボが特定の位置(30度)に固定されるというものです。
分かりやすいようにロボットアームを1本用意して動かしてみました。
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | // Arduino入門編⑯ ジョイスティックでサーボモーターを動かす // https://burariweb.info #include <Servo.h> // Servoライブラリの読み込み Servo myservo1; // Servoオブジェクトの宣言 Servo myservo2; const int X_PIN = A0; // X軸方向の入力をアナログピンA0に const int Y_PIN = A1; // Y軸方向の入力をアナログピンA1に const int SW_PIN = 8; // センタースイッチの入力をデジタルピンD8に const int SV_PIN1 = 6; // サーボ接続ピンを指定 const int SV_PIN2 = 7; int X_POS; // X軸方向の読み取り値の変数を整数型に int Y_POS; // Y軸方向の読み取り値の変数を整数型に int SW_POS; // センタースイッチの読み取り値の変数を整数型に void setup(){ pinMode(X_PIN, INPUT); // A0ピンを入力に(省略可) pinMode(Y_PIN, INPUT); // A1ピンを入力に(省略可) pinMode(SW_PIN, INPUT_PULLUP); // D8ピンをプルアップして入力に myservo1.attach(SV_PIN1); // サーボ1をD6に割り当て myservo2.attach(SV_PIN2); // サーボ2をD7に割り当て } void loop(){ X_POS = map(analogRead(X_PIN), 0, 1023, 0, 180); // X軸方向のアナログ値を読み取る(0-180の範囲に置きかえる) Y_POS = map(analogRead(Y_PIN), 0, 1023 ,0, 180); // Y軸方向のアナログ値を読み取る(0-180の範囲に置きかえる) SW_POS = digitalRead(SW_PIN); // センタースイッチの状態を読み取る if(SW_POS == LOW){ // スイッチが押された状態では両サーボを30°の位置に固定 myservo1.write(30); myservo2.write(30); } else{ myservo1.write(X_POS); // X方向のサーボを動かす myservo2.write(Y_POS); // Y方向のサーボを動かす } delay(100); } |
このようにジョイスティックを動かし各サーボモーターを連動して動かすことができます。
この投稿をInstagramで見る
スケッチ解説
analogRead関数を使いX方向(アナログ入力ピンA0)・Y方向(アナログ入力ピンA1)の入力値の読み取り(0-1023の範囲)、digitalRead関数でプッシュスイッチの状態(HIGH or LOW)を読み取っています。
ここで重要な箇所が2点あります。
①内部プルアップ
まずデジタルピンをプルアップさせているという点です。
プッシュスイッチはON/OFFさせる単純なスイッチとなりますが、直接デジタルピンとGNDに繋いでON/OFFさせると不具合(不安定な動作)が起こります。
ONさせている時(回路がつながった状態)では問題ないのですが、OFFの時(デジタルピンに何も繋がっていない状態)はフローティング(宙に浮いた状態)となりデジタル回路では不安定な状態となります。
この状態を避けるために回路内にプルアップ抵抗やプルダウン抵抗を繋いで安定的に動作させる必要があります。
Arduinoの場合、内部プルアップ機能を有効(INPUT_PULLUP)にすることにより実際にこのような抵抗を繋がなくても内部的にプルアップさせ安定的に動作させることが出来ます。
23 24 25 | pinMode(X_PIN, INPUT); // A0ピンを入力に(省略可) pinMode(Y_PIN, INPUT); // A1ピンを入力に(省略可) pinMode(SW_PIN, INPUT_PULLUP); // D8ピンをプルアップして入力に |
プルアップ・プルダウンに関して詳しくはこちらを参考にして下さい。

②アナログ入力ピンの入力値はA/D変換される
次にアナログ入力ピンに入力された値はA/D変換(アナログ/デジタル変換)により0~1023の数値に置き換えられるという点です。
ジョイスティックの状態を読み取る場合、内蔵された可変抵抗器にかかる電圧の変化(0-5V)をアナログ入力ピンから読み取ります。
その際、Arduinoのアナログ入力ピンは10ビットの分解能(2の10乗=1024)を持っておりA/D変換により0-1023までの数値に置き換えられます。
電圧の変化をArduinoが処理できる数値に変換するというものですね。
アナログ入力ピンのA/D変換に関してはこちらを参考にして下さい。

つまりArduinoが読み取った0-1023の数値をサーボモーターの動く角度(0-180度)に対応させる必要があるということです。
上記スケッチではmap関数を使いこれを対応させています。
35 36 | X_POS = map(analogRead(X_PIN), 0, 1023, 0, 180); // X軸方向のアナログ値を読み取る(0-180の範囲に置きかえる) Y_POS = map(analogRead(Y_PIN), 0, 1023 ,0, 180); // Y軸方向のアナログ値を読み取る(0-180の範囲に置きかえる) |
応用例
今回ジョイスティックを例にアナログ入力ピンからの入力値をもとにサーボモーターを動かしてみました。
これまでやってきた事では、光センサー(Cdsセル)を使い光の明るさに応じサーボモーターを動かすなんてことも出来ますね。
太陽の位置(光の強い方向)に太陽電池パネルを動かす・・・なんてことにも応用できそうです。

また超音波センサーを使い障害物を検知してそれを避ける動作をさせる・・・なんていうことにも応用できます。

この投稿をInstagramで見る
シリアルモニタ(PC)からサーボを動かしてみる
次にシリアルモニタからサーボモーターの動きを制御してみたいと思います。
シリアルモニタに関してはLEDの点灯を制御したりPCからサーボ角度を入力して動かしたこちらの記事も参考にして下さい。
Servoライブラリを使うと複数台(最大12台)のサーボモーターを簡単に動かすことが出来るので、シリアルモニタと組み合わせると動作チェックやあらかじめ作っておいた複数の動作をPCから指定して動かしたりも出来ます。
この投稿をInstagramで見る
今回は上記回路をそのまま使い(ジョイスティックは外して下さい)、シリアルモニタ(PC)から2台のサーボモーターを動かしてみたいと思います。
と言ってもほぼ以前やった復習的な内容となります。
前回はシリアルモニタから角度を入力して単一サーボを制御してみました。
今回は2つのサーボモーターの動作をあらかじめ決めておき、呼び出すコマンド(入力された数字)によりそれぞれの動作をさせてみたいと思います。
上記動画のような使い方となります。
先程のジョイスティックの項目で使った回路はそのままでこのようなスケッチを作ってみました。
シリアルモニタから入力された数字をArduinoで読み取り、あらかじめ設定しておいた動作をさせるというものです。
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 34 35 36 37 38 39 40 41 42 43 44 45 | // Arduino入門編⑯ シリアルモニタからサーボモーターの動きを制御する // https://burariweb.info #include <Servo.h> // Servoライブラリの読み込み Servo myservo1; // Servoオブジェクトの宣言 Servo myservo2; const int SV_PIN1 = 6; // サーボ接続ピンを指定 const int SV_PIN2 = 7; int input = 0; void setup(){ myservo1.attach(SV_PIN1); // サーボ1をD6に割り当て myservo2.attach(SV_PIN2); // サーボ2をD7に割り当て Serial.begin(9600); // シリアル通信の開始 } void loop(){ if(Serial.available() > 0){ // 入力された文字が何バイトか調べその回数分繰り返す input = Serial.read(); // 1バイト分のデータを読み取る if(input == 49){ // ASCII文字[1]=10進数[49]なら以下を実行 myservo1.write(90); myservo2.write(90); delay(500); } else if(input == 50){ // ASCII文字[2]=10進数[50]なら以下を実行 myservo1.write(0); myservo2.write(0); delay(500); } else if(input == 51){ // ASCII文字[3]=10進数[51]なら以下を実行 myservo1.write(180); myservo2.write(180); delay(500); } } } |
シリアルモニタから”1”を入力すると両サーボを90度、”2”で0度、”3”で180度の位置に動く動作をさせています。
この投稿をInstagramで見る
スケッチ解説
Serial.available()関数を使いシリアルモニタから文字が入力されると次にその文字をSerial.read()関数で読み込み、条件文if()を使いそれぞれの動作に分岐させているシンプルなスケッチとなります。
25 26 | if(Serial.available() > 0){ // 入力された文字が何バイトか調べその回数分繰り返す input = Serial.read(); // 1バイト分のデータを読み取る |
こちらも前回の復習的な内容となります。

サーボモーターの基本的な動かし方が分かれば、これまでやってきたことを組み合わせていろいろと応用ができますね!
あると便利なアイテム
今回Arduinoを使ったサーボモーターの制御ということで、これまでやってきた事を組み合わせていろいろな方法でサーボを動かしてみました。
Arduino標準のServoライブラリは非常に便利で最大12台までのサーボモーターを同時に制御することが出来ます。
しかしサーボモーターはDCモーターの一種なのでその駆動には比較的大きな電力を消費します。
Arduinoへ接続する数が増えてくるとサーボ駆動用の外部電源を用意する必要があり、その配線も面倒なものとなります。
テスト環境では今回のようにブレッドボードなどを用意し外部電源に接続し動かす形となりますが、Arduinoには便利な「シールド」と呼ばれる拡張ボードが多数販売されています。
その中で『センサーシールド』を使えば今回のように複数台のサーボモーターを接続する際に電源確保も容易となり接続もシンプルで大変重宝します。

また、サーボモーターの動作チェックやホームポジション(センター)の確認だけならArduinoを使わなくてもチェックが出来る『サーボテスター』などもあると非常に便利になります。

【追記】ジョイスティックコントローラーを作ってみました!
Arduinoのテスト環境であると便利なジョイスティックコントローラーを3Dプリントパーツで作ってみました!
Arduinoで動くもののテストをする場合、コントローラーという形状にしておくと操作性もイメージしやすくプログラムの修正などにも役立つと思います。

今後、コントローラーの無線化なども考えています。
楽しく動かせ、アームの制御などArduino学習教材としても最適です!
興味ある方は作ってみてはいかがでしょうか?

今回使ったアイテム
SG90 サーボモーター
ラジコンや小型ロボットなどホビーユースで使われるサーボモーターとして非常にポピュラーなものとなります。
国内でも数百円程度で入手することができArduino学習用として手元にあるといろいろと試せます。
アナログジョイスティック
今回使用したアナログジョイスティックはArduinoスターターキットにも含まれています。
個別でも販売されており、Arduinoを使い何かを動かす場合に使用頻度が高いパーツの1つになり学習用に手元にあると便利です!
Arduino UNO
Arduinoはオープンソースのハードウェアなので正規品以外にも互換品が多数メーカーから販売されています。
互換品でも正規品と比べて特に問題なく使用でき数百円程度で購入が可能なのでArduino学習用としていいですね!

Arduino スターターキット
これからArduino学習を進めていくにあたりArduino UNO(互換品)やブレッドボード、ジャンパーピンなどがセットになったスターターキットが販売されています。
私はGeekcreit製のスターターキットを使っていますが、ELEGOO製のものは国内Amazonなどでも購入可能で人気があるようです。(セット内容はほぼ同じです!)
そしてELEGOOのサイトからスターターキット用サンプルスケッチのダウンロードも可能です。(Geekcreitのキットでも使えます)
参考 チュートリアルダウンロードELEGOO基本的にこれからこのセットで出来るものから紹介していこうと考えていますが、かなり多くのことが出来ます。
電子工作を始めるにはまずブレッドボードやジャンパーピン、メインとなるArduino UNOやサーボ、LEDなどの基本的なパーツがないと実際に動かすことが出来ませんが、個々にパーツを購入して回路を組んでとなるとかなりの手間がかかります。
スターターキットがあればArduinoの初歩的なことはかなりの数こなすことが出来るのでオススメです!
そこからスキルアップに伴い個別でセンサーなど必要なものを増やしていくのがいいと思います。
今回使ったSG90サーボモーターやアナログジョイスティックはArduinoスターターキットに含まれています。
最後に!
今回、Arduinoを使ったサーボモーターの制御としてこれまでやってきた事と組み合わせて動かしてみました。
今回ご紹介したものはほんの一例となりますが、サーボモーターを使えるようになると電子工作用途での幅が広がりますね。
これでサーボモーターの基本的な制御方法が理解できれば今回の目標は達成ですが、いかがだったでしょうか?












コメントを残す