Light-seeking robot with Arduino and two LDRs: design worksheet and code

A ₹1,370 design worksheet for a robot that steers toward a torch using two LDR voltage dividers, with wiring, a sketch and a test plan.

About the author · Sources, testing and AI policy

  • Parts₹1,370
  • Bench time2–3 h
  • LevelBeginner
  • ReviewedNov 2026

A ₹1,370 light-seeking robot that steers toward a torch. Two light-dependent resistors (LDRs) face forward and slightly outward. The Arduino compares their readings and turns toward the brighter side, then drives forward when both sides match. The page includes the voltage-divider wiring, a complete sketch with a dead band and a minimum-light check, and a test plan for the ambient-light problems that confuse this kind of robot.

Scope: beginner. This is a design worksheet with illustrative costs. It has not been bench-tested by this site, and the thresholds in the sketch are starting values to tune in your own room. It is a good first lesson in differential sensing: the robot never needs to know how bright the light is, only which side is brighter.

How it behaves

Each LDR forms a voltage divider with a fixed resistor, so the Arduino’s analog pin sees a voltage that changes with light. The sketch subtracts the right reading from the left. If the difference is bigger than a dead band, the robot turns toward the brighter side. If the readings are close, it drives forward. If both are dim, it stops, because there is nothing to chase and a robot that spins forever in a dark room is not useful.

Bill of materials

PartQtyUnitTotal
Arduino Uno R31₹520₹520
L298N motor driver1₹180₹180
LDR (light-dependent resistor)2₹15₹30
10 kΩ resistor2₹10₹20
TT gear motor with wheel2₹110₹220
Acrylic chassis1₹80₹80
2×18650 holder with cells1₹200₹200
Caster wheel and screws1₹40₹40
Jumper wire set1₹50₹50
Switch1₹30₹30
Parts total₹1,370

Scroll the table sideways to see every column.

Prices checked Nov 2026. Shipping and tools are not included.

Prices are illustrative figures for Indian sellers in November 2026, before shipping, and have not been checked against current listings. LDRs are sold in packs, so one pack covers this build and several more.

Wiring the sensors

Make one divider per eye: 5 V, then the LDR, then the junction that goes to the analog pin, then a 10 kΩ resistor to ground. In a bright spot the LDR resistance falls, so the junction voltage rises. The exact LDR resistance range varies between parts, so treat 10 kΩ as a sensible starting value and test it.

PartArduino UnoNote
Left divider junctionA0LDR to 5 V, 10 kΩ to GND
Right divider junctionA1LDR to 5 V, 10 kΩ to GND
L298N IN1 / IN2D5 / D6Left motor direction
L298N IN3 / IN4D12 / D13Right motor direction
L298N ENA / ENBD3 / D11PWM speed. Remove the onboard jumpers.
L298N +5V5V pinPowers the Uno from the driver’s regulator
All groundsCommon GNDBattery, L298N, Uno and both dividers
Angle the two LDRs about 30 to 45 degrees apart, with a small card between them so each sees mostly its own side.

The sketch

// Light-seeking robot: Uno + L298N + 2 LDR dividers
// Design worksheet: tune DEAD_BAND and MIN_LIGHT in your own room.

const int LEFT_EYE = A0;
const int RIGHT_EYE = A1;

const int IN1 = 5;
const int IN2 = 6;
const int IN3 = 12;
const int IN4 = 13;
const int ENA = 3;
const int ENB = 11;

const int SPEED = 130;
const int TURN_SPEED = 130;
const int DEAD_BAND = 40;     // difference below this counts as "straight ahead"
const int MIN_LIGHT = 250;    // both eyes below this: nothing to chase

void setup() {
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode(ENA, OUTPUT);
  pinMode(ENB, OUTPUT);
  Serial.begin(9600);
  stopMotors();
}

void loop() {
  int left = smooth(LEFT_EYE);
  int right = smooth(RIGHT_EYE);
  int difference = left - right;

  Serial.print(left);
  Serial.print(" ");
  Serial.println(right);

  if (left < MIN_LIGHT && right < MIN_LIGHT) {
    stopMotors();
  } else if (difference > DEAD_BAND) {
    turnLeft();
  } else if (difference < -DEAD_BAND) {
    turnRight();
  } else {
    forward();
  }
  delay(50);
}

int smooth(int pin) {
  long sum = 0;
  for (int i = 0; i < 8; i++) {
    sum += analogRead(pin);
  }
  return sum / 8;
}

void forward() {
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  analogWrite(ENA, SPEED);
  analogWrite(ENB, SPEED);
}

void turnLeft() {
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  analogWrite(ENA, TURN_SPEED);
  analogWrite(ENB, TURN_SPEED);
}

void turnRight() {
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  analogWrite(ENA, TURN_SPEED);
  analogWrite(ENB, TURN_SPEED);
}

void stopMotors() {
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, LOW);
  analogWrite(ENA, 0);
  analogWrite(ENB, 0);
}

The two eyes are never perfectly matched. Before the first drive, shine the same light on both from straight ahead and compare the printed values; if one is always higher, add that offset to the difference in code. Without this the robot has a built-in lean.

Test plan

  1. Readings: print both values in the room with no torch, then with a torch on each side. Note the numbers and set MIN_LIGHT and DEAD_BAND from what you see.
  2. Match the eyes: light both from straight ahead at the same distance and compensate for any constant difference.
  3. Motor direction: check that the robot turns toward the light, not away. If it turns away, swap the two turn functions or the sensor pins.
  4. Chase: move a torch slowly in front of the robot at floor height. It should follow within a short delay.
  5. Overshoot: if the robot swings past the light and back, lower TURN_SPEED or widen the dead band.
  6. Ambient light: repeat near a window and under a ceiling lamp. Record when it is distracted.
  7. Reflections: try a glossy floor. A bright reflection can look like a second light.

What usually goes wrong

SymptomLikely causeFix
Spins in circlesOne eye reads higher than the other at restAdd an offset, or swap in a better-matched LDR
Turns away from the lightEyes or motor leads reversedSwap the pins or the turn functions
Never goes forwardDead band too small for the noiseWiden DEAD_BAND, average more readings
Stops in a lit roomMIN_LIGHT set too highLower it using the printed values
Readings barely changeResistor value does not suit the LDRTry other resistor values and watch the range
Chases room lightsAmbient light stronger than the torchTest in a dim room or use a brighter torch

Upgrades

  • Proportional steering: scale the motor speeds by the difference instead of turning on the spot.
  • Light-avoiding mode: swap the turn directions to make a robot that hides in the dark.
  • More eyes: add a third sensor at the front to improve the forward decision.
  • Obstacle sensor: add an ultrasonic sensor so it does not drive into the wall while chasing the torch.

Cost and parts notes

The ₹1,370 total is an illustration for the parts above and does not include shipping. The L298N guide explains the voltage drop that makes a 7.4 V pack behave like a 5.8 V one at the motors. Use the cost calculator to compare sellers.

Common questions

Why compare the two sensors instead of using a brightness threshold?

A comparison works in a dim or bright room alike, because it only asks which side is brighter. A single threshold has to be retuned whenever the room changes.

Can I use a photodiode or phototransistor instead?

Yes, with a different resistor and a different range of readings. LDRs are slower to respond, which helps smooth the motion in this build.

Will it follow the sun?

Probably not usefully. Sunlight is much brighter than a torch and comes from everywhere in a room, so the readings saturate. Test it before expecting it to work outdoors.

Can it carry on if the torch goes out?

In this sketch it stops. You could make it spin slowly to search, but add a time limit so it does not spin forever.

Last reviewed: November 2026. This is a design worksheet with illustrative costs. It has not been bench-tested by this site; thresholds and speeds are starting values, and measurements from your build are welcome.

More builds

Next builds to try

Free: the final-year project pack

A shortlist with BOMs, a report outline that matches the usual chapter scheme, a costing sheet and 40 viva questions. Built for the February–April submission season.

The Build Note

One short email when something is worth your bench time.

A new build sheet, a part price that moved, or a mistake worth avoiding. No daily drip, no recycled news.

One short email when a build or a price is worth your time. Unsubscribe in one click.