# Table-edge cliff detection with TCRT5000 sensors on a 2WD robot: design worksheet and code

> A ₹1,580 design worksheet for a robot that stops and backs away at a table edge, with the stopping-distance maths that decides how far ahead of the wheels the sensors must sit.

Canonical: https://roboticsengineering.in/projects/cliff-detection-tcrt5000-edge-robot-arduino/ | Published: 2026-11-04 | Updated: 2026-11-04

**A ₹1,580 robot that wanders a table without driving off the edge. Two downward-facing reflective sensors at the front see the table surface; when one loses it, the robot stops, backs up and turns away. The page works out the stopping distance, which decides where the sensors have to be mounted.**

**Scope:** intermediate. This is a design worksheet with illustrative costs. It has not been bench-tested by this site. The stopping table was computed by script from assumed values: a 50 ms control reaction and a 100 ms stop from drive speed with constant deceleration. The real figures depend on your motors, battery and surface, so measure them. Sensors work only on surfaces that reflect enough infrared: a black or glossy table edge can read as a cliff or hide one. Keep the robot over a soft landing for early tests.

## How it works

The robot keeps moving during the loop delay and then while it slows down. Distance = v × t_react + v × t_stop / 2, assuming constant deceleration over the stopping time. At 0.3 m/s with a 50 ms reaction and a 100 ms stop, that is 15 mm plus 15 mm, so 30 mm; at 0.5 m/s it is 50 mm.

The sensors must therefore look at the floor at least that far ahead of the point where the front wheels would go over the edge, plus a margin of about 20 mm, so at 0.3 m/s mount them about 50 mm ahead of the wheel contact line. A TCRT5000 module gives a digital output from a comparator with a trimmer, high when little light returns, so no table under the sensor reads as “cliff”.

## Bill of materials

| Part | Qty | Unit | Total |
| --- | --- | --- | --- |
| Arduino Uno R3 (or compatible) | 1 | ₹550 | ₹550 |
| 2WD chassis kit with two gear motors and wheels | 1 | ₹450 | ₹450 |
| L298N motor driver board | 1 | ₹180 | ₹180 |
| TCRT5000 reflective sensor module | 2 | ₹60 | ₹120 |
| Battery holder with two 18650 cells | 1 | ₹210 | ₹210 |
| Switch | 1 | ₹20 | ₹20 |
| Jumper wires | 1 | ₹50 | ₹50 |
| Parts total | ₹1,580 |  |  |

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.

## The numbers

| Speed | Reaction distance (50 ms) | Stopping distance (100 ms stop) | Total |
| --- | --- | --- | --- |
| 0.2 m/s | 10 mm | 10 mm | 20 mm |
| 0.3 m/s | 15 mm | 15 mm | 30 mm |
| 0.5 m/s | 25 mm | 25 mm | 50 mm |

*Total = v × 0.05 s + v × 0.10 s / 2. Assumed times; measure your own robot.*

Keep the sensor height at the module’s recommended working distance, often listed as a few millimetres, because the reading is very sensitive to height. A soft front skid or bumper on the chassis stops the nose digging in when the robot brakes.

## Power and wiring

| Part | Connects to | Note |
| --- | --- | --- |
| Left TCRT5000 DO | D2 | High means no surface |
| Right TCRT5000 DO | D3 | High means no surface |
| Sensor VCC and GND | 5V and GND |  |
| L298N ENA / IN1 / IN2 | D5 / D7 / D8 | Left motor |
| L298N ENB / IN3 / IN4 | D6 / D9 / D4 | Right motor |

*Shield the sensors from direct sunlight, which carries a lot of infrared and can fool them.*

## The sketch

```
// Table-edge cliff detection: Uno + L298N + two TCRT5000 modules
// Design worksheet: tune each sensor's trimmer on your table first.

const int L_EN = 5, L_IN1 = 7, L_IN2 = 8;
const int R_EN = 6, R_IN3 = 9, R_IN4 = 4;
void drive(int left, int right) {   // -255..255 per side
  digitalWrite(L_IN1, left >= 0);  digitalWrite(L_IN2, left < 0);
  digitalWrite(R_IN3, right >= 0); digitalWrite(R_IN4, right < 0);
  analogWrite(L_EN, constrain(abs(left), 0, 255));
  analogWrite(R_EN, constrain(abs(right), 0, 255));
}
void motorsInit() {
  pinMode(L_EN, OUTPUT); pinMode(L_IN1, OUTPUT); pinMode(L_IN2, OUTPUT);
  pinMode(R_EN, OUTPUT); pinMode(R_IN3, OUTPUT); pinMode(R_IN4, OUTPUT);
}

const int CLIFF_L = 2, CLIFF_R = 3;
const bool CLIFF_LEVEL = HIGH;              // output HIGH = no surface seen
const int CRUISE = 130;                     // keep speed low

void setup() {
  motorsInit();
  pinMode(CLIFF_L, INPUT); pinMode(CLIFF_R, INPUT);
  delay(2000);
}

void loop() {
  bool l = digitalRead(CLIFF_L) == CLIFF_LEVEL;
  bool r = digitalRead(CLIFF_R) == CLIFF_LEVEL;

  if (l || r) {
    drive(0, 0); delay(150);
    drive(-CRUISE, -CRUISE); delay(450);    // back off the edge
    if (l && !r)      drive(CRUISE, -CRUISE);   // left edge: spin right
    else if (r && !l) drive(-CRUISE, CRUISE);   // right edge: spin left
    else              drive(CRUISE, -CRUISE);   // both: spin right
    delay(500);
    drive(0, 0); delay(100);
  } else {
    drive(CRUISE, CRUISE);
  }
}
```

Backing up blindly assumes the table behind the robot is there; a rear sensor is a sensible addition. The sensor output polarity depends on the module, so confirm it with the indicator LED and flip CLIFF_LEVEL if needed. Test over a soft surface, and increase the sensor distance ahead of the wheels before raising speed. The sketch has been proofread but not compiled on this site.

## Test plan

1. **Sensor check:** hold the module over the table and then past its edge and watch its LED.
2. **Trimmer:** set the trimmer so the table reads as surface and empty air reads as cliff.
3. **Stop distance:** run toward an edge at cruise speed and measure how far the wheels get.
4. **Approach angles:** test head-on and at an angle.
5. **Surface test:** try dark and glossy tables.
6. **Speed test:** raise speed in steps and stop at the first failure.

## What usually goes wrong

| Symptom | Likely cause | Fix |
| --- | --- | --- |
| Drives off the edge | Sensors too close to the wheels or speed too high | Move sensors forward or lower speed |
| Thinks table is a cliff | Dark surface or wrong trimmer | Adjust the trimmer or choose a lighter test surface |
| Backs off a rear edge | No rear sensor | Add one |
| Spins forever | Both sensors triggered by lifting | Add a timeout and stop |
| Erratic in sunlight | Infrared interference | Shade the sensors |

## Upgrades

- **Rear sensor:** protect the reverse move.
- **Ramp speed:** slow near edges.
- **Obstacle sensor:** add an ultrasonic sensor for objects.
- **Lift detection:** stop motors when both sensors lose the table.

## Cost and parts notes

The ₹1,580 total is an illustration and does not include shipping. Use the [cost calculator](https://roboticsengineering.in/robotics-project-cost-calculator/) to compare sellers.

## Common questions

**Why does speed matter?**

Stopping distance grows with speed, so faster robots need the sensors further ahead.

**Will it work on a dark table?**

Often not; dark surfaces reflect little infrared and can read as a cliff.

**Can it detect the edge of black tape instead?**

Yes, but then the sensor sees “no reflection” on the tape rather than on air.

**Why a stop before reversing?**

It lets the motors slow so the reverse move is controlled.

Last reviewed: November 2026. This is a design worksheet with illustrative costs. It has not been bench-tested by this site; library names, pins and limits must be checked against your board and the current library versions, and measurements from your build are welcome.
