これは何?
ロボット作りの習作ということで、Arduinoを使っていわゆるルンバみたいな部屋の中を自律的に走行するロボット(ただし掃除はしない)を作ってみました。
材料
筐体の作成
今回は作りながら構成を考えるということで、まずはこういうユニバーサルボードを作ってみます。
穴の大きさは11mm。僕がよく作るねじの直径が10mmなので、そのねじがうまく入るような大きさにしました。
ギアボックスと3mmのボルトとナットでで固定します。この時点でかなりそれっぽい!
OpenSCADでねじを作ります。
Fusion360でこういうのを作ります。
Arduino固定用パーツ
ブレッドボード固定用パーツ
9V電池固定用パーツ
で、こんな風に上にArduinoを固定します。
9V電池はこんな風に固定する
回路
下の記事を参考にして、モータードライバを制御しました。今回は両輪別々に制御したかったので、同じ回路を2つ並べました。
超音波センサーについては下記記事を参考に。
(この後紹介するスピーカーも含めた回路図です)
プログラムの作成
ほとんどプログラムも前述の記事の真似です。
自立制御の部分はテキトーに作りました。
50cm先に障害物を発見すると、バックして左に少し回転してまた前進します。
const int motor1A = 2; const int motor1B = 3; const int motor2A = 4; const int motor2B = 5; const int motorPwm = 6; const int echoPin = 8; const int trigPin = 7; enum Mode{modeLeft, modeRight, modeForward, modeBackward}; Mode mode = modeForward; void back(){ digitalWrite(motor1A, HIGH); digitalWrite(motor1B, LOW); digitalWrite(motor2A, LOW); digitalWrite(motor2B, HIGH); } void backward(){ digitalWrite(motor1A, HIGH); digitalWrite(motor1B, LOW); digitalWrite(motor2A, LOW); digitalWrite(motor2B, HIGH); } void forward(){ digitalWrite(motor1A, LOW); digitalWrite(motor1B, HIGH); digitalWrite(motor2A, HIGH); digitalWrite(motor2B, LOW); } void turnLeft(){ digitalWrite(motor1A, HIGH); digitalWrite(motor1B, LOW); digitalWrite(motor2A, HIGH); digitalWrite(motor2B, LOW); } void turnRight(){ digitalWrite(motor1A, LOW); digitalWrite(motor1B, HIGH); digitalWrite(motor2A, LOW); digitalWrite(motor2B, HIGH); } double getDistance(){ double duration = 0; double distance = 0; digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite( trigPin, HIGH ); delayMicroseconds( 10 ); digitalWrite( trigPin, LOW ); duration = pulseIn( echoPin, HIGH ); if (duration > 0) { duration = duration/2; distance = duration*340*100/1000000; if(distance > 100){ distance = 100; } } return distance; } void setup() { Serial.begin(9600); pinMode(motor1A, OUTPUT); pinMode(motor2A, OUTPUT); pinMode(motor1B, OUTPUT); pinMode(motor2B, OUTPUT); pinMode(motorPwm, OUTPUT); digitalWrite(motorPwm, LOW); pinMode( echoPin, INPUT ); pinMode( trigPin, OUTPUT ); forward(); } int sp = 255; int nearCount = 0; int forceTurnCount = 0; int forceBackCount = 0; void loop() { switch(mode){ case modeLeft: turnLeft(); break; case modeRight: turnRight(); break; case modeForward: forward(); break; case modeBackward: backward(); break; } // speed analogWrite(motorPwm,sp); double distance = getDistance(); if(distance < 50){ nearCount ++; }else{ nearCount = 0; } if(nearCount > 10 && mode == modeForward){ mode = modeBackward; forceBackCount = 100; Serial.println("detect object. back"); }else if(mode == modeBackward){ forceBackCount --; if(forceBackCount == 0){ forceTurnCount = 30; mode = modeLeft; } Serial.println("back"); }else if(mode == modeLeft){ forceTurnCount --; if(forceTurnCount == 0){ mode = modeForward; } Serial.println("left"); }else{ mode = modeForward; Serial.println("forward"); } }
動画
距離センサーで壁を検知して回避するようにしてみた 自立して動かすのはなかなか難しい pic.twitter.com/4MrufmSC0f
— ina_ani (@ina_ani) 2018年3月31日
感想
3Dプリンタがあると、こういう物理的な工作が簡単にできました。
また今回は初めからすべてを設計するのではなく、ユニバーサルボード的なものを作って、後付けパーツで組み立てていくという方式にしたため、簡単に設計を試行錯誤することができました。
そして自律的に動くものをプログラムするのは難しいと感じました。今回はとても単純な仕組みで作りましたが、これ以上賢く作るためには、このようなルールをどんどん入れていくか、ロボットが空間を把握するような仕組みをプログラムするか、、 いずれにしても大変そうです。
また気が向いたら改良していこうと思います。
追記:話せるようにしてみる
ちょうど家にあったDFPlayerMiniを使って状況に応じてmp3を再生させるようにしてみました。
昨日のArduinoで作った”掃除しないルンバ” を喋らせてみた 心が宿った感あるぞ pic.twitter.com/uHaD8Fv7pN
— ina_ani (@ina_ani) 2018年4月1日
おきまりのセリフをしゃべるだけだけど、これだけでかなり愛着がわくものになった気がします。
音声は下記サイトのものを利用しました。
参考部品リンク
Arduino
つかったのはこちら
普通のならこれかな?
モーターとギアボックス
つかったのはこれ。もう欠品のようだ
これが同じもののように見える。タイヤも付いている。
プラスチック タイヤ ホイール スマート カー ロボット用 Arduino DC 3V 5V 6V ギアモーター付き 4点セット
- 出版社/メーカー: Yosoo
- メディア:
- この商品を含むブログを見る
モータードライバ
つかったのはこれ。ディスコンらしい。
Amazonにもあるが別のモータードライバを使うのがよさそう。
距離センサー
Amazonならこれかな?
HC-SR04 超音波距離センサーモジュール For Arduino
- 出版社/メーカー: サインスマート(SainSmart)
- メディア: Wireless Phone Accessory
- この商品を含むブログを見る
DFPlayerMini
Rasbee ミニ MP3 プレイヤー DF-Player 音声ヴォイスモジュール TFカード Arduino対応 3個 [並行輸入品]
- 出版社/メーカー: Rasbee
- メディア:
- この商品を含むブログを見る
ブレッドボード
Amazonならこれかな?