Sensors and motor control

Arduino Line Follower Robot: Build & Calibrate

A line-following robot steers from measurements of the surface below it. This reference build uses an Arduino UNO Rev3, Arduino Motor Shield Rev3 and Pololu QTR-3A analog reflectance array. It follows a dark line on a lighter floor with simple steering decisions, stopping on lost or ambiguous readings. These are construction instructions and example code, not measured results from a physical Robotic Sir test build.

By Robotic Sir · Learning guide

What you need

  • Arduino UNO Rev3 and Arduino Motor Shield Rev3 with its brake/current-sense connections intact
  • Pololu QTR-3A array with three analog outputs, mounted parallel to the track
  • Two geared DC motors compatible with the shield and selected supply, wheels, chassis and castor
  • A switched motor supply selected from the motor and shield ratings; follow the shield's VIN Connect instructions
  • USB data cable, Arduino IDE, wiring, fasteners and an accessible power switch
  • A light practice surface with a dark line and clear floor-level space

1. Check the power plan and connect the reference hardware

Disconnect power before assembly. Fit the shield to the UNO, connect the left motor to channel A and the right motor to channel B, and secure the array ahead of the wheels. Use the manufacturer's mounting guidance; begin with the array parallel to the surface and adjust its height while reading sensor values.

The motor supply must meet the motors' requirements and the shield's electrical and thermal limits. Follow the shield documentation for the VIN Connect arrangement when motor and controller power are separate. Have the power plan checked before connecting USB and a motor supply. Motor outputs must not be connected to controller GPIO pins.

1. Check the power plan and connect the reference hardware: reference table
ConnectionUNO / shield reference
QTR-3A VIN and GND5V and GND; read the sensor's own pin labels before connecting
Left, centre and right sensor outputsA2, A3 and A4 respectively; identify left/right as seen by the robot
Motor channel A: direction / PWM / brakeD12 / D3 / D9; channel A drives the left wheel
Motor channel B: direction / PWM / brakeD13 / D11 / D8; channel B drives the right wheel
Shield current sensingA0 and A1 are reserved by the shield; this sketch uses A2–A4 for sensors

2. Upload the reference sketch with the wheels raised

Download the sketch into a folder named uno-line-follower and open it in Arduino IDE. Select Arduino UNO and the correct port, then verify and upload. No additional library is used. Open Serial Monitor at 115200 baud; startup applies the shield brakes and waits for calibration.

The sketch defines forward direction separately for the two motors because their mounting orientations can differ. Check FORWARD_LEVEL with the wheels raised and a clear line pattern under the sensors before floor testing. BASE_PWM and TURN_PWM are starting settings, not a measured speed or a value guaranteed to move every motor.

Download UNO line-follower sketch (.ino)
Control workflow (pseudocode)
sample a light surface and a dark surface
refuse start if either sample is missing or contrast is too low
repeat while started:
  read left, centre and right sensors
  if no line or ambiguous pattern: stop and wait for restart
  if line is left: reduce the left motor command
  if line is right: reduce the right motor command
  otherwise: drive both sides forward

3. Calibrate on your actual surface

With the wheels raised, place every sensor over the light surface and send W in Serial Monitor. Then place every sensor over the dark surface and send B. Read the three values printed after each sample. The code compares each measurement with its own light and dark references, rather than assuming one universal threshold.

The initial MIN_CONTRAST setting is 80 UNO ADC counts. Inspect the readings before changing it: weak contrast can come from mounting height, unsuitable materials, ambient light or incorrect wiring. If either sample is missing or any sensor lacks the configured contrast, G will not start the motors.

  • Check each sensor sees distinctly different readings over both surfaces.
  • Place the centre sensor over the line with the outer sensors over the lighter floor.
  • Send G only after checking motor direction with the wheels raised.
  • Send S to stop; keep the physical switch accessible throughout the demonstration.

4. Test a short line before attempting a course

Start on a clear floor-level track, not near a table edge or stairs. After a straight section works, add a gentle curve and observe the readings and wheel response. This simple controller does not implement PID or junction navigation. When no sensor sees the line, or the two outer sensors both see dark, it stops and requires repositioning and G to restart.

Change one setting or mechanical adjustment at a time and repeat the same track section. Record the surface, sensor height, power arrangement and code settings. Tune for repeatable tracking before trying to increase the motor command.

5. Troubleshoot sensing, steering and power separately

5. Troubleshoot sensing, steering and power separately: reference table
ProblemCheck first
Line follower does not detect the black lineInspect W/B readings for every sensor, array height, surface contrast and analog-output wiring.
Start is refusedCapture both surfaces and check each contrast exceeds MIN_CONTRAST; do not lower it just to hide wiring problems.
Robot turns away from the lineCheck left/right sensor order, motor channel placement and FORWARD_LEVEL with wheels raised.
Robot stops at a junction or loses a curveThis sketch deliberately stops on ambiguous input. Reposition, then reduce speed or adjust the track/sensor geometry.
Arduino resets when motors startInspect supply capacity, grounding, loose connectors and the shield's power arrangement.
Motors do not moveCheck the motor supply, shield brake connections, channel wiring and whether the start conditions passed.

References and further learning

Project questions

Frequently asked questions

Practical answers to help you choose the next step.

This sketch reads three analog outputs from a QTR-3A on A2–A4. A digital threshold module or an RC-timed sensor array needs different reading code and wiring. Check the sensor output type before using the sketch.
The reference code stops on missing or ambiguous line readings and waits for a restart. Reposition it on a clear line and send G after checking the cause. It does not search blindly or navigate intersections.
This pin map is for an Arduino UNO Rev3 and Motor Shield Rev3. An ESP32 has different pin assignments and 3.3 V GPIO requirements, so the controller, shield interface and sensor outputs need a separate compatibility check.

Build your understanding

Keep learning with another project

Choosing a project

Choose a Robotics Project: Parts & Skills

Choose a school or beginner robotics project by learning goal, parts and experience. Compare LED, line-follower, obstacle-avoider and soccer-robot builds.

Read the guide

Distance sensing and decisions

Arduino Obstacle-Avoiding Robot: Build Guide

Build a reference UNO obstacle-avoiding robot with HC-SR04 sensing. Includes wiring, downloadable code, timeout handling and troubleshooting.

Read the guide

Competition preparation

Robot Race Preparation: Testing Checklist

Prepare for a robot race with a practical checklist for rules, steering, stopping, practice runs, troubleshooting and packing your equipment.

Read the guide
Browse all learning guides