【Arduino】自動運転ロボットカーの作り方

【Arduino】自動ロボットカーの作り方

こんにちは! けい(Twitter)です。

普段は電子工作をやりながら、それをブログで情報発信を行っています。
そんな私が電子工作を始めて約2年ほど経過しました。

そこで、私が人生で初めての電子工作で作ったロボットカーを2年の時を経た今、ご紹介していきたいと思います。

材料

Arduino mega

「Arduino Uno」だと「モータ・ドライバ」が全ての「gpioピン」を使ってしまうため、「Arduino Mega」を使用します。

created by Rinker
ELEGOO
¥3,299 (2024/04/27 08:32:33時点 Amazon調べ-詳細)

モータードライバ

モータードライバを使うと簡単にプログラムを書けます。
ピンヘッダーをはんだ付けする必要があるので、そちらも持っていない方は用意してください。

HiLetgo L293D モータ ドライバー拡張ボード 基板モーター モータ制御シールド [並行輸入品]
HiLetgo

モーター

タミヤのシリーズを買うと、プロモデルみたいにロボットを組み立てられるので、初心者におすすめです。

created by Rinker
タミヤ(TAMIYA)
¥665 (2024/04/27 08:32:35時点 Amazon調べ-詳細)

ボディ

タミヤのユニバーサルプレートに、モーターやキャタピラを固定します。

created by Rinker
タミヤ(TAMIYA)
¥660 (2024/04/27 08:32:39時点 Amazon調べ-詳細)

キャタピラがやっぱりかっこいい!

created by Rinker
タミヤ(TAMIYA)
¥506 (2024/04/27 08:32:36時点 Amazon調べ-詳細)

電池(3V)

モーター駆動用の電池です。モーターの定格が3Vなので、電池2つを使用します。

サーボモーター

超音波センサーを乗せて首振り機能を付けるのに使います。

超音波センサー

自動運転の要となるセンサーです。
障害物との距離を測定して、壁にぶつからないように走行することが可能となります。

ELEGOO Arduino用 HC-SR04超音波距離センサー5PCS
ELEGOO

モバイルバッテリー

Arduinoに電源を供給するためのモバイルバッテリーがあると、パソコンと線を繋がなくても良いので、よりロボット感がでます。

ほとんどのモバイルバッテリーが「Arduino」で動作します。モバイルバッテリーとArduinoをUSBで接続して、Arduinoに電力を供給します。

ロボットカーに乗るような小型のものがおすすめです。

あると便利なもの

グルーガンがあると、サーボモーターとボディの固定などに便利です。
また、電子工作と親和性が高いので、持っておくと今後も便利なものです。

100均でも売っていますが、使い心地が最悪なので1000円程度のものを買うことをお勧めします。
(作業効率が100倍になります。)

ロボットカーの組み立て

タミヤのダブルギヤモーターユニバーサルプレートトラック&ホイールを組み合わせてロボットカーのボディを組み立てます。

説明書が入っているので、それを読みながらフィーリングで作れます。

下の写真はただの一例ですので、ご自由に作ってください。

配線

モータードライバの接続

モータードライバの配線はこのようになっています。

この中で使うものは、「M1」「M2」「INPUT+」「INPUT-」です。
また、超音波センサーとサーボモーターの電源ピンをモータードライバからとりたいので、ピンヘッダーをはんだ付けしてください。

私の場合はM1に左側のモーター、M2に右側のモーターを接続しました。

また、INPUTはモーターの電源を接続します。つまり、電池ボックスのコネクタを接続します。

全体の配線

順に部分ごとに説明していきます。

モーターの接続部

電池ボックスの接続

電池ボックスの+(赤)と-(黒)のコネクタを接続します。

超音波センサーとサーボモーター

超音波センサーとサーボモーターのVCCとGNDをモータードライバ上の5VとGndに接続します。

また、超音波センサーのTrigピンをgpio52、Echoピンをgpio50、サーボモーターのPWMピンをgpio46に接続します。

以上で配線は終了です。

ロボットカーの完成系

「電池ボックス」「Arduino」「サーボモーター」をグルーガンで固定したら、ロボットカーの完成です。

モータードライバのライブラリのインストール

続いて、ソフト側の準備に移行します。

Arduinoを開いて、「スケッチ」→「ライブラリをインクルード」→「ライブラリを管理」をクリックします。

検索窓で「adafruit motor」と入力してEnterを押します。

一番上に出てくるものをインストールしてください。
(上の画像ではすでにインストールした画面になってます)

プログラム

このプログラムで動きはしますが、電子工作のど初心者が書いたものなのできちゃないコードです。
あえて2年前の無修正コードを載せています。参考にはしないでください。

#include <Servo.h>
#include <AFMotor.h>
#define echoPin 50 // Echo Pin
#define trigPin 52 // Trigger Pin
#define servoPin 46 //servo Pin
#define point 30 //距離の基準
 
double Duration = 0; //受信した間隔
double Distance[9]; //距離 50°から130までの距離を10°ずつに9個の値を格納

Servo myservo;

AF_DCMotor motorleft(1);
AF_DCMotor motorright(2);

int pos[9]={50,60,70,80,90,100,110,120,130};  //サーボの角度 50°から130°までの9個値を格納

int i=0;  //角度のカウント関数

int N=0;   //90°の時の値
int R=0;   //60°の時の値
int R1=0;  //80°の時の値
int L=0;   //120°の時の値
int L1=0;  //100°の時の値

int q=0;   //状態関数 q=0->静止 q=1->直進

void setup() {
  Serial.begin( 9600 );

  myservo.attach(servoPin);

  motorleft.setSpeed(100);
  motorleft.run(RELEASE);
  motorright.setSpeed(100);
  motorright.run(RELEASE);

  pinMode( echoPin, INPUT );
  pinMode( trigPin, OUTPUT );
}

void loop() {
  for (i=0; i<=8; i++){  //カウンタ関数を進めて配列に格納
  myservo.write(pos[i]);     //サーボを回転
  digitalWrite(trigPin, LOW); 
  delayMicroseconds(2); 
  digitalWrite( trigPin, HIGH ); //超音波を出力
  delayMicroseconds( 10 ); //
  digitalWrite( trigPin, LOW );
  Duration = pulseIn( echoPin, HIGH ); //センサからの入力
  if (Duration > 0) {
    Duration = Duration/2; //往復距離を半分にする
    Distance[i] = Duration*340*100/1000000; // 音速を340m/sに設定

    //評価する3つの値をそれぞれ格納
    N=Distance[4];
    R=Distance[1];
    L=Distance[7];
    R1=Distance[3];
    L1=Distance[5];
    
    Serial.print("angle:");
    Serial.print(pos[i]);
    Serial.print("    ");
    Serial.print("Distance:");
    Serial.print(Distance[i]);
    Serial.println(" cm");

    if(i==0) delay(300);   //50°から130°までは距離があるため
    else delay(50);
}
  }
  
  switch(q){
    case 0 : 
    if(point<N&&point<R1&&point<L1){
    motorleft.run(FORWARD);
    motorright.run(FORWARD);
    q=1;  //状態
    delay(500);
  }

  else if(N<point&&L>R){
    q=2;
  }

  else if(N<point&&R>=L){
    q=5;
  }

  else{
    motorleft.run(BACKWARD);
    motorright.run(BACKWARD);
    delay(500);
    motorleft.run(RELEASE);
    motorright.run(RELEASE);
  }
  break;

  case 1 : 
  if(point<N&&point<R1&&point<L1){
    motorleft.run(FORWARD);
    motorright.run(FORWARD);
    delay(300);
  }

  else if(point>=N||point>=R1||point>=L1){
    motorleft.run(RELEASE);
    motorright.run(RELEASE);
    q=0;
    delay(500);
  }
  break;

  case 2 :     //左回転
  
    motorright.run(FORWARD);
    motorleft.run(BACKWARD);
    delay(1000);
    motorright.run(RELEASE);
    motorleft.run(RELEASE);
    q=0;
  break;

  case 5 :   //右回転
 
    motorleft.run(FORWARD);
    motorright.run(BACKWARD);
    delay(1000);
    motorleft.run(RELEASE);
    motorright.run(RELEASE);
    q=0;
  break;

  default :
    motorleft.run(BACKWARD);
    motorright.run(BACKWARD);
    delay(1000);
    motorleft.run(RELEASE);
    motorright.run(RELEASE);
    q=0;
    break;
  }
}

動画

2年前に動かした動画がyoutubeにアップしてありました。気になった方はぜひ見て下さい。

合わせて読みたい記事

Raspberry Pi Picoでも同様に、自動運転ロボットカーを作成しました。

今回の反省も踏まえて、よりグレードアップしたものを作ったのでぜひ見て行ってください。