
こんにちは、メカ旦那です!

Arduinoを使ってなんか作品を作りたい!できれば生活の役に立つものが良い!
そう思った私は、ルンバのようなお掃除ロボットを作ることにしました。今回は後編です。前編はこちらで解説しているので、まだ読まれていない方はぜひチェックしてくださいね。
電気回路
回路図
-1-1024x602.jpg)
回路図はこんな感じです。(中央にあるモータードライバーはfritzingにパーツ登録が無かったので、別のもので描きました。なので若干配線が違いますが、大まかにはこんな感じです。)
配線が複雑なので、丁寧に解説していきます!
モータードライバー
まずはArduinoとL293Dモータードライバーシールドを配線します。Arduinoのソケットにドライバーのピンを挿すだけで終わりです。デジタルピン、アナログピン、電源ピンそれぞれ正しいソケットに挿入してくださいね。


このモータードライバーってどんな役割があるんですか?ドライバー無しでモーターを直接Arduinoに接続してはダメなんですか?

合体することでArduinoのソケットは全て埋まったので、他の機器はドライバーに繋ぎます。Arduinoはドライバー経由で他の機器と信号をやり取りします。

モーター
続いて、モーターをドライバーに接続します。今回はM1、M4の端子を使いました。こちらで解説したように、QIコネクタを圧着しておくと、接続が容易になります。

超音波センサ
障害物検知のため、前方に超音波センサ(HC-SR04)を3つ付けました。
今回のセンサ「HC-SR04」はトランスミッタから超音波を送信し、前方の物体に当たって跳ね返ってきたものをレシーバで受信することで、その物体との距離を測定します。基板から20~4000 mm の距離、15度の角度まで超音波が届きます。

15度ということで、センサ1つだけだと検知範囲が狭いので、3つ付けてみました。
配線について、HC-SR04は4ピンあります。VccとGndは電源供給のためのピンで、Arduino側ではそれぞれ5VとGNDに接続します。Trig(トリガー)は超音波送信の合図信号を出すピンです。超音波は常に出している訳ではなく、Arduinoから一定間隔で合図信号をTrigに送り、トランスミッタから超音波を送信しています。この合図信号は、IT用語ではトリガ信号と呼ばれています。なので、センサのピン名もTrigとなっている訳ですね。このピンはArduinoの14ピンに接続しました。また、Echo(エコー)は超音波を送信した後、返ってくるまでHighになるピンです。このHighの時間を使って障害物との距離を測定します。詳しくはソースコードで解説しますね。EchoはArduinoの16ピンに接続しました。

ちなみに、Arduino側はピンを挿入するだけだと固定が弱いので、はんだづけをしました。

今回は3つのセンサを付けるんですよね。1センサ当たり4ピンあるということは、計12本配線をArduinoに接続するという事ですよね・・・なんかゴチャゴチャしそうですね・・・

電池・スイッチ
電池はモータードライバーの動作電圧が4.5~25Vである事と、何回も使用できるように、9Vの充電池を使いました。またスイッチはON・OFFがしやすいように、ロッカースイッチを用いました。配線は下図のようにドライバーの外部電源端子にそれぞれ繋いでいます。どちらもロボットの上面に設置することで、充電のための取り外しと、操作が簡単になるようにしました。

ソースコード
全体
ソースコードはこちらになります!長いので1つ1つ解説します。
// Adafruit Motor Shield library - Version: Latest
#include <AFMotor.h>
//モータードライバーシールド
AF_DCMotor motorRight(1); // モーター(進行方向の右輪)をモーター端子1に接続
AF_DCMotor motorLeft(4); // モーター(進行方向の左輪)をモーター端子4に接続
//超音波センサ
#define trigPin 14 //TrigPinの定義。今回は14ピンに設定。文末の;は不要。
#define echoPin 16 //EchoPinの定義。今回は16ピンに設定。文末の;は不要。
//変数
float echoHigh = 0; //Echo出力のHigh期間を格納
float distance = 0; //計算した距離を格納する変数
const int speed = 100 ; //モータースピード値を格納
void setup(){
//超音波センサ
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop(){
digitalWrite(trigPin, LOW); //trigPinからLOWを出力
delayMicroseconds(10); //10us待機
//超音波を出力するためのトリガ信号発信
digitalWrite(trigPin, HIGH); //トリガ信号HIGH
delayMicroseconds(10); //トリガ信号パルス幅10 usを生成
digitalWrite(trigPin, LOW); //トリガ信号Low
echoHigh = pulseIn(echoPin, HIGH); //echoPinのHigh時間を格納。pulseIn(パルスを入力するピン番号、測定するパルスの種類、タイムアウトまでの時間(省略可))
distance = 340 * echoHigh / 2 / 1000; //音速340m/sを用いて距離計算。echoHighは往復の距離(μm)であるため、2で割り片道に、1000で割りmmに直す
if(distance > 30){ //もし障害物との距離が30 mm 以上なら直進
motorRight.setSpeed(speed); // モータースピード(0~255の範囲)
motorLeft.setSpeed(speed);
motorRight.run(FORWARD); // モーター1とモーター2を正回転させる
motorLeft.run(FORWARD);
}
if(distance <= 30){ //もし障害物との距離が30 mm 以下なら旋回
motorRight.run(RELEASE); // モーターを停止させる(ブレーキ)
motorLeft.run(RELEASE);
delay(1000);
distance = 50; //距離測定を一時停止
motorRight.setSpeed(speed); // 後進
motorLeft.setSpeed(speed);
motorRight.run(BACKWARD);
motorLeft.run(BACKWARD);
delay(1000);
motorRight.setSpeed(speed); //90°旋回
motorLeft.setSpeed(speed);
motorRight.run(FORWARD);
motorLeft.run(BACKWARD);
delay(500);
distance = 340 * echoHigh / 2 / 1000; //距離測定再開
}
}
ライブラリ宣言
まずは冒頭のこちらです!
// Adafruit Motor Shield library - Version: Latest
#include <AFMotor.h>
こちらは、ライブラリである「Adafruit Motor Shield library」の使用宣言です。1から複雑なコードを作成しなくとも、このライブラリを使うことで、簡単にドライバー、モーターを動かすことが可能です。エディターによってライブラリの使用方法が若干異なるので解説します。
エディターが Web editor の場合
先ほどのコードをそのままエディターにコピペするだけでOKです。ただ、せっかくですので、ライブラリを探す方法についても解説します。
5. 先ほどのライブラリが「FAVORITES」に登録されました。こちらをクリック
6. 「INCLUDE」をクリック
7. 「#include <AFMotor.h>」が入力されました。こちらでライブラリ宣言は完了です!
Arduino IDEでは後述の通りライブラリをPCにインストールする必要がありますが、Web editorは不要です。PC容量も消費せずオススメです!
エディターが Arduino IDE の場合
ちなみに、Web editorでは前述の通りインストール不要で「#include <AFmotor.h>」のコピペで終わるので非常に楽です。是非活用を検討してみて下さい!
定義
次は変数の定義です!
AF_DCMotor motorRight(1);
AF_DCMotor motorLeft(4);
モータードライバーの端子1には右輪用モーターを、端子4には左輪用モーターを接続しており、それぞれ、「motorRight」「motorLeft」と定義しています。
#define trigPin 14
#define echoPin 16
Arduinoの14ピンは超音波センサのtrigに繋がっているので「trigPin」、16ピンはechoに繋がっているので「echoPin」と定義しています。 ちなみに、#defineは文末の;は不要です。
float echoHigh = 0;
float distance = 0;
const int speed = 100 ;
echoPin(16ピン)のHigh時間を格納する変数を「echoHigh」、その値を元に物体との距離計算した値を格納する変数を「distance」と定義しました。最初はまだ測定していないので0を格納しています。また、モーターのrpm(毎分の回転速度)を格納する定数を「speed」と定義しました。後述するsetSpeed関数にこのspeedを格納して、回転速度を指定します。0~255の範囲で入力でき、今回は試しに100を入れてみました。
void setup(){
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
trigPinを出力ピン(OUTPUT)、echoPinを入力ピン(INPUT)に定義しています。
超音波センサ
続いて、センサから超音波を送信します。超音波を送信するためには、トリガ信号を出す必要があります。
void loop(){
digitalWrite(trigPin, LOW);
delayMicroseconds(10);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
echoHigh = pulseIn(echoPin, HIGH);
pulseIn関数を使って、echoPinのHIGH時間をechoHighに格納します。
distance = 340 * echoHigh / 2 / 1000;
echoHighは単位が時間 [μs] なので、音速340m/sを掛けて距離に変換します。また、往復になっているので、2で割って片道にし、更に1000で割って [mm] に直します
モーター
最後に、超音波センサで算出した障害物との距離に応じて、モーターを制御します。その前に、重要な関数を2つご紹介します!
離れている場合(障害物との距離が 30 mm 以上)
if(distance > 30){
motorRight.setSpeed(speed);
motorLeft.setSpeed(speed);
motorRight.run(FORWARD);
motorLeft.run(FORWARD);
}
もし障害物と十分離れている場合(距離が30 mm 以上)、両輪とも正回転させて、前進させます。冒頭定義したspeed(rpm : 100)で回転させます。
近い場合(障害物との距離が 30 mm 以下)
if(distance <= 30){
motorRight.run(RELEASE);
motorLeft.run(RELEASE);
delay(1000);
もし障害物と近い場合(距離が30 mm 以下)、まずモーターを停止させて、1000 μs(1 s)維持します。
distance = 50;
次に、距離測定を一時停止すべく、一旦50をdistanceに格納します。(もし一時停止しない場合、この後の後進で距離が30 mm以上になった際に前進し、また障害物に近づく事になるため、それを防止します)
motorRight.setSpeed(speed);
motorLeft.setSpeed(speed);
motorRight.run(BACKWARD);
motorLeft.run(BACKWARD);
delay(1000);
motorRight.setSpeed(speed);
motorLeft.setSpeed(speed);
motorRight.run(FORWARD);
motorLeft.run(BACKWARD);
delay(500);
distance = 340 * echoHigh / 2 / 1000;
}
}
旋回が完了した後、距離測定を再開させ、障害物と離れている事を確認したら前進します。まだ近い場合は再度後進・旋回を行います。
まとめ
作り方の説明は以上です!実際に走らせた様子はこちらです。
よかったら参考にしてみて下さい!
コメント