マイコンでモーターカーを作ろう|2つのDCモーターで前進・後退・旋回

モーター

これまでの記事では、マイコンとモータードライバを使ってDCモーターを正転・逆転させ、さらにPWMを使って回転速度を変える方法を紹介しました。

今回は、DCモーターを2つ使ってモーターカーを動かしてみましょう。

左右のモーターを別々に制御できるようになると、

  • 前進
  • 後退
  • 右旋回
  • 左旋回
  • その場で回転
  • PWMによる滑らかな旋回

といった動きができるようになります。

DCモーター制御の仕組みが、実際の「動くもの」につながっていくところです。

モーターカーはどうやって曲がる?

今回作るのは、左右にDCモーターを1つずつ配置したモーターカーです。

自動車のように前輪の向きを変えて曲がるのではなく、左右の車輪の回転方向や速度を変えることで進行方向を変えます。

たとえば左右のモーターを両方とも前方向へ回せば、車は前進します。

反対に両方を逆方向へ回せば後退します。

そして左右のモーターを違う動きにすると、車体の向きを変えることができます。

左右のモーターを組み合わせて動かす

基本的な動きを整理してみましょう。

左モーター右モーターモーターカー
正転正転前進
逆転逆転後退
停止正転左旋回
正転停止右旋回
逆転正転左方向へその場回転
正転逆転右方向へその場回転
停止停止停止

※モーターの取り付け方向によって正転・逆転の関係は変わります。

重要なのは、左右2つのモーターを独立して制御するという考え方です。

モーターが1個だったときには、

「正転する」

「逆転する」

「停止する」

だけでした。

2個になると、それぞれの状態を組み合わせることで車体そのものの動きを作れるようになります。

モーターを2個動かすには?

DCモーター1個を正転・逆転させるには、Hブリッジ回路を使ったモータードライバを利用できます。

左右2個のモーターをそれぞれ正転・逆転させたい場合は、2つのモーターを独立して制御できるモータードライバ回路が必要です。

基本的な構成は、

マイコン
↓
モータードライバ
↓
左モーター・右モーター

となります。

マイコンから4本の制御信号を出す場合、

  • 左モーター:2本
  • 右モーター:2本

を使って、それぞれの回転方向を制御します。

4本のGPIOで左右のモーターを制御する

ここでは例として、次のGPIOを使用します。

const int B_1A = 7;
const int B_1B = 6;

const int A_1A = 5;
const int A_1B = 4;

A側を左モーター、B側を右モーターとして考えてみましょう。

まずはGPIOを出力に設定します。

void setup() {
  pinMode(B_1A, OUTPUT);
  pinMode(B_1B, OUTPUT);
  pinMode(A_1A, OUTPUT);
  pinMode(A_1B, OUTPUT);
}

これで左右のモータードライバへ制御信号を送れるようになります。

前進させる

まずは左右のモーターを同時に正転させてみましょう。

void forward() {
  digitalWrite(B_1A, HIGH);
  digitalWrite(B_1B, LOW);

  digitalWrite(A_1A, HIGH);
  digitalWrite(A_1B, LOW);
}

左右の車輪が前方向へ回転すれば、モーターカーは前進します。

ただし、左右のモーターは車体に対して鏡合わせに取り付けることがあります。

その場合、一方のモーターではHIGH/LOWの組み合わせを反対にする必要があります。

実際に動かしてみて、一方だけ逆方向へ回る場合は制御方向を確認しましょう。

後退させる

前進とは反対に、左右のモーターを逆転させます。

void reverse() {
  digitalWrite(B_1A, LOW);
  digitalWrite(B_1B, HIGH);

  digitalWrite(A_1A, LOW);
  digitalWrite(A_1B, HIGH);
}

これで左右の車輪が逆方向へ回り、モーターカーが後退します。

停止させる

両方のモーターを停止します。

void stopAll() {
  digitalWrite(B_1A, LOW);
  digitalWrite(B_1B, LOW);

  digitalWrite(A_1A, LOW);
  digitalWrite(A_1B, LOW);
}

モーターカーを作るときは、前進・後退だけでなく確実に停止できる処理も用意しておきましょう。

左右に曲がる

モーターカーを曲げる最も簡単な方法は、片方のモーターを停止することです。

たとえば左モーターを停止し、右モーターだけを回転させれば、車体は左方向へ向きを変えます。

void turnLeft() {
  // 右モーター
  digitalWrite(B_1A, HIGH);
  digitalWrite(B_1B, LOW);

  // 左モーター停止
  digitalWrite(A_1A, LOW);
  digitalWrite(A_1B, LOW);
}

反対にすれば右方向へ曲がります。

void turnRight() {
  // 右モーター停止
  digitalWrite(B_1A, LOW);
  digitalWrite(B_1B, LOW);

  // 左モーター
  digitalWrite(A_1A, HIGH);
  digitalWrite(A_1B, LOW);
}

これだけでも前後左右に動くモーターカーを作れます。

その場で回転する

さらに左右のモーターを反対方向へ回すと、車体をその場で回転させることもできます。

たとえば、

左モーター:逆転
右モーター:正転

とします。

void spinLeft() {
  // 右モーター正転
  digitalWrite(B_1A, HIGH);
  digitalWrite(B_1B, LOW);

  // 左モーター逆転
  digitalWrite(A_1A, LOW);
  digitalWrite(A_1B, HIGH);
}

反対に、

左モーター:正転
右モーター:逆転

とすれば、反対方向へその場回転できます。

狭い場所で方向転換するときなどに利用できる動きです。

前進・停止・後退・旋回を順番に試してみる

ここまでの処理を組み合わせてみましょう。

const int B_1A = 7;
const int B_1B = 6;
const int A_1A = 5;
const int A_1B = 4;

void setup() {
  pinMode(B_1A, OUTPUT);
  pinMode(B_1B, OUTPUT);
  pinMode(A_1A, OUTPUT);
  pinMode(A_1B, OUTPUT);
}

void forward() {
  digitalWrite(B_1A, HIGH);
  digitalWrite(B_1B, LOW);
  digitalWrite(A_1A, HIGH);
  digitalWrite(A_1B, LOW);
}

void reverse() {
  digitalWrite(B_1A, LOW);
  digitalWrite(B_1B, HIGH);
  digitalWrite(A_1A, LOW);
  digitalWrite(A_1B, HIGH);
}

void stopAll() {
  digitalWrite(B_1A, LOW);
  digitalWrite(B_1B, LOW);
  digitalWrite(A_1A, LOW);
  digitalWrite(A_1B, LOW);
}

void turnLeft() {
  digitalWrite(B_1A, HIGH);
  digitalWrite(B_1B, LOW);
  digitalWrite(A_1A, LOW);
  digitalWrite(A_1B, LOW);
}

void turnRight() {
  digitalWrite(B_1A, LOW);
  digitalWrite(B_1B, LOW);
  digitalWrite(A_1A, HIGH);
  digitalWrite(A_1B, LOW);
}

void loop() {
  // 前進
  forward();
  delay(2000);

  // 停止
  stopAll();
  delay(1000);

  // 後退
  reverse();
  delay(2000);

  // 停止
  stopAll();
  delay(1000);

  // 左旋回
  turnLeft();
  delay(1000);

  // 停止
  stopAll();
  delay(1000);

  // 右旋回
  turnRight();
  delay(1000);

  // 停止
  stopAll();
  delay(2000);
}

これで、

前進 → 停止 → 後退 → 停止 → 左旋回 → 停止 → 右旋回 → 停止

という一連の動作を確認できます。

PWMを使えばもっと滑らかに曲がれる

片方のモーターを完全に停止させれば簡単に旋回できますが、前回学習したPWMを利用すると、もっと細かく動きを制御できます。

たとえば、

左モーター:PWM 255
右モーター:PWM 150

のように設定します。

両方のモーターは前進していますが、左側の方が速く回転します。

その結果、車体は速度の遅い右側へ曲がっていきます。

左右のPWM値の差を小さくすれば緩やかに曲がり、大きくすれば急に曲がる、といった調整もできます。

つまりPWMは単なる「モーターの速度変更」だけではなく、モーターカーの進行方向を制御するためにも使えるわけです。

左右のモーターは同じ速度で回るとは限らない

実際にモーターカーを走らせてみると、

「両方に同じPWM値を指定しているのに、まっすぐ走らない」

ということがあります。

これは珍しいことではありません。

DCモーターには個体差があり、

  • モーターそのものの特性
  • ギヤの摩擦
  • タイヤの状態
  • 車体の重量バランス
  • 電源電圧
  • 床との摩擦

などによって左右の回転速度に差が出ます。

そこで実際のモーターカーでは、左右のPWM値を少し変えて直進するよう調整することがあります。

たとえば、

int leftSpeed  = 230;
int rightSpeed = 250;

のように左右で異なる値を設定します。

プログラム上では同じ「前進」でも、実際の機械では調整が必要になる。

これは実機を使った組み込み開発の面白いところでもあります。

KUMITATE-MOTORでモーターカーを動かしてみよう

クミタテでは、KUMITATE-C3と組み合わせてモーター制御を学習できるKUMITATE-MOTORを用意しています。

KUMITATE-MOTORでは左右のDCモーターを使って、

  • 正転・逆転
  • 前進・後退
  • 左右旋回
  • その場回転
  • PWMによる速度制御
  • 左右モーターの独立制御

などを実際に試すことができます。

DCモーター1個を回すだけでは分かりにくかった「複数の出力を組み合わせて機械を動かす」という考え方も、モーターカーにすると視覚的に理解しやすくなります。

▶ KUMITATE-MOTORの詳細はこちら
https://kumicla.tatepro.com/asp-products/kumitate-motor/

モーターカーはさらに発展できる

前進・後退・旋回ができれば、モーターカーとしての基本部分は完成です。

しかしマイコンを使っているので、ここからさらに機能を追加できます。

たとえば、

無線通信
→ スマートフォンや別のマイコンから操作する

距離センサー
→ 障害物を見つけて自動停止する

光センサー
→ 明るさによって動きを変える

加速度センサー
→ 車体の動きを検出する

などです。

単純なモーターカーから始めて、センサーや通信を追加していくことで、マイコンでできることが一気に広がります。

まとめ

今回は、2つのDCモーターを使ってモーターカーを制御する方法を紹介しました。

ポイントは、

  • 左右のDCモーターを独立して制御する
  • 両方を正転させれば前進できる
  • 両方を逆転させれば後退できる
  • 左右で異なる動きをさせることで旋回できる
  • 左右を逆方向へ回せばその場回転もできる
  • PWMで左右の速度差を作れば滑らかな旋回ができる
  • 実際のモーターには個体差があるため速度調整が必要になる場合がある

というところです。

ここまでで、DCモーターの正転・逆転 → PWM速度制御 → 2モーターによるモーターカーまでつながりました。

次は、作ったモーターカーを無線通信で操作する方法へ発展させてみましょう。

KUMITATE

読むだけでなく、
実際に動かして学びませんか?

クミタテは、組み込み開発や電子工作を 実践しながら学べる学習プラットフォームです。 ESP32を使ったプログラミングから、電子回路、センサー、 通信、基板設計まで、自分のペースで学習できます。

  • 無料で学べる実践的な教材を掲載
  • すぐに試せるサンプルプログラム付き
  • Googleアカウントですぐに登録可能
クミタテに無料登録する
モーター
スポンサーリンク