# 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.

Canonical: https://roboticsengineering.in/projects/light-seeking-robot-arduino/ | Published: 2026-11-03 | Updated: 2026-11-03

**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

| Part | Qty | Unit | Total |
| --- | --- | --- | --- |
| Arduino Uno R3 | 1 | ₹520 | ₹520 |
| L298N motor driver | 1 | ₹180 | ₹180 |
| LDR (light-dependent resistor) | 2 | ₹15 | ₹30 |
| 10 kΩ resistor | 2 | ₹10 | ₹20 |
| TT gear motor with wheel | 2 | ₹110 | ₹220 |
| Acrylic chassis | 1 | ₹80 | ₹80 |
| 2×18650 holder with cells | 1 | ₹200 | ₹200 |
| Caster wheel and screws | 1 | ₹40 | ₹40 |
| Jumper wire set | 1 | ₹50 | ₹50 |
| Switch | 1 | ₹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.

| Part | Arduino Uno | Note |
| --- | --- | --- |
| Left divider junction | A0 | LDR to 5 V, 10 kΩ to GND |
| Right divider junction | A1 | LDR to 5 V, 10 kΩ to GND |
| L298N IN1 / IN2 | D5 / D6 | Left motor direction |
| L298N IN3 / IN4 | D12 / D13 | Right motor direction |
| L298N ENA / ENB | D3 / D11 | PWM speed. Remove the onboard jumpers. |
| L298N +5V | 5V pin | Powers the Uno from the driver’s regulator |
| All grounds | Common GND | Battery, 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

| Symptom | Likely cause | Fix |
| --- | --- | --- |
| Spins in circles | One eye reads higher than the other at rest | Add an offset, or swap in a better-matched LDR |
| Turns away from the light | Eyes or motor leads reversed | Swap the pins or the turn functions |
| Never goes forward | Dead band too small for the noise | Widen `DEAD_BAND`, average more readings |
| Stops in a lit room | `MIN_LIGHT` set too high | Lower it using the printed values |
| Readings barely change | Resistor value does not suit the LDR | Try other resistor values and watch the range |
| Chases room lights | Ambient light stronger than the torch | Test 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](https://roboticsengineering.in/components/l298n-motor-driver/) 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](https://roboticsengineering.in/robotics-project-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.
