DCモーターの回転を制御してみる(Arduino)
電池で駆動するおもちゃなど、
モーターを使った製品は多くあります。
正転、逆転などは、電池の向きを変えてあげればできそう?
ですが、回転数や、ブレーキなどの制御ができれば、
いろいろできそうな気がします。
今回は、
プラモデルやおもちゃによく使われている、
DCモータ(1.5V~3.0V程度で動作)を使ってみます。
・・・乾電池1~2本で使っているものです。
今回使用するものは、
・DCモーター
・モータードライバ
・DCモーター用電源(3V)
・可変抵抗(10KΩ)
です。

DCモーターですが、
何か目的がある場合には、その目的に合わせて選択します。
・電圧範囲、無負荷時電流、無負荷時回転数、
定格負荷時電流、定格負荷時回転数、負荷出力、
効率、静止電流、静止トルク、などでしょうか?
モータードライバは、
DCモーターを制御するために使用します。
ただ回ってくれれば良いのであれば、電池を繋ぐ、放す
を行うリレーユニットなどを入れれば良いですが、
回転数を変化させたり、ブレーキを掛けるなどを行いたい
場合には、このドライブを利用すると簡単に行えます。
今回私が利用する、TB6612FNG搭載 デュアルモータードライバは、
詳しい解説や使用例が、メーカー(SPARKFUN)ページ に紹介されています。
私が解説するするより確かです。
https://learn.sparkfun.com/tutorials/tb6612fng-hookup-guide?_ga=2.68766999.766402060.1591960917-1588015560.1591960917



BIN1 | BIN2 | PWMB | 説明 |
L | L | H | 停止(制御なし) |
H | L | H | CW(時計回り):正転 |
L | H | H | CCW(反計回り):反転 |
H | L | L | ショートブレーキ |
L | H | L | ショートブレーキ |
※STBYがHIGHであることが動作条件 |
モータードライバは、使用するモータに合わせたものを選択します。
今回使用するドライバは、2台のモーターを制御できるもので、
車のおもちゃなどの両輪にモーターを設置して制御したい
場合などによく利用されるものです。
・2つモーターを同時に制御できるため、左右輪のモーターの
同時回転・同時停止のタイムラグを少なくできます。
電池ボックスは、
今回使用するモーターの電圧範囲は、1.5~3.0V (標準1.5V)
ということで、Arduino 本体のからの 3.3V 供給 は、
製品によっても異なるようですが、(50mA程度)が利用可能です。
モーター類は、大量の電流を必要とするため、別途専用電源を
用意するが一般的で、可能範囲であっても Arduino 本体からの
電源供給は避けるのが無難でしょう。
今回は、単三電池を2本セットできる電池ボックスを使用して、
モーターへ電源供給します。
入手できる通販サイトを掲載しておきます。
・TB6612FNG搭載 デュアルモータードライバ
¥629- [SFE-ROB-14451]
スイッチサイエンス
https://www.switch-science.com/catalog/3587/
・TB6612使用 Dual DCモータードライブキット
¥350- [AE-TB6612]
秋月電子通商
http://akizukidenshi.com/catalog/g/gK-11219/
・DCモーター FA-130RA-2270L
¥120- [FA-130RA-2270L]
秋月電子通商
http://akizukidenshi.com/catalog/g/gP-09169/
・電池ボックス 単3×2本 リード線・間仕切りあり
¥50- [BH-321-2A150]
秋月電子通商
http://akizukidenshi.com/catalog/g/gP-00327/
スケッチですが、
このメーカーが、Webページで提供しているライブラリを使用して制御するものと、
ライブラリを使用せずに制御するものを書いてみます。
回路は図の通りです。
この回路図の作図には fritzing を利用させて頂いております。
https://fritzing.org/home/


まず、ライブラリを使用するものですが、
これは、メーカーのページでサンプルが紹介されていますので、
このサンプルを使用させて頂きます。
ライブラリのインストールです。
1.メーカー(sparkfun)ページ の
https://learn.sparkfun.com/tutorials/tb6612fng-hookup-guide?_ga=2.68766999.766402060.1591960917-1588015560.1591960917
”TB6612FNG ARDUINO ライブラリ” を選択します。
”SparkFun_TB6612FNG_Arduino_Library-master.zip”
というファイルがダウンロードされます。


2.メニュー「スケッチ」→「ライブラリのインクルード」
→「.ZIP形式のライブラリをインストール」を選択しインストールします。
1.でダウンロードしたファイル
(私の場合SparkFun_TB6612FNG_Arduino_Library-masterというファイル名)を
指定して、[開く]ボタンを押します。


3.インストールができているか確認します。
メニュー「ファイル」→「スケッチ例」→「SparkFun_TB6612FNG・・・」
→「Motor TestRun」が表示されれば、インストールは完了です。

では、このサンプルを利用して動作確認してみます。
メニュー「ファイル」→「スケッチ例」→「SparkFun_TB6612FNG・・・」
→「Motor TestRun」 を選択します。
このスケッチの先頭で、
define定義を使って Arduino の使用デジタルピンを設定しています。
この定義に合わせて、配線をするか、
私の配線図に合わせる場合は、
// 使用デジタルピン設定(今回はBのみ設定)
define AIN1 2 // 未設定
define AIN2 3 // 未設定
define PWMA 5 // 未設定
define BIN1 11
define BIN2 10
define PWMB 9
define STBY 7
と変更します。

必要ないとは思いますが、
このサンプルにコメント付けたものを貼り付けておきます。
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | // This is the library for the TB6612 that contains the class Motor and all the // functions // インクルード宣言 SparkFun_TB6612ライブラリ利用宣言 #include <SparkFun_TB6612.h> // Pins for all inputs, keep in mind the PWM defines must be on PWM pins // the default pins listed are the ones used on the Redbot (ROB-12097) with // the exception of STBY which the Redbot controls with a physical switch // 使用デジタルピン設定(今回はBのみ設定) define AIN1 2 // 未設定 define AIN2 3 // 未設定 define PWMA 5 // 未設定 define BIN1 11 define BIN2 10 define PWMB 9 define STBY 7 // these constants are used to allow you to make your motor configuration // line up with function names like forward. Value can be 1 or -1 // モータの構成を設定 const int offsetA = 1; const int offsetB = 1; // Initializing motors. The library will allow you to initialize as many // motors as you have memory for. If you are using functions like forward // that take 2 motors as arguements you can either write new functions or // call the function more than once. // オブジェクト生成 Motor motor1 = Motor(AIN1, AIN2, PWMA, offsetA, STBY); Motor motor2 = Motor(BIN1, BIN2, PWMB, offsetB, STBY); void setup() { // put your setup code here, to run once: } void loop() { //Use of the drive function which takes as arguements the speed //and optional duration. A negative speed will cause it to go //backwards. Speed can be from -255 to 255. Also use of the //brake function which takes no arguements. // motor1を255の(正転)速度で、1秒回転(次の指示があっても1秒は実行する) motor1.drive(255,1000); // motor1を-255の(逆転)速度で、1秒回転(次の指示があっても1秒は実行する) motor1.drive(-255,1000); // motor1を停止 motor1.brake(); delay(1000); //Use of the drive function which takes as arguements the speed //and optional duration. A negative speed will cause it to go //backwards. Speed can be from -255 to 255. Also use of the //brake function which takes no arguements. // motor2を255の(正転)速度で、1秒回転(次の指示があっても1秒は実行する) motor2.drive(255,1000); // motor2を-255の(逆転)速度で、1秒回転(次の指示があっても1秒は実行する) motor2.drive(-255,1000); // motor2を停止 delay(1000); //Use of the forward function, which takes as arguements two motors //and optionally a speed. If a negative number is used for speed //it will go backwards // motor1,motor2を150の(正転)速度で、前進(同時に回転)させる forward(motor1, motor2, 150); delay(1000); //Use of the back function, which takes as arguments two motors //and optionally a speed. Either a positive number or a negative //number for speed will cause it to go backwards // motor1,motor2を-150の(逆転)速度で、後退(同時に回転)させる back(motor1, motor2, -150); delay(1000); //Use of the brake function which takes as arguments two motors. //Note that functions do not stop motors on their own. // motor1,motor2を同時に停止する brake(motor1, motor2); delay(1000); //Use of the left and right functions which take as arguements two //motors and a speed. This function turns both motors to move in //the appropriate direction. For turning a single motor use drive. // motor1,motor2を使って100の速度で左へ(効率よく?)旋回する left(motor1, motor2, 100); delay(1000); // motor1,motor2を使って100の速度で右へ(効率よく?)旋回する right(motor1, motor2, 100); delay(1000); //Use of brake again. // motor1,motor2を同時に停止する brake(motor1, motor2); delay(1000); } |
Arduino に書き込んで実行してみます。
回転方向や回転速度などが変わって実行されると思います。
続いて、ライブラリを使用せず、制御してみます。
この、TB6612FNGドライバのモーター制御は、
各ピンの設定を以下のように設定することで実現できます。
回路図は同じです。
スケッチしてみます。
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 | // 使用デジタルピン設定 define BIN1 11 define BIN2 10 define PWMB 9 define STBY 7 void setup() { // put your setup code here, to run once: // ピンモード設定 pinMode( BIN1, OUTPUT ); pinMode( BIN2, OUTPUT ); pinMode( STBY, OUTPUT ); // 停止状態に設定(初期化) digitalWrite( BIN1, LOW ); digitalWrite( BIN2, LOW ); analogWrite( PWMB, 255); // 駆動可能状態に設定 digitalWrite( STBY, HIGH ); } void loop() { // put your main code here, to run repeatedly: // 正転(時計回り)CW digitalWrite( BIN1, HIGH ); digitalWrite( BIN2, LOW ); analogWrite( PWMB, 255); delay(200); // ショートブレーキ digitalWrite( BIN1, HIGH ); digitalWrite( BIN2, LOW ); analogWrite( PWMB, 0); delay(2000); // 反転(反時計回り)CCW digitalWrite( BIN1, LOW ); digitalWrite( BIN2, HIGH ); analogWrite( PWMB, 255); delay(200); // 停止 digitalWrite( BIN1, LOW ); digitalWrite( BIN2, LOW ); analogWrite( PWMB, 0); delay(2000); } |

Arduino に書き込んで実行してみます。
こちらも回転速度が変わって実行されると思います。
速度については、
analogWrite( PWMB, 255 )
で、最高回転数で定義しています。
ライブラリを使うか使わないかは、どちらでもよいと思いますが、
車のおもちゃのようなもので、
左右のタイヤにそれぞれモーターを設置した場合、
この2つのモータを同時正転させる方法に難易度があります。
例えば、
右:ON
digitalWrite( AIN1, HIGH );
digitalWrite( AIN2, LOW );
analogWrite( PWMA, 255);
左:ON
digitalWrite( BIN1, HIGH );
digitalWrite( BIN2, LOW );
analogWrite( PWMB, 255);
とスケッチすれば、右がONになった後に左がONとなり、
同時ではありません。停止させる場合も同じです。
こんな時、このライブラリには、
2つのモータに対して同時に指示する関数が用意されています。
右左:ON
forward(motor1, motor2, 150);
これらを考えると、使うものによっては、ライブラリの方が
簡単に作成できるかもしれませんね。
次は、回路上に可変抵抗(10KΩ)を入れて、
この抵抗の値により、モーターの回転を変化させてみます。
回路は図の通りです。


スケッチしてみます。
このスケッチは、SparkFun_TB6612ライブラリを使用しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // インクルード宣言 SparkFun_TB6612ライブラリ利用宣言 #include <SparkFun_TB6612.h> // 使用デジタルピン設定 define BIN1 11 define BIN2 10 define PWMB 9 define STBY 7 // モータの構成を設定 const int offsetB = 1; // オブジェクト生成 Motor motor2 = Motor(BIN1, BIN2, PWMB, offsetB, STBY); void setup() { // put your setup code here, to run once: } void loop() { // put your main code here, to run repeatedly: // A0ピンより可変抵抗値の電圧を取得 int val = analogRead( A0 ); // A0ピンの取得値を map()関数で、0 から 255 に数値置換 val = map( val, 0, 1023, 0, 255 ); // 変換したvalの値で、モータを回転させる motor2.drive( val ); delay(20); } |

Arduino に書き込んで実行してみます。
可変抵抗のつまみを廻すと、モーターの回転が変化します。
可変抵抗を通過した電圧を取得します。
analogRead( A0 );
このとき、0~1023の整数値で表現されます。
これを、モーターのPWMに受け渡すのですが、
PWMは0~255の範囲で指定でした。
そのため、変化が必要になります。
そこで map( ) 関数をを利用します。
この関数は、
ある範囲の値を、別の範囲の値に変換してくれます。
map( 変数名, 現在の範囲下, 現在の範囲上, 変換する範囲下, 変換する範囲上 );
という使い方で、
A0から、analogRead( )で取得した、0~1023範囲内の値を、
PWMの指定範囲 0~255 に変換します。
map( val, 0, 1023, 0, 255 );
となり、変換された値を、変数へ代入します。
val = map( val, 0, 1023, 0, 255 );
別に、valに入れなくても、別途変数を用意しても良いです。
この変換済みの値を、ライブラリ関数を使用して、
motor2.drive( val )
モータードライバへ送ります。