① 今日の目標
🏆 Chapter 5 総合作品 ② — DCモーター(Lesson 17)+超音波センサー(Lesson 13)を組み合わせた自律ロボット!
左右2つのモーターで走行・旋回できる
超音波センサーで障害物を検知できる
障害物回避アルゴリズムを実装できる
センサー入力→判断→モーター制御の流れを理解する
② 必要なもの
Arduino Uno
マイコンボード本体
L298Nモータードライバー
2チャンネルで左右モーターを制御
DCモーター×2+タイヤ
左右の車輪を別々に制御
HC-SR04超音波センサー
前方の障害物との距離を計測
外部電源 6〜9V
モーター2個を動かす電力が必要
ロボットカーシャーシ
2WDシャーシキット(車体フレーム)
③ しくみを学ぼう
🚗 左右モーターで方向を制御
| 動き | 左モーター | 右モーター |
|---|---|---|
| ⬆️ 前進 | 正転 | 正転 |
| ⬇️ 後退 | 逆転 | 逆転 |
| ↩️ 左ターン | 停止 or 逆転 | 正転 |
| ↪️ 右ターン | 正転 | 停止 or 逆転 |
| ⏹ 停止 | 停止 | 停止 |
🧠 障害物回避アルゴリズム
🔄 loop() スタート
📡 超音波で距離を測る
❓ 距離 < 20cm?
YES(近い)
⏹ 停止
⬇️ 少し後退
↪️ 右ターン
NO(遠い)
⬆️ 前進
🔄 繰り返し
📡 HC-SR04おさらい(Lesson 13)
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
long dur = pulseIn(ECHO, HIGH);
float dist = dur * 0.034 / 2;
④ Arduinoコード
robot_car.ino
// ── ピン定義 ──
// 超音波センサー
const int TRIG = 9, ECHO = 10;
// 左モーター(L298N チャンネルA)
const int ENA = 3, IN1 = 4, IN2 = 5;
// 右モーター(L298N チャンネルB)
const int ENB = 6, IN3 = 7, IN4 = 8;
const int SPEED = 180; // 通常スピード (0〜255)
const int AVOID_DIST = 20; // 障害物判定距離 (cm)
void setup() {
pinMode(TRIG, OUTPUT); pinMode(ECHO, INPUT);
pinMode(ENA, OUTPUT); pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT);
pinMode(ENB, OUTPUT); pinMode(IN3, OUTPUT); pinMode(IN4, OUTPUT);
Serial.begin(9600);
}
// ── 距離を測る関数 ──
float getDistance() {
digitalWrite(TRIG, LOW); delayMicroseconds(2);
digitalWrite(TRIG, HIGH); delayMicroseconds(10);
digitalWrite(TRIG, LOW);
long dur = pulseIn(ECHO, HIGH);
return dur * 0.034 / 2.0;
}
// ── モーター制御関数 ──
void moveForward(int spd) {
analogWrite(ENA, spd); digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW);
analogWrite(ENB, spd); digitalWrite(IN3, HIGH); digitalWrite(IN4, LOW);
}
void moveBackward(int spd) {
analogWrite(ENA, spd); digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH);
analogWrite(ENB, spd); digitalWrite(IN3, LOW); digitalWrite(IN4, HIGH);
}
void turnRight(int spd) {
analogWrite(ENA, spd); digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW);
analogWrite(ENB, 0); // 右モーター停止
}
void stopAll() {
analogWrite(ENA, 0); analogWrite(ENB, 0);
}
void loop() {
float dist = getDistance();
Serial.print("Distance: "); Serial.println(dist);
if (dist < AVOID_DIST && dist > 0) {
// 障害物発見!回避行動
stopAll(); delay(200);
moveBackward(SPEED); delay(400);
turnRight(SPEED); delay(500);
stopAll(); delay(100);
} else {
// 安全!前進
moveForward(SPEED);
}
}
関数で整理
moveForward()・moveBackward()・turnRight()などの関数にまとめることで、loop()のコードが読みやすくなります。
moveForward()・moveBackward()・turnRight()などの関数にまとめることで、loop()のコードが読みやすくなります。
delay()で動作時間を決める
後退400ms・旋回500msのように、delay()で動く時間を調整します。値を変えることで回り方を変えられます。
後退400ms・旋回500msのように、delay()で動く時間を調整します。値を変えることで回り方を変えられます。
dist > 0 の条件
HC-SR04が範囲外(400cm以上・壁なし)のとき0を返すことがあります。0cmと誤判定しないよう「dist > 0」も条件に入れます。
HC-SR04が範囲外(400cm以上・壁なし)のとき0を返すことがあります。0cmと誤判定しないよう「dist > 0」も条件に入れます。
AVOID_DISTで感度調整
20cmを大きくすると早めに回避、小さくすると障害物に近づいてから回避します。スピードも同様に定数で調整可能!
20cmを大きくすると早めに回避、小さくすると障害物に近づいてから回避します。スピードも同様に定数で調整可能!
⑤ 配線図
💡 L298Nの2チャンネル
L298Nには左右2つのモーター出力があります。チャンネルAが左モーター(ENA/IN1/IN2)、チャンネルBが右モーター(ENB/IN3/IN4)です。
L298Nには左右2つのモーター出力があります。チャンネルAが左モーター(ENA/IN1/IN2)、チャンネルBが右モーター(ENB/IN3/IN4)です。
⑥ チェックリスト
⑦ チャレンジクイズ!
⑧ 🚗 ロボットカーシミュレーター
ロボットカーの動きをシミュレートしよう!障害物の距離を変えて動作を確認できるよ。
⬆️ 前進中
80
cm
前方距離
✅ 安全
左モーター
⬆️
PWM: 180
右モーター
⬆️
PWM: 180
手動でテスト
float dist = getDistance(); // → 80 cm
if (dist < 20 && dist > 0) {
stopAll(); moveBackward(); turnRight();
// → 前進
} else {
moveForward(180); // ⬆️ 前進
}
if (dist < 20 && dist > 0) {
stopAll(); moveBackward(); turnRight();
// → 前進
} else {
moveForward(180); // ⬆️ 前進
}
⑨ まとめ
2モーターで方向制御
左右の速度差で
前進・後退・旋回
左右の速度差で
前進・後退・旋回
関数で整理
moveForward()等に
まとめて読みやすく
moveForward()等に
まとめて読みやすく
回避アルゴリズム
距離判定→停止→
後退→ターン→前進
距離判定→停止→
後退→ターン→前進
自律ロボット完成!
センサー入力を使った
自律制御の基礎習得
センサー入力を使った
自律制御の基礎習得