部室の片隅 #4 障害物回避自動走行車

こんにちは, 情物2年 TM4-K10です. 今回はめちゃくちゃ長い.

この「部室の片隅」では, 自分で制作したものについて, 制作物の写真や動画, 参考サイトに加え, ワタシTM4-K10自身の制作時の色んなコメントを書いていきます. 不定期連載の日記です. 類似のものをつくるときはこの日記をあてにしないでね!(制作物に関するご意見はお待ちしております)

第4弾は, Arduinoで作る障害物回避自動走行車.

Arduinoを使用した, 障害物を探知して回避し走行する車です. モーターを使ったもので, 一人でも作れそうなものを作りたいと思ったので, 挑戦しました. 実は2月に作り始めましたが, 紆余曲折ありまして(というか一回諦めまして), ついこの間「ほぼ」完成しました.

<仕組み>

距離を測りながら直進し, 距離が既定より小さくなった場合は, 後進して左右の距離を計測. 距離の大きい方へ向きを変えて走る. フローチャートをみるといいかも.

距離を計測するのは超音波センサー(HC-SR04). 左右確認するのはサーボモーター(SG-90). 距離を計測するために温度を測定したいので, 温度センサー(LM61CIZ)も使用. 今回はモーターをモータードライバー(TB6612使用 Dual DCモータードライブキット)で制御. いずれもArduinoで制御.

<部品>

・Arduino Nano(互換品)
分割ロングピンソケット 1×42 (42P)
片面ガラスコンポジット・ユニバーサル基板 Cタイプ めっき仕上げ(72×47mm)日本製
電池ボックス 単3×3本 リード線
・単三電池 3本
ブレッドボード・ジャンパーワイヤ(オス-オス)(オス-メスも用意しましょう)
超音波距離センサー HC-SR04
マイクロサーボ9g SG-90
高精度IC温度センサLM61CIZ
TB6612使用 Dual DCモータードライブキット
ツインモーターギヤボックス <<タイヤも忘れずに!(今回は四輪)
ユニバーサルプレートセット

<回路図>

KiCadを使って回路図を書きました. これが一番時間食ったかも.

Arduino Nanoの3.3V電源は書いてないです. モータードライバーの電源は単三電池(4.5V)から, 超音波センサー(HC-SR04)と温度センサ(LM61)とサーボモーター(SG90)の電源はArduino Nanoの5V電源から.

<組み立てるよ!>

箇条書きですみません.

・ツインモーターギヤボックスを組み立てる

・マイクロサーボ(サーボモーター)本体とユニバーサルプレートを接着する

・ユニバーサルプレートにタイヤやギヤボックスをつける 

 ギヤボックスは後ろの二輪に, 地面側につける (写真を見たらわかるかも?)

・サーボモータのプロペラに超音波センサーを接着する

・回路を組む

・ユニバーサル基板とユニバーサルプレートをネジでつなぐ

<コメント>

正面から. 超音波センサー(HC-SR04)がウォー〇ーみたいでかわいい. ちなみに上部につながっている線はジャンパーワイヤ(オス-メス)です. オス-オスとセンサーのピンをはんだでつなぐことも可能ですが, いつとれるか分からないのでオス-メスを使いましょう.

正面から

真横から. 組み立てたらこういう形になる. 文面ではうまく説明できなかったモーターの位置もこれで大体わかるのではなかろうか. しっかし, いろいろ曲がっていますな(超音波センサと基板が水平じゃない)

真横から

真上から. ごちゃごちゃしている. 電池ボックスが固定されていない!

真上から

余談ですが, 最初は別のモータードライバーを使用していました. 参考にしていたサイトで使っていた、モータードライバーの後続を使っていましたが, 電源電圧が最低4.5Vと高く, 加えてモータードライバーの電源電圧が9V電池と扱いづらい回路を作ってしまったものです. 9V電池はすぐ使えなくなるので, すぐに動かなくなってしまいます. このことを部員に相談したら, 今のドライバーを教えてもらいました. 分からなくなって放棄する前に人に聞いてみるのもいいですね.

動画はこれです. ブレが激しいので視聴の際は注意してください. 外の音が入っていたので, 音なしです.

車体との距離が小さくなったら後ろに下がる様子, 左右確認をしている様子は観測できる. 確認後, 距離の大きい方へ方向転換できているかは怪しい. あとめちゃくちゃ後ろに下がるなあ. 下がる距離はもう少し小さくてもいいかな. 動きをよくするためにどういう風にコードを変えていけばいいのか(調整していけばいいのか), 聞いて回りたい.

コードはこちら.

//Avoidance Car
//sg-90, kakudo
#include <Servo.h>
Servo sg;
//hc-sr04
#define echo 3
#define trig 2
//b=left, a=right
#define a1 6
#define a2 4
#define ap 5
#define b1 10
#define b2 12
#define bp 11
#define stby 8

void setup(){
  Serial.begin(9600);
  sg.write(90);
  sg.attach(9);
  pinMode(echo,INPUT);
  pinMode(trig,OUTPUT);
  
  pinMode(a1,OUTPUT);
  pinMode(a2,OUTPUT);
  analogWrite(ap,255);
  pinMode(b1,OUTPUT);
  pinMode(b2,OUTPUT);
  analogWrite(bp,255);
  pinMode(stby,OUTPUT);

  digitalWrite(a1,LOW);
  digitalWrite(a2,LOW);
  digitalWrite(b1,LOW);
  digitalWrite(b2,LOW);
  digitalWrite(stby,HIGH);
  }

void loop(){
  go();
  check();
  }
void go(){
  digitalWrite(a1,HIGH);
  digitalWrite(a2,LOW);
  analogWrite(ap,80);
  digitalWrite(b1,HIGH);
  digitalWrite(b2,LOW);
  analogWrite(bp,80);
  }
void STOP(){
  analogWrite(ap,0);
  analogWrite(bp,0);
  delay(1000);
  }
void back(){
  digitalWrite(a1,LOW);
  digitalWrite(a2,HIGH);
  analogWrite(ap,80);
  digitalWrite(b1,LOW);
  digitalWrite(b2,HIGH);
  analogWrite(bp,80);
  delay(2000);
  }
void left(){
  digitalWrite(a1,HIGH);
  digitalWrite(a2,LOW);
  analogWrite(ap,100);
  digitalWrite(b1,LOW);
  digitalWrite(b2,HIGH);
  analogWrite(bp,80);
  delay(4000);
  }
void right(){
  digitalWrite(a1,LOW);
  digitalWrite(a2,HIGH);
  analogWrite(ap,80);
  digitalWrite(b1,HIGH);
  digitalWrite(b2,LOW);
  analogWrite(bp,100);
  delay(4000);
  }
int temp(){
  int ans,ondo,tv;
  ans=analogRead(0);
  tv=map(ans,0,1023,0,5000);//センサーの値を電圧に変換
  ondo=map(tv,300,1600,-30,100);//電圧の値を温度セ氏に変換
  return ondo;
  }
 int dis(){
  double v;
  double duration;
  int distance;
  int t=temp();
  digitalWrite(trig,LOW);
  delayMicroseconds(2);
  digitalWrite(trig,HIGH);
  delayMicroseconds(10);
  digitalWrite(trig,LOW);
  duration=pulseIn(echo,HIGH);
  delay(1000);
  v=331.5+0.6*t;
  if(duration>0){
    duration/=2;
    distance=duration*v*100/1000000;
    }
   return distance;
  }
void check(){
  double f=dis();
  if(f<40&&f>=0){
    STOP();
    back();
    STOP();
    sg.write(60);
    double r=dis();
    delay(1000);
    sg.write(120);
    double l=dis(); 
    delay(1000);

    if(r>l){
      sg.write(90);
      right();
      STOP();
      }
    else if(r<l){
      sg.write(90);
      left();
      STOP();
      }
    else{
      sg.write(90);
      }
    }
  }

<最後に>

プログラミングで部品の動きを制御できること, 制作の基本(?)である問題解決方法を学べました. ただ, 情報をうのみにせず(正しさというのは流動的ではあるので), どういう結果になるかある程度自分で想像する力は必要だなあと思いました.

マイコンや組み込みに関する理解をもっと深めたいです. もう少しコイツをブラッシュアップしたいので, 夏休み中有識者に聞いて回ろうかな. あと, ものをつくるペースをもっとあげたい.

<調べ物をする際のキーワード>

つくる対象に関しては, 「障害物 避ける 車 Arduino」で調べました.

部品それぞれに関しては, データシートを検索したり(「部品名 データシート」で検索したら出てくるかと思います), Arduinoで制御するものに関しては, 「部品名 Arduino」で検索したりしました.

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です