Non-engineer memoblog

エンジニアではない人間のメモブログ(備忘録とアウトプット欲のために)

ArduinoでRover超入門

ArduinoでRoverを超入門した話(というほどのモノでもないですが)。

構成

  • Arduino UNO x 1
  • Arduino用モバイルバッテリー
  • 超音波センサ x 1
  • マイクロサーボ x 1

マイクロサーボ9g SG−90: パーツ一般 秋月電子通商 電子部品 ネット通販
超音波距離センサー HC−SR04: センサ一般 秋月電子通商 電子部品 ネット通販

  • モータードライバ x 2
  • その他もろもろ

モータードライバはSN754410NE(2つあれば4輪駆動が可能)
akizukidenshi.com

Rover本体側のパーツ

マイコンカーベース板 - aitendo
モータホルダ - aitendo
ホイール付きタイヤ - aitendo
DC減速型モータ - aitendo
電池ボックス 単3×4本 リード線・フタ・スイッチ付: パーツ一般 秋月電子通商 電子部品 ネット通販

大変だったこと

通常の単3電池4本だと、パワーが足りずめちゃくちゃ遅いか、駆動ができない状態に。。。プログラムやパーツの重量の原因なのは重々承知でしたが、ちまたのRover動画などを拝見してるとめちゃくちゃスムーズに動いていて・・・

そんな時、ニッケル単3電池が出力強いよと知り合いが言っていたので、ためしに変更してみましたところ、

なんと!!(ギリギリではありますが)まともに動くようになりました!!
vimeo.com
(1.5Vから1.2Vの電池へ交換なのになぜなんだぜ??)

その他大変だったこと

  • ジャンパワイヤの配線が大変でしたし、結果すんごい汚い状態で接続(ちまたの完成形では恐ろしいほどにみんな綺麗で無駄がない)
  • 各モーター(4個)それぞれにコンデンサを1つだけ半田付けしましたが、これが結構難しくて大変でした(本当は2つずつ付けたかった)
  • バッテリーボックスをジャンパワイヤ接続できるようにコンタクタなどを買ったですが、どうしてもうまくカシめることができずに知り合いにカシめてもらいました。

プログラム

#include<Servo.h>

//アナログピンをデジタルピンとして代用
#define MOTOR_A1 14
#define MOTOR_A2 15
#define MOTOR_B1 17
#define MOTOR_B2 16

#define MOTOR_C1 6
#define MOTOR_C2 7
#define MOTOR_D1 12
#define MOTOR_D2 13

Servo myservo;

int motor_speed = 255;   //回転速度(0~255段階)

const int trigPin = 2;   //HC-SR04のトリガーを2pin
const int echoPin = 4;   //HC-SR04のエコーを4pin
unsigned long duration;  //距離(HC-SR04)
int cm;                  //距離(cmへ変換)

void setup()
{
    pinMode(MOTOR_A1, OUTPUT);
    pinMode(MOTOR_A2, OUTPUT);
    pinMode(11, OUTPUT);

    pinMode(MOTOR_B1, OUTPUT);
    pinMode(MOTOR_B2, OUTPUT);
    pinMode(3, OUTPUT);

    pinMode(MOTOR_C1, OUTPUT);
    pinMode(MOTOR_C2, OUTPUT);
    pinMode(9, OUTPUT);

    pinMode(MOTOR_D1, OUTPUT);
    pinMode(MOTOR_D2, OUTPUT);
    pinMode(10, OUTPUT);

    //HC-SR04の設定
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);
    Serial.begin(9600);

    //SG90の設定
    myservo.attach(5);
    //SG90を横に取り付けたため初期値90に設定
    myservo.write(90);
}

void loop() {
    motor_foward();
    conflict_control();
}

//---距離検出-------------------------------------
void detect_sonor()
{
    //pinをOUTPUTに設定(パルス送信のため)
    pinMode(trigPin, OUTPUT);
    //LOWパルスを送信
    digitalWrite(trigPin, LOW);
    delayMicroseconds(5);
    //HIGHパルスを送信
    digitalWrite(trigPin, HIGH);
    //10uSパルスを送信してHC-SR04を起動
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    //入力パルスの長さを測定
    duration = pulseIn(echoPin, HIGH);

    //パルスの長さを半分に分割
    duration = duration / 2;
    //cmに変換
    cm = int(duration / 29);

    //シリアルコンソールに表示
    Serial.print(cm);
    Serial.print("cm");
    Serial.println();

    delay(100);
}

//---衝突回避-------------------------------------
void conflict_control()
{
    detect_sonor();
    if (cm <= 20) {
        motor_stop();
        motor_back();
        motor_stop();
        //左方確認
        myservo.write(165);
        delay(500);
        detect_sonor();
        if (cm <= 20) {
            //右方確認
            myservo.write(10);
            delay(500);
            detect_sonor();
            if (cm <= 20) {
                //前方向を向く
                myservo.write(90);
                delay(500);
                motor_back();
                motor_stop();
                //左方確認(再)
                myservo.write(165);
                delay(500);
                detect_sonor();
                if (cm <= 20) {
                    //右方確認(再)
                    myservo.write(10);
                    delay(500);
                    detect_sonor();
                    if (cm <= 20) {
                        //前方
                        myservo.write(90);
                        delay(500);
                        //方向転換(180度)
                        motor_left();
                        delay(2000);
                        motor_foward();
                    } else {
                        //前方
                        myservo.write(90);
                        delay(500);
                        motor_left();
                        motor_foward();
                    }
                } else {
                    //前方
                    myservo.write(90);
                    delay(500);
                    motor_left();
                    motor_foward();
                }
            } else {
                //前方
                myservo.write(90);
                delay(500);
                motor_left();
                motor_foward();
            }
        } else {
            //前方
            myservo.write(90);
            delay(500);
            motor_right();
            motor_foward();
        }
    }
}

//---前進-------------------------------------
void motor_foward()
{
    digitalWrite(MOTOR_A1, HIGH);
    digitalWrite(MOTOR_A2, LOW);
    analogWrite(11, motor_speed);

    digitalWrite(MOTOR_B1, HIGH);
    digitalWrite(MOTOR_B2, LOW);
    analogWrite(3, motor_speed);

    digitalWrite(MOTOR_D2, HIGH);
    digitalWrite(MOTOR_D1, LOW);
    analogWrite(9, motor_speed);

    digitalWrite(MOTOR_C2, HIGH);
    digitalWrite(MOTOR_C1, LOW);
    analogWrite(10, motor_speed);
}

//---後退-------------------------------------
void motor_back()
{
    digitalWrite(MOTOR_A1, LOW);
    digitalWrite(MOTOR_A2, HIGH);
    analogWrite(11, motor_speed);

    digitalWrite(MOTOR_B1, LOW);
    digitalWrite(MOTOR_B2, HIGH);
    analogWrite(3, motor_speed);

    digitalWrite(MOTOR_D2, LOW);
    digitalWrite(MOTOR_D1, HIGH);
    analogWrite(9, motor_speed);

    digitalWrite(MOTOR_C2, LOW);
    digitalWrite(MOTOR_C1, HIGH);
    analogWrite(10, motor_speed);

    delay(500);
}

//---左旋回-------------------------------------
void motor_left()
{
    digitalWrite(MOTOR_A1, HIGH);
    digitalWrite(MOTOR_A2, LOW);
    analogWrite(11, 255);

    digitalWrite(MOTOR_B1, LOW);
    digitalWrite(MOTOR_B2, HIGH);
    analogWrite(3, motor_speed);

    digitalWrite(MOTOR_D2, HIGH);
    digitalWrite(MOTOR_D1, LOW);
    analogWrite(9, motor_speed);

    digitalWrite(MOTOR_C2, LOW);
    digitalWrite(MOTOR_C1, HIGH);
    analogWrite(10, motor_speed);

    delay(1000);
}

//---右旋回-------------------------------------
void motor_right()
{
    digitalWrite(MOTOR_A1, LOW);
    digitalWrite(MOTOR_A2, HIGH);
    analogWrite(11, motor_speed);

    digitalWrite(MOTOR_B1, HIGH);
    digitalWrite(MOTOR_B2, LOW);
    analogWrite(3, motor_speed);

    digitalWrite(MOTOR_D2, LOW);
    digitalWrite(MOTOR_D1, HIGH);
    analogWrite(9, motor_speed);

    digitalWrite(MOTOR_C2, HIGH);
    digitalWrite(MOTOR_C1, LOW);
    analogWrite(10, motor_speed);

    delay(1000);
}

//---停止-------------------------------------
void motor_stop()
{
    analogWrite(11, 0);
    analogWrite(3, 0);

    analogWrite(9, 0);
    analogWrite(10, 0);

    delay(500);
}

普通の人なら簡単にできそうなことかもですが、結構(かなり)大変でしたが、動いてよかった!!