Arduino Nano Bluetooth
Line Follower Robot
Autonomous IR path tracking + wireless Bluetooth smartphone control. 5-channel sensor array, L298N H-bridge, HC-05 module, 18650 battery pack.
What This Robot Does
The Arduino Nano Bluetooth Line Follower Robot combines two powerful capabilities in one chassis: it autonomously follows a black line on a white surface using a 5-channel IR sensor array, and can be switched to manual Bluetooth control from any smartphone app at any time.
Powered by dual 18650 lithium-ion batteries regulated through a DC-DC buck converter, the robot uses an L298N H-bridge driver to independently control two geared DC motors — enabling sharp turns, precise speed control via PWM, and smooth directional changes.
Key Components
How the System Works
IR Sensor Array — Path Detection
Five IR sensors (A0–A4) read analog values. A value below 500 means the sensor is over the black line. The Arduino maps sensor combinations to movement decisions: forward, turn left, turn right, or stop.
L298N Motor Driver — Speed & Direction
The L298N H-bridge receives PWM signals via analogWrite() on ENA (pin 3) and ENB (pin 9), and direction signals via IN1–IN4 (pins 4,5,7,8). Independent control of each motor enables turning in place.
HC-05 Bluetooth — Wireless Override
The HC-05 module listens on UART (D0 RX / D1 TX) at 9600 baud. Single-character commands (F/B/L/R/S) from a smartphone app are read in loop() and passed to executeBluetoothCommand(), overriding autonomous control immediately.
Buck Converter — Stable Power
The 18650 battery pack (7.4V) feeds the L298N motor driver directly for full motor torque, while the DC-DC buck converter steps voltage down to 5V for the Arduino Nano — preventing motor noise from affecting the microcontroller.
IR Sensor → Motor Action Table
The robot reads all 5 sensors every loop cycle and decides motor action based on which sensors detect the black line (shown as 🔴 ON):
| S1 | S2 | S3 (Centre) | S4 | S5 | Action | Motor A | Motor B |
|---|---|---|---|---|---|---|---|
| Forward | 255 | 255 | |||||
| Turn Left | 255 | 0 | |||||
| Turn Right | 0 | 255 | |||||
| Forward | 255 | 255 | |||||
| Stop | 0 | 0 |
Serial.println(irValues[i]) to calibrate in real time.Smartphone Command Reference
Use any Bluetooth serial app (e.g. Bluetooth RC Controller, Serial Bluetooth Terminal) paired with the HC-05 at 9600 baud. Send these single-character commands:
Pin Connections
Wiring: Arduino Nano ↔ 5-Ch IR Array (A0–A4) · L298N (D3–D9) · HC-05 (D0/D1) · 18650 + Buck Converter
| Component | Signal | Arduino Nano Pin | Notes |
|---|---|---|---|
| 5-Channel IR Sensor Array | |||
| IR Sensor 1 (leftmost) | Analog OUT | A0 | <500 = line detected |
| IR Sensor 2 | Analog OUT | A1 | <500 = line detected |
| IR Sensor 3 (centre) | Analog OUT | A2 | Primary tracking sensor |
| IR Sensor 4 | Analog OUT | A3 | <500 = line detected |
| IR Sensor 5 (rightmost) | Analog OUT | A4 | <500 = line detected |
| L298N Motor Driver (Motor A — Left) | |||
| L298N ENA | PWM Speed A | D3 | PWM-capable pin |
| L298N IN1 | Direction A1 | D4 | Motor A forward/reverse |
| L298N IN2 | Direction A2 | D5 | Motor A forward/reverse |
| L298N Motor Driver (Motor B — Right) | |||
| L298N IN3 | Direction B1 | D7 | Motor B forward/reverse |
| L298N IN4 | Direction B2 | D8 | Motor B forward/reverse |
| L298N ENB | PWM Speed B | D9 | PWM-capable pin |
| HC-05 Bluetooth Module | |||
| HC-05 RX | Serial Receive | D1 (TX) | Cross-connected: Nano TX → HC05 RX |
| HC-05 TX | Serial Transmit | D0 (RX) | Cross-connected: Nano RX ← HC05 TX |
| Power | |||
| 18650 Pack + | Motor Power | L298N 12V IN | 7.4V direct to motor driver |
| Buck Converter OUT | Logic Power | Arduino Nano VIN / 5V | Regulated 5V for Nano |
| GND | Common Ground | GND (all shared) | Nano + L298N + HC-05 + IR |
Step-by-Step Build Instructions
Prepare the Chassis
Mount two geared DC motors on the robot chassis. Attach wheels and caster ball for balance. Secure the battery holder and power switch in an accessible position on the chassis.
Mount the IR Sensor Array
Fix the 5-channel IR sensor array at the front-bottom of the robot, 5–10 mm above the surface. The sensors should span the track width. Wire all 5 signal outputs to A0–A4, VCC to 5V, and GND to common ground.
Wire the L298N Motor Driver
Connect both DC motors to the L298N output terminals. Connect ENA→D3, IN1→D4, IN2→D5, IN3→D7, IN4→D8, ENB→D9. Connect the 18650 battery pack to L298N's 12V input pin.
Install the Buck Converter
Wire the 18650 pack to the buck converter input. Set output to exactly 5V using the adjustment potentiometer (measure with a multimeter). Connect the 5V output to the Arduino Nano's VIN pin.
Connect the HC-05 Bluetooth Module
Wire HC-05 VCC to 5V, GND to GND. Cross-connect TX→D0 (Nano RX) and RX→D1 (Nano TX). Important: Use a voltage divider (1kΩ + 2kΩ) on the HC-05 RX line — it's a 3.3V device and D1 outputs 5V.
Upload the Code
Open Arduino IDE. Select board: Arduino Nano, processor: ATmega328P (Old Bootloader). Disconnect HC-05 from D0/D1 before uploading (they share the serial port). Upload the code, then reconnect HC-05.
Calibrate IR Sensors
Open Serial Monitor at 9600 baud. Place robot on the track and observe the printed IR values. Adjust the threshold (default 500) in the code to match your specific sensor and track conditions.
Pair & Test Bluetooth Control
Pair phone with "HC-05" (PIN: 1234). Open a Bluetooth serial app, connect, and send F/B/L/R/S characters. Verify the robot responds correctly, then test autonomous line following on a prepared track.
Complete Arduino Code
Upload this to your Arduino Nano. Remember to disconnect the HC-05 from D0/D1 before uploading, then reconnect afterwards:
/* * Arduino Nano Bluetooth Controlled Line Follower Robot * MakeMindz.com | makemindz.com/arduino-nano-bluetooth-line-follower * * Modes: * 1. Autonomous — 5-channel IR array follows black line on white surface * 2. Bluetooth — HC-05 receives F/B/L/R/S commands from smartphone * * Hardware: * IR sensors → A0–A4 (analog) * L298N ENA → D3 (PWM), IN1→D4, IN2→D5, IN3→D7, IN4→D8, ENB→D9 (PWM) * HC-05 → RX=D0, TX=D1 (SoftwareSerial) */ #include <SoftwareSerial.h> // ── IR Sensor Pins (5-channel analog array) ─────── const int irPins[] = {A0, A1, A2, A3, A4}; const int IR_THRESHOLD = 500; // <500 = black line detected // ── L298N Motor Driver Pins ─────────────────────── const int motorEnableA = 3; // ENA — PWM speed Motor A const int motorIn1 = 4; // IN1 — Motor A direction const int motorIn2 = 5; // IN2 — Motor A direction const int motorIn3 = 7; // IN3 — Motor B direction const int motorIn4 = 8; // IN4 — Motor B direction const int motorEnableB = 9; // ENB — PWM speed Motor B // ── HC-05 Bluetooth on hardware serial D0/D1 ───── const int btRx = 0; const int btTx = 1; SoftwareSerial bluetooth(btTx, btRx); // RX, TX // ── Speed Settings ──────────────────────────────── const int SPEED_FULL = 255; const int SPEED_TURN = 200; const int SPEED_STOP = 0; // ───────────────────────────────────────────────── void setup() { // Motor driver output pins pinMode(motorEnableA, OUTPUT); pinMode(motorEnableB, OUTPUT); pinMode(motorIn1, OUTPUT); pinMode(motorIn2, OUTPUT); pinMode(motorIn3, OUTPUT); pinMode(motorIn4, OUTPUT); // IR sensor input pins for (int i = 0; i < 5; i++) { pinMode(irPins[i], INPUT); } // Bluetooth + debug serial bluetooth.begin(9600); Serial.begin(9600); Serial.println("Line Follower Robot Ready!"); } // ───────────────────────────────────────────────── void loop() { // ── Priority 1: Bluetooth command check ────────── if (bluetooth.available()) { char command = bluetooth.read(); Serial.print("BT Command: "); Serial.println(command); executeBluetoothCommand(command); return; // Skip autonomous mode this cycle } // ── Priority 2: Autonomous line following ───────── int ir[5]; for (int i = 0; i < 5; i++) { ir[i] = analogRead(irPins[i]); } // Debug — uncomment to calibrate sensor values: // for(int i=0;i<5;i++){Serial.print(ir[i]);Serial.print(" ");} Serial.println(); bool L2 = ir[0] < IR_THRESHOLD; // Leftmost sensor bool L1 = ir[1] < IR_THRESHOLD; bool C = ir[2] < IR_THRESHOLD; // Centre bool R1 = ir[3] < IR_THRESHOLD; bool R2 = ir[4] < IR_THRESHOLD; // Rightmost sensor if (L2 && L1 && !C && !R1 && !R2) { driveMotors(SPEED_FULL, SPEED_STOP); // Sharp left } else if (L2 && !C) { driveMotors(SPEED_TURN, SPEED_STOP); // Gentle left } else if (!C && R1 && R2) { driveMotors(SPEED_STOP, SPEED_FULL); // Sharp right } else if (!C && R2) { driveMotors(SPEED_STOP, SPEED_TURN); // Gentle right } else if (C || L1 || R1) { driveMotors(SPEED_FULL, SPEED_FULL); // Straight ahead } else { driveMotors(SPEED_STOP, SPEED_STOP); // No line — stop } } // ── Set motor speeds and directions ─────────────── // speedA/speedB: +255=forward, 0=stop, negative=reverse void driveMotors(int speedA, int speedB) { analogWrite(motorEnableA, abs(speedA)); analogWrite(motorEnableB, abs(speedB)); digitalWrite(motorIn1, speedA > 0 ? HIGH : LOW); digitalWrite(motorIn2, speedA > 0 ? LOW : HIGH); digitalWrite(motorIn3, speedB > 0 ? HIGH : LOW); digitalWrite(motorIn4, speedB > 0 ? LOW : HIGH); } // ── Process Bluetooth single-char command ───────── void executeBluetoothCommand(char command) { switch (command) { case 'F': driveMotors(SPEED_FULL, SPEED_FULL); // Forward break; case 'B': driveMotors(-SPEED_FULL, -SPEED_FULL); // Backward break; case 'L': driveMotors(SPEED_STOP, SPEED_FULL); // Pivot left break; case 'R': driveMotors(SPEED_FULL, SPEED_STOP); // Pivot right break; case 'S': driveMotors(SPEED_STOP, SPEED_STOP); // Emergency stop break; default: break; // Unknown command — ignore } }
Comments
Post a Comment