# IR sensor with Arduino: wiring, calibration and code

> Learn IR sensor with Arduino wiring: set up a TCRT5000 module, set the threshold from real readings and write line-follower code for glossy floors.

Canonical: https://roboticsengineering.in/ir-sensor-with-arduino/ | Published: 2026-10-27 | Updated: 2026-10-28 | Author: Jignesh Panchal

**An IR reflectance sensor is the cheapest way to give a robot sight of the floor — and the most common reason a line follower behaves perfectly on a table and fails on the competition mat.** An IR sensor with Arduino is the cheapest way to give a robot sight of the floor.

The module is simple: an infrared LED shines down, a phototransistor measures how much bounces back, and a comparator turns that into a clean high or low. Everything difficult about it is calibration and geometry. This guide covers the TCRT5000 module that sells for ₹30–60 in India, how to wire it to an Arduino, how to set the threshold with evidence instead of guesswork, and the failure modes that make readings flicker.

## How the module sees a line

White surfaces reflect infrared; black surfaces absorb it. The module’s phototransistor produces a voltage proportional to the reflected light, and an LM393 comparator compares that voltage with a level you set using the small potentiometer on the board. The digital output goes high or low at the threshold. Many modules also expose an analog output that gives you the raw sensor voltage, which is far more useful for debugging and for proportional control.

Typical sensing distance is a few millimetres up to roughly 3 cm depending on surface and module. That is why line followers mount the sensors 5–15 mm above the mat: close enough for a strong reflection, high enough not to scrape the surface.

| Pin | Connect to | Purpose |
| --- | --- | --- |
| VCC | 3.3 V or 5 V | Most modules work on both; 5 V gives a stronger emitter |
| GND | Common ground | Must share ground with the Arduino |
| DO | Any digital pin | Thresholded output, high or low |
| AO | Any analog pin | Raw reflection level for calibration and PID |

*Not every module breaks out AO. If yours has only three pins, calibrate by watching DO and adjusting the potentiometer.*

## Wiring an IR sensor with Arduino and a first test

Connect VCC and GND, then DO to pin 7 and AO to A0. Upload a sketch that prints both readings once per 100 ms, open the Serial Monitor and slide a piece of white paper and a piece of black tape under the sensor. The analog number should move clearly between the two surfaces. If it barely moves, the sensor is too high, the surface is glossy, or the room light is washing out the reading.

```
const int DO_PIN = 7;
const int AO_PIN = A0;

void setup() {
  Serial.begin(9600);
  pinMode(DO_PIN, INPUT);
}

void loop() {
  int raw = analogRead(AO_PIN);      // 0-1023
  int digital = digitalRead(DO_PIN); // 0 or 1
  Serial.print("analog=");
  Serial.print(raw);
  Serial.print(" digital=");
  Serial.println(digital);
  delay(100);
}
```

On most modules the digital output goes low over a reflective (white) surface and high over black. Do not assume it: check your own board. Clone modules vary in comparator wiring, and a line follower that treats black as white will spin in place forever.

## Setting the threshold with numbers

Record the analog value on white and on black, at the height the sensor will actually run. Suppose white reads around 850 and black around 120. A threshold of about 480 sits in the middle with margin on both sides. Turn the potentiometer until the on-board LED switches state when you move between the two surfaces, then confirm the digital output agrees with your analog midpoint.

If the two readings are close — say 600 and 520 — the sensor is not discriminating. Lower it slightly, clean the emitter and receiver, or replace a glossy surface with matte tape. A threshold cannot fix a weak signal; it only decides where the ambiguity is.

## Two sensors, one line follower

With a left and right sensor straddling the line, the control logic is short: both see white, go straight; left sees black, turn left; right sees black, turn right; both see black, stop or back up. That is enough for a first build and for most college demonstrations.

```
const int L = 7, R = 8;
const int IN1 = 4, IN2 = 5, ENA = 6;
const int IN3 = 9, IN4 = 10, ENB = 11;

void setMotors(int leftSpeed, int rightSpeed) {
  digitalWrite(IN1, leftSpeed >= 0 ? HIGH : LOW);
  digitalWrite(IN2, leftSpeed >= 0 ? LOW : HIGH);
  digitalWrite(IN3, rightSpeed >= 0 ? HIGH : LOW);
  digitalWrite(IN4, rightSpeed >= 0 ? LOW : HIGH);
  analogWrite(ENA, abs(leftSpeed));
  analogWrite(ENB, abs(rightSpeed));
}

void loop() {
  bool leftBlack  = digitalRead(L) == HIGH;
  bool rightBlack = digitalRead(R) == HIGH;

  if (leftBlack && !rightBlack) setMotors(0, 160);      // steer right
  else if (!leftBlack && rightBlack) setMotors(160, 0);  // steer left
  else if (leftBlack && rightBlack) setMotors(0, 0);     // lost the line
  else setMotors(150, 150);                               // straight
}
```

Two sensors give an on-off correction: the robot lurches left and right instead of tracking smoothly. That is the natural next problem, and the answer is either more sensors or proportional control using the analog values. The [PID guide](https://roboticsengineering.in/pid-control-line-follower-explained/) explains the tuning order, and the [line follower build sheet](https://roboticsengineering.in/projects/line-follower-robot-arduino/) prices a complete robot at about ₹1,400.

## Why readings flicker on a real mat

- **Ambient infrared.** Direct sunlight and incandescent lamps contain infrared. Test in the room and lighting where the robot will run, and shield the sensor from above if needed.
- **Glossy surfaces.** A shiny black tile reflects like a mirror at some angles. Matte vinyl or paper tape is far more predictable.
- **Height drift.** A chassis that flexes or a battery that sags changes the distance to the floor. Mount sensors on a rigid bracket and keep the height fixed.
- **Crosstalk.** Two emitters placed too close can illuminate each other’s receivers. Space them at least 20–25 mm apart, or pulse them alternately.
- **Supply noise.** Motors on the same 5 V rail inject noise into the comparator. Power the sensors from the regulated logic rail, not the motor battery, and keep grounds star-shaped.

## From two sensors to an array

Five or eight sensors in a row give a position estimate instead of a binary left/right decision, which is what a smooth PID follower needs. Read them as analog values if the module exposes AO, normalise each sensor against its own white and black readings, and compute a weighted average position. That single change is usually worth more than increasing motor power.

For a maze robot, the same sensors feed a different decision layer: detect junctions and dead ends, then run flood fill on a stored map. The [maze solver build](https://roboticsengineering.in/projects/maze-solver-robot-arduino/) covers that logic, and the [Uno pinout guide](https://roboticsengineering.in/arduino-uno-pinout-for-robotics/) helps you allocate analog and digital pins before you run out.

## Sources and further reading

- [Vishay TCRT5000 datasheet](https://www.vishay.com/docs/83760/tcrt5000.pdf) for emitter wavelength, phototransistor characteristics and test conditions.
- [Arduino language reference: analogRead()](https://docs.arduino.cc/language-reference/en/functions/analog-io/analogRead/) for the 10-bit conversion used above.
- [Arduino language reference: analogWrite()](https://docs.arduino.cc/language-reference/en/functions/analog-io/analogWrite/) for the PWM pins used by the motor driver.

Last reviewed: October 2026. Module behaviour is described from the TCRT5000 and LM393 datasheets; clone boards vary in resistor values and output polarity. Readings quoted are illustrative, not measurements from a specific unit. Not bench-tested by this site.
