Autonomous Line-Following Robot

1. Engineering Overview & Control Strategy

The Objective: To engineer a high-speed, autonomous differential-drive robot capable of navigating complex trajectories defined by high-contrast visual markers. The project focuses on implementing a real-time closed-loop control system that dynamically adjusts motor velocity based on continuous sensor feedback. This system serves as a foundational prototype for automated guided vehicles (AGVs) used in industrial logistics.

System Architecture: The robot is built upon the Arduino Nano (ATmega328P) architecture, chosen for its small form factor and efficient interrupt handling. It employs a sensor fusion strategy using dual Infrared (IR) Reflectance sensors to constantly poll the surface albedo. This data is processed by a custom control algorithm that drives a Dual H-Bridge (L293D), allowing for precise differential steering and rapid course correction.

Power Electronics Challenge: A critical engineering hurdle was power delivery. Standard 6V setups suffer from voltage sag under load, causing processor brownouts. I engineered a robust 12V DC Rail (8x AA Series Configuration). This high-voltage rail drives the DC motors directly to overcome static friction (stiction) during sharp turns, while the Arduino's onboard linear regulator steps it down to a stable 5V logic level, ensuring processor stability even during peak current draw.

System Validation: Dynamic Path Tracking & Motor Response

Core Hardware Specifications

The hardware was selected to balance weight, torque, and computational efficiency.

  • Microcontroller: Arduino Nano V3 (16MHz, ATmega328P).
  • Motor Driver: L293D Dual H-Bridge (600mA/channel continuous).
  • Sensors: Active IR Reflectance Modules (LM393 Comparator with adjustable hysteresis).
  • Chassis: 2WD Acrylic Platform with caster wheel stabilization.
  • Actuators: 2x Geared DC Motors (High Torque, Low RPM).
Power & Signal Integrity

To ensure reliability during autonomous operation, the power distribution network was split into two isolated domains.

  • HV Domain (12V): 8x AA Batteries in series supply raw power to the L293D driver, maximizing motor torque and response time.
  • LV Domain (5V): Regulated logic voltage for the MCU and IR sensors, protected from back-EMF spikes by flyback diodes internal to the L293D.
  • Frequency Optimization: Modified the TCCR0B register to increase PWM frequency, ensuring smoother motor response curves.

2. Control Algorithm & State Machine

The robot operates on a high-frequency polling loop that implements a Bang-Bang Control System. By treating the line position as a binary error state, the system applies immediate corrective torque to the opposing motor. This approach minimizes computation time, allowing for faster reaction speeds compared to float-heavy PID loops on 8-bit controllers.

State Vector Left Sensor (IR) Right Sensor (IR) Control Action (Differential Drive) System Behavior
On Track Low (0) Low (0) Left: FWD | Right: FWD Maintains linear velocity (Error = 0).
Right Deviation Low (0) High (1) Left: FWD | Right: REV Rapid Pivot Right to correct heading.
Left Deviation High (1) Low (0) Left: REV | Right: FWD Rapid Pivot Left to correct heading.
Stop Condition High (1) High (1) Left: STOP | Right: STOP Destination Reached / Intersection Hold.

3. Embedded Firmware Implementation

The following C++ firmware demonstrates advanced embedded concepts, including direct register manipulation for PWM frequency optimization (`TCCR0B`), bitwise operations for sensor fusion, and modular driver design. The code is structured for modularity and scalability.

File: LineFollower_Main.ino Role: Low-Level Hardware Control
// Define pins for the IR sensors
#define IR_SENSOR_RIGHT 11 // Right IR sensor connected to pin 11
#define IR_SENSOR_LEFT 12  // Left IR sensor connected to pin 12

// Define the motor speed
#define MOTOR_SPEED 180 // Motor speed (PWM value between 0-255)

// Define pins for the right motor
const int enableRightMotor = 6; // PWM pin to control the speed of the right motor
const int rightMotorPin1 = 7;   // Pin to control the direction of the right motor (forward)
const int rightMotorPin2 = 8;   // Pin to control the direction of the right motor (backward)

// Define pins for the left motor
const int enableLeftMotor = 5;  // PWM pin to control the speed of the left motor
const int leftMotorPin1 = 9;    // Pin to control the direction of the left motor (forward)
const int leftMotorPin2 = 10;   // Pin to control the direction of the left motor (backward)

// Function prototypes for modular code
void setupMotors();         // Sets up the motor control pins
void setPWMFrequency();     // Adjusts the PWM frequency for smoother motor control
void controlMotors(int leftSpeed, int rightSpeed); // Controls motor speed and direction
int readLineSensors();      // Reads the IR sensors and returns a combined binary value

void setup()
{
  // Initialize motor pins
  setupMotors();

  // Adjust the PWM frequency for smoother motor control
  setPWMFrequency();

  // Initialize sensor pins as inputs
  pinMode(IR_SENSOR_RIGHT, INPUT);
  pinMode(IR_SENSOR_LEFT, INPUT);

  // Stop motors initially to ensure the robot does not move
  controlMotors(0, 0);
}

void loop()
{
  // Read the sensor values and determine the state of the robot
  int sensorState = readLineSensors();

  // Perform actions based on the sensor state using a switch-case statement
  switch (sensorState)
  {
    case 0b00: // No line detected by either sensor
      controlMotors(MOTOR_SPEED, MOTOR_SPEED); // Move straight
      break;

    case 0b01: // Line detected by the left sensor only
      controlMotors(MOTOR_SPEED, -MOTOR_SPEED); // Turn left
      break;

    case 0b10: // Line detected by the right sensor only
      controlMotors(-MOTOR_SPEED, MOTOR_SPEED); // Turn right
      break;

    case 0b11: // Line detected by both sensors
      controlMotors(0, 0); // Stop the robot
      break;

    default: // Fallback case to stop the robot for safety
      controlMotors(0, 0);
  }
}

// Function to initialize motor pins
void setupMotors()
{
  // Set motor control pins as outputs
  pinMode(enableRightMotor, OUTPUT);
  pinMode(rightMotorPin1, OUTPUT);
  pinMode(rightMotorPin2, OUTPUT);

  pinMode(enableLeftMotor, OUTPUT);
  pinMode(leftMotorPin1, OUTPUT);
  pinMode(leftMotorPin2, OUTPUT);
}

// Function to adjust PWM frequency for smoother motor control
void setPWMFrequency()
{
  // Set PWM frequency for pins 5 and 6 (Timer0)
  // Timer0 default frequency is ~490 Hz; this changes it to ~7812.5 Hz
  TCCR0B = TCCR0B & 0b11111000 | 0b00000010;
}

// Function to control motor speed and direction
void controlMotors(int rightSpeed, int leftSpeed)
{
  // Control the right motor direction
  digitalWrite(rightMotorPin1, rightSpeed > 0); // Forward if speed > 0
  digitalWrite(rightMotorPin2, rightSpeed < 0); // Backward if speed < 0

  // Control the left motor direction
  digitalWrite(leftMotorPin1, leftSpeed > 0); // Forward if speed > 0
  digitalWrite(leftMotorPin2, leftSpeed < 0); // Backward if speed < 0

  // Control the motor speeds using PWM
  analogWrite(enableRightMotor, abs(rightSpeed)); // Set speed for the right motor
  analogWrite(enableLeftMotor, abs(leftSpeed));   // Set speed for the left motor
}

// Function to read IR sensors and return a combined binary value
int readLineSensors()
{
  // Read the state of the right and left IR sensors
  int rightSensor = digitalRead(IR_SENSOR_RIGHT); // 0 = no line, 1 = line detected
  int leftSensor = digitalRead(IR_SENSOR_LEFT);   // 0 = no line, 1 = line detected

  // Combine the two sensor readings into a single binary number
  // Example: if rightSensor = 1 and leftSensor = 0, the result will be 0b10 (decimal 2)
  return (rightSensor << 1) | leftSensor;
}

4. Engineering Competencies Applied

Embedded Software
Embedded C++ Bare-Metal Programming Register Manipulation Bitwise Operations PWM Signal Generation State Machine Logic Algorithm Optimization Sensor Fusion Interrupt Service Routines
Hardware Systems
Arduino Nano H-Bridge Topology Power Budgeting Voltage Regulation Rapid Prototyping Sensor Calibration Electromechanical Assembly Circuit Analysis Schematic Interpretation