Arduinoサーボ制御から応用へ!DCモーターと超音波センサー(HC-SR04)で追従システムを作る方法

Arduinoを使った電子工作は、アイデア次第で様々なものを生み出せる魅力的な趣味です。サーボモーターでアームを動かしたり、LEDを点滅させたりすることから始める方も多いのではないでしょうか。

本記事では、サーボモーターの基本的な制御から一歩進んで、DCモーターと**超音波距離センサー(HC-SR04)**を組み合わせ、前方の障害物に自動で追従するシステムの構築方法を、ステップバイステップで詳しく解説します。

目次

ステップ1:基本のおさらい「サーボモーター」

まず基本となるのがサーボモーターです。今回は「GeekServo 9G Servo-Gray」を例に挙げます。サーボモーターは、指定した角度にピタッと動かしたい場合(例えば、ロボットアームの関節や車のステアリングなど)に使われます。

配線は非常にシンプルです。

  • 黄 (または白・オレンジ): 信号線 (PWM) → Arduino の PWM対応ピン (例: D9)
  • 赤: 電源 (VCC) → Arduino の 5V
  • 茶 (または黒): GND (グラウンド) → Arduino の GND

Arduinoの標準ライブラリ Servo.h を使えば、myServo.write(角度); のような簡単な命令で制御できます。

(※サーボの基本的な動かし方の詳細は、以前の記事「ArduinoでGeekServo 9G Servo-Grayを制御する方法」もご参照ください。)

ステップ2:発展「DCモーター」の追加

サーボモーターの次に使いたくなるのが、タイヤなどを連続して回転させるための「DCモーター」です。ここでは「GeekServo 9G Motor-Red」(これはDCモーターです)があると仮定します。

DCモーターを動かすには、サーボモーターとは少し異なる準備が必要です。

なぜ「モータードライバー」が必要か?

DCモーターは、サーボモーターやLEDに比べて大きな電流を必要とします。Arduinoのピンから直接電源を取ろうとすると、電流が足りずに動作しないか、最悪の場合Arduinoが故障してしまいます。

そこで登場するのが「モータードライバー」(例: L298N, DRV8833, TB6612FNG など)です。

モータードライバーは、Arduinoからの「正転しろ」「逆転しろ」「このくらいの速度で回れ」という小さな信号を受け取り、外部電源(バッテリーなど)からの大きな電力をモーターに流す役割を担います。

サーボでステアリング(方向転換)を、DCモーターで駆動(前進・後退)を担当させれば、車型ロボットの基本的な動きが完成します。

ステップ3:応用「超音波センサー(HC-SR04)」で自動制御

さて、車体が動くようになったら、次は「自動制御」に挑戦したくなります。ここで活躍するのが「超音波距離センサー HC-SR04」です。

HC-SR04は、人間には聞こえない超音波を発射し、それが障害物に当たって跳ね返ってくるまでの時間を計測することで、障害物までの距離を割り出すことができます。

これを使えば、「前方の障害物(あるいは先行車)との距離を測り、一定の距離を保ちながら追従する」といった賢い動作が可能になります。

HC-SR04を使った追従システムの構築

それでは、これら3つの要素(サーボは今回使いませんが、応用としてDCモーターとセンサー)を組み合わせて、簡単な追従システムを作ってみましょう。

1. 必要な部品

  • Arduino (Uno, Nano など)
  • 超音波センサー (HC-SR04)
  • DCモーター (GeekServo 9G Motor-Red など)
  • モータードライバー (L298N, DRV8833 などを想定)
  • モーター用の外部電源 (電池ボックスなど)
  • ジャンパーワイヤー

2. ピン配置(接続例)

ここでは、一般的なモータードライバー(2ピンで方向制御、1ピンで速度制御(PWM)が可能なタイプ)を想定しています。

重要: モータードライバーには、Arduinoとは別に**モーター用の電源(バッテリーなど)を接続してください。そして、その電源のGNDとArduinoのGNDを必ず接続(共通GNDに)**してください。

① 超音波センサー (HC-SR04) の接続

HC-SR04Arduino役割
VCC5Vセンサーへの電源
GNDGND接地
TRIGD6超音波を発射するトリガー信号
ECHOD7超音波が返ってくるのを受け取る信号

② モータードライバーとDCモーターの接続

モータードライバーArduino役割
IN1 (入力1)D9モーターの回転方向制御1
IN2 (入力2)D10モーターの回転方向制御2
ENA (または PWM)D5 (PWMピン)モーターの速度制御(PWM)
モーター端子1DCモーターの片側
モーター端子2DCモーターの反対側

3. Arduinoサンプルコード

以下のコードは、前方の障害物との距離を測り、一定の距離(SAFE_DISTANCE)を保つようにモーターの速度を制御するスケッチです。

/*
 * 超音波センサー(HC-SR04)を使った追従システム
 */

// --- ピン定義 ---
// HC-SR04
#define TRIG_PIN 6  // HC-SR04のTRIGピン
#define ECHO_PIN 7  // HC-SR04のECHOピン

// モータードライバー
#define MOTOR_IN1 9   // モーター制御ピン1 (方向)
#define MOTOR_IN2 10  // モーター制御ピン2 (方向)
#define MOTOR_PWM 5   // モーター速度制御ピン (PWM対応ピン)

// --- 制御設定 ---
const int SAFE_DISTANCE = 30;  // この距離(cm)を保とうとする
const int MAX_SPEED = 200;     // 最大速度 (0~255)
const int MIN_SPEED = 100;     // 追従時の最低速度 (0~255)
const int TOO_CLOSE = 25;      // これより近づいたら停止 (SAFE_DISTANCEより小さく)

void setup() {
  // ピンモードの設定
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  pinMode(MOTOR_IN1, OUTPUT);
  pinMode(MOTOR_IN2, OUTPUT);
  pinMode(MOTOR_PWM, OUTPUT);

  // シリアル通信を開始 (デバッグ用)
  Serial.begin(9600);
}

void loop() {
  long duration;
  int distance;

  // --- 1. 超音波センサーで距離測定 ---
  // トリガーピンを一旦LOWにする
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  
  // トリガーピンを10μs HIGHにして超音波を発射
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  
  // ECHOピンがHIGHになった時間(μs)を測定
  duration = pulseIn(ECHO_PIN, HIGH);
  
  // 時間を距離(cm)に変換 (音速 約340m/s を利用)
  distance = duration * 0.034 / 2;

  // シリアルモニタに距離を表示
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");

  // --- 2. 距離に応じたモーター制御 ---
  if (distance > SAFE_DISTANCE) {
    // 目標より遠い場合: 加速して近づく
    // 遠ければ遠いほど速く (最大MAX_SPEEDまで)
    int speed = map(distance, SAFE_DISTANCE, SAFE_DISTANCE + 50, MIN_SPEED, MAX_SPEED);
    speed = constrain(speed, MIN_SPEED, MAX_SPEED); // 速度が範囲内に収まるように調整
    motorForward(speed);
    
  } else if (distance < TOO_CLOSE) {
    // 近づきすぎた場合: 停止
    motorStop();
    
  } else {
    // 適正な距離 (TOO_CLOSE ~ SAFE_DISTANCE) の場合: 低速で維持
    motorForward(MIN_SPEED);
  }

  delay(100); // 100ms待機して繰り返す
}

// --- モーター制御用の関数 ---

// 前進
void motorForward(int speed) {
  digitalWrite(MOTOR_IN1, HIGH);
  digitalWrite(MOTOR_IN2, LOW);
  analogWrite(MOTOR_PWM, speed); // PWMで速度制御
}

// 停止
void motorStop() {
  digitalWrite(MOTOR_IN1, LOW);
  digitalWrite(MOTOR_IN2, LOW);
  analogWrite(MOTOR_PWM, 0);
}

コードのポイント解説

  1. 距離の測定: pulseIn() 関数で超音波が返ってくる時間を測定し、distance = duration * 0.034 / 2; の式で距離(cm)に変換しています。
  2. モーター制御ロジック: if-else if-else構文を使い、測定した距離に応じて3つのパターン(加速、低速維持、停止)に分けています。
  3. 速度調整 (map関数): map(distance, SAFE_DISTANCE, SAFE_DISTANCE + 50, MIN_SPEED, MAX_SPEED) の部分は、「距離が30cmから80cm(30+50)の間にある場合、その距離に応じて速度を100から200の間に線形に変化させる」という命令です。これにより、遠いほど速く、近いほどゆっくり近づく、滑らかな制御を目指しています。
  4. 関数化: motorForward()motorStop() のように、モーターの動作を関数としてまとめておくことで、loop()の中のコードがスッキリと読みやすくなります。

まとめ

今回は、Arduinoを使った電子工作のステップアップとして、サーボモーターの基本から始まり、DCモーターとモータードライバー、さらに超音波センサー(HC-SR04)を組み合わせて「追従システム」を構築する方法をご紹介しました。

  • サーボモーター:角度制御(ステアリングなど)
  • DCモーター+ドライバー:連続回転(駆動輪など)
  • 超音波センサー:距離測定(自動制御の「目」)

このように、Arduinoでは基本的な部品を組み合わせることで、アイデア次第で非常に高度なシステムを作り上げることが可能です。

ここからさらに、サーボモーターで超音波センサーを左右に振って(首振り)、より広範囲の障害物を検知する「障害物回避車」などへも発展させることができます。ぜひ、挑戦してみてください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次