NodeMCUとTCRT5000赤外線センサーを2個、そして2チャンネル(右前進・左前進)のモータードライバーを使用したライントレースロボットのプログラムを作成します。
センサーを2個使用することで、1個の時よりもスムーズなライントレースが可能になります。ロボットは線の両端(エッジ)を捉えながら進みます。
概要
センサー2個を、黒い線の両側(外側)の白い地面を検出するように配置します。
- 両方のセンサーが白: ロボットは線の中央にいると判断し、直進します。
- 左センサーが黒、右センサーが白: ロボットが右にズレすぎたと判断し、左に曲がります(右モーターON、左モーターOFF)。
- 左センサーが白、右センサーが黒: ロボットが左にズレすぎたと判断し、右に曲がります(左モーターON、右モーターOFF)。
重要な注意点 (NodeMCUのアナログピン)
ESP32ではアナログ値が読み取れるピンが18ピン(Wifiを使う場合は8ピン)ありますが、廉価版のNodeMCU (ESP8266) には、アナログ値を読み取れるピン(A0)が1つしかありません。
そのため、TCRT5000センサーモジュールのアナログ出力(A0)を2つ同時に使うことはできません。
解決策:
センサーモジュールに搭載されているデジタル出力(DO)ピンを使用します。DOピンは、センサーが白か黒かを0か1で出力するため、NodeMCUのデジタルピン(D1, D2など)で読み取ることができます。
必要なもの
- NodeMCU (ESP8266)
- 赤外線反射センサー TCRT5000モジュール x 2 (DO出力があるもの)
- モータードライバー (L9110S, TB6612など)
- DCモーター x 2 と車体
- 電源
配線例 (DOピンを使用)
| 接続元 | 接続先 | 備考 |
| NodeMCU | ||
| D5 (GPIO14) | 左センサー デジタル出力 (DO) | |
| D6 (GPIO12) | 右センサー デジタル出力 (DO) | |
| D1 (GPIO5) | 右モータードライバー入力 (右前進) | |
| D2 (GPIO4) | 左モータードライバー入力 (左前進) | |
| 3V3 (3.3V) | 各センサー VCC | センサー電源 |
| GND | 各センサー GND | センサーGND |
| (外部電源) | モータードライバー VM + GND | モーター用電源 |
| VIN | モータードライバー VCC | ドライバーロジック用電源 |
| GND | モータードライバー GND | NodeMCUとGNDを共通化 |
Arduino IDE プログラム (デジタルDO版)
このプログラムをArduino IDEにコピー&ペーストしてNodeMCUに書き込んでください。
/*
* NodeMCUとTCRT5000センサー2個 (DO) によるライントレース
*
* 条件:
* - 両センサーが白: 前進
* - どちらかのセンサーが黒: 黒を感知した側のモーターを停止
*
* ピン配置:
* - 左センサー (DO): D5 (GPIO14)
* - 右センサー (DO): D6 (GPIO12)
* - 右モーター (前進): D1 (GPIO5)
* - 左モーター (前進): D2 (GPIO4)
*/
// ===== ピン設定 (指定通り) =====
const int LEFT_SENSOR_PIN = D5; // 左センサー (GPIO14)
const int RIGHT_SENSOR_PIN = D6; // 右センサー (GPIO12)
const int RIGHT_MOTOR_PIN = D1; // 右モーター前進用 (GPIO5)
const int LEFT_MOTOR_PIN = D2; // 左モーター前進用 (GPIO4)
// ===== センサーのHIGH/LOW設定 =====
// センサーモジュールによって、黒を検出したときの出力がHIGHかLOWか異なります。
// 動作が逆の場合は、ここの値を入れ替えてください。
const int BLACK = LOW; // 黒を検出した時のセンサー出力 (一般的)
const int WHITE = HIGH; // 白を検出した時のセンサー出力 (一般的)
void setup() {
// デバッグ用にシリアル通信を開始
Serial.begin(115200);
// センサーピンを入力モードに設定
pinMode(LEFT_SENSOR_PIN, INPUT);
pinMode(RIGHT_SENSOR_PIN, INPUT);
// モーター制御ピンを出力モードに設定
pinMode(RIGHT_MOTOR_PIN, OUTPUT);
pinMode(LEFT_MOTOR_PIN, OUTPUT);
// 起動時にモーターを停止
digitalWrite(RIGHT_MOTOR_PIN, LOW);
digitalWrite(LEFT_MOTOR_PIN, LOW);
// 5秒待機。ロボットをコースに置く時間
Serial.println("5秒後にスタートします...");
Serial.println("センサーを調整してください。");
delay(5000);
Serial.println("スタート!");
}
void loop() {
// センサーからデジタル値を読み取る (BLACK または WHITE)
int leftValue = digitalRead(LEFT_SENSOR_PIN);
int rightValue = digitalRead(RIGHT_SENSOR_PIN);
// デバッグ用にセンサーの状態を表示
Serial.print("左: ");
Serial.print(leftValue == BLACK ? "黒" : "白");
Serial.print(" | 右: ");
Serial.println(rightValue == BLACK ? "黒" : "白");
// ===== ご指定のライントレース ロジック =====
// 1. (左:白, 右:白) -> 両方のセンサーが白
// 動作: 前進 (両モーターON)
if (leftValue == WHITE && rightValue == WHITE) {
Serial.println(" -> 直進");
digitalWrite(LEFT_MOTOR_PIN, HIGH);
digitalWrite(RIGHT_MOTOR_PIN, HIGH);
}
// 2. (左:黒, 右:白) -> 左センサーが黒
// 動作: 左モーターを止める (右へ曲がる)
else if (leftValue == BLACK && rightValue == WHITE) {
Serial.println(" -> 右へ (左モーター停止)");
digitalWrite(LEFT_MOTOR_PIN, LOW);
digitalWrite(RIGHT_MOTOR_PIN, HIGH);
}
// 3. (左:白, 右:黒) -> 右センサーが黒
// 動作: 右モーターを止める (左へ曲がる)
else if (leftValue == WHITE && rightValue == BLACK) {
Serial.println(" -> 左へ (右モーター停止)");
digitalWrite(LEFT_MOTOR_PIN, HIGH);
digitalWrite(RIGHT_MOTOR_PIN, LOW);
}
// 4. (左:黒, 右:黒) -> 両センサーが黒 (交差点、または線が太い)
// 動作: 停止 (安全のため両方停止)
else {
Serial.println(" -> 停止 (両方黒)");
digitalWrite(LEFT_MOTOR_PIN, LOW);
digitalWrite(RIGHT_MOTOR_PIN, LOW);
}
delay(10); // 処理の安定化
}【最重要】センサーの調整方法
デジタル出力(DO)を使う場合、プログラムの「閾値」の代わりに、センサーモジュール本体の調整が必要です。
- ポテンショメータ(可変抵抗)を見つける: TCRT5000モジュールには、通常、小さなマイナスドライバーで回せる青い部品(ポテンショメータ)が付いています。これが閾値調整用です。
- 電源を入れる: プログラムを書き込んだNodeMCUに電源を入れます。
- シリアルモニタを開く: Arduino IDEのシリアルモニタ(115200 bps)を開きます。
- 左センサーの調整:
- 左センサーを白い地面の上に置きます。
- シリアルモニタで「左: 白」と表示されるように、左センサーのポテンショメータをゆっくり回します。モジュールのLEDが消灯するはずです。
- 次に、左センサーを黒い線の上に置きます。
- シリアルモニタで「左: 黒」と表示されることを確認します。モジュールのLEDが点灯するはずです。
- 右センサーの調整:
- 右センサーでも4と同様の調整を行い、「右: 白」「右: 黒」が正しく表示されるようにします。
- 動作確認: 両方のセンサーが白と黒を正しく区別できるようになったら、ロボットをコースに置いて走らせてみてください。
うまく動かない場合のヒント
- 動きが逆の場合:
const int BLACK = HIGH;とconst int WHITE = LOW;のHIGHとLOWを入れ替えてみてください。- または、
else ifブロック内のモーター制御(digitalWrite)のHIGH/LOWを左右で入れ替えてみてください。
- ジグザグしすぎる場合: モーターの速度が速すぎるかもしれません。PWM制御(
analogWrite)で速度を落とすか、電源電圧を下げることを検討してください。(このプログラムはON/OFFのみの制御です)


コメント