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
と変更します。
必要ないとは思いますが、
このサンプルにコメント付けたものを貼り付けておきます。
// 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ドライバのモーター制御は、
各ピンの設定を以下のように設定することで実現できます。
回路図は同じです。
スケッチしてみます。
// 使用デジタルピン設定
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ライブラリを使用しました。
// インクルード宣言 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 )
モータードライバへ送ります。