Project Overview & Difficulty Rating
If you are building an infrared proximity sensor Arduino project for obstacle avoidance, line following, or object counting, the TCRT5000 reflective optical sensor module (often sold under the FC-51 label) is the definitive starting point. It outputs both a clean digital HIGH/LOW signal and a raw analog voltage, giving you flexibility for simple triggers or nuanced distance estimation.
Difficulty Rating: 2/5 (Beginner-friendly hardware, intermediate code filtering)
Time to Complete: 20 minutes
Target Board Variant: This guide and code specifically target the Arduino Uno R4 Minima, utilizing its 14-bit ADC capabilities for smoother analog readings, though the code is 100% backward-compatible with the classic Uno R3 and Nano.
Hardware Spec Sheet & Parts List
The TCRT5000 module isn't just a raw sensor; it includes an onboard LM393 dual comparator to digitize the analog signal, and a blue multi-turn trimpot to set the digital trip threshold. Understanding these specs prevents the most common bench failures.
| Component | Specification / Variant | Est. Cost (2026) |
|---|---|---|
| Microcontroller | Arduino Uno R4 Minima (or R3/Nano) | $22.00 |
| Sensor Module | TCRT5000 Reflective Optical (FC-51 variant) | $1.50 (5-pack) |
| IR Emitter Wavelength | 950 nm (Near-Infrared) | N/A |
| Phototransistor Peak | 940 nm - 950 nm | N/A |
| Operating Voltage | 3.3V to 5.0V DC | N/A |
| Comparator IC | LM393 (Open-collector output) | N/A |
| Wiring | 22 AWG solid core (4 wires, 150mm) | $0.50 |
Pin Mapping & Wiring Steps
The LM393 comparator on the module requires a stable 5V reference to function correctly. While the module will power up on 3.3V, the analog output swing will be compressed, reducing your effective resolution on the Arduino's ADC.
| TCRT5000 Pin | Arduino Uno R4 Pin | Wire Color (Std) | Function |
|---|---|---|---|
| VCC | 5V | Red | Module power (3.3V-5V) |
| GND | GND | Black | Common ground reference |
| DO (Digital Out) | D2 | Yellow | Comparator trip signal (Active LOW) |
| AO (Analog Out) | A0 | Blue | Raw phototransistor voltage |
- De-energize the board: Ensure the Arduino is unplugged from USB before making connections.
- Strip and tin: Strip 5mm of insulation from your 22 AWG wires. If using a breadboard, ensure the module's header pins are fully seated; the FC-51 variant sometimes ships with cold solder joints on the 4-pin header.
- Connect Power: Route VCC to the 5V rail and GND to the ground rail. Do not use the 3.3V pin unless you are specifically testing low-voltage operation.
- Connect Signals: Wire DO to Digital Pin 2. Wire AO to Analog Pin A0.
- Tune the Trimpot: Before uploading code, power the board and place an object 10mm from the sensor. Use a small Phillips screwdriver to turn the blue trimpot until the onboard DO LED just toggles off. This sets your baseline threshold.
Complete Arduino Code (Uno R4 / R3 Compatible)
This sketch reads both the digital interrupt-style pin and the analog pin. It implements a simple moving average filter for the analog reading to smooth out 60Hz/50Hz mains hum and ambient IR noise, which is critical for reliable optical sensor data.
/*
* TCRT5000 Infrared Proximity Sensor Arduino Sketch
* Target: Arduino Uno R4 Minima (Compatible with R3/Nano)
* Author: ElectricalFlux Bench Team
*/
// --- PIN DEFINITIONS ---
#define IR_DIGITAL_PIN 2
#define IR_ANALOG_PIN A0
// --- CONFIGURATION ---
#define BAUD_RATE 115200
#define SAMPLE_SIZE 16 // Moving average window size
#define PROX_THRESHOLD 800 // Analog threshold (0-1023 for 10-bit, scales to 4095 on R4 14-bit mapped)
// Global variables for filtering
int analogSamples[SAMPLE_SIZE];
int sampleIndex = 0;
long analogSum = 0;
void setup() {
Serial.begin(BAUD_RATE);
// Initialize digital pin with internal pull-up just in case module pull-up fails
pinMode(IR_DIGITAL_PIN, INPUT_PULLUP);
pinMode(IR_ANALOG_PIN, INPUT);
// Initialize the sample array
for (int i = 0; i < SAMPLE_SIZE; i++) {
analogSamples[i] = 0;
}
Serial.println("TCRT5000 Initialized. Calibrate trimpot if DO is stuck.");
}
void loop() {
// 1. Read Digital Pin (Active LOW when object is detected)
bool objectDetectedDigital = !digitalRead(IR_DIGITAL_PIN);
// 2. Read and Filter Analog Pin
analogSum -= analogSamples[sampleIndex];
int currentRead = analogRead(IR_ANALOG_PIN);
analogSamples[sampleIndex] = currentRead;
analogSum += currentRead;
sampleIndex = (sampleIndex + 1) % SAMPLE_SIZE;
int smoothedAnalog = analogSum / SAMPLE_SIZE;
// 3. Hardware Fault Detection
if (smoothedAnalog >= 1020 && objectDetectedDigital) {
Serial.println("Error: Sensor reading stuck at 1023. Check AO wiring.");
}
// 4. Output Data
Serial.print("Digital: ");
Serial.print(objectDetectedDigital ? "DETECTED" : "CLEAR ");
Serial.print(" | Analog Raw: ");
Serial.print(currentRead);
Serial.print(" | Smoothed: ");
Serial.println(smoothedAnalog);
delay(50); // 20Hz update rate
}
Debugging: First 3 Things to Check When It Fails
When an infrared proximity sensor Arduino build fails, it rarely means the sensor is dead. It is almost always a configuration or wiring fault. Here is the ranked decision tree for the three most common bench errors.
⸮⸮⸮⸮⸮ or garbage charactersRanked Causes:
1. Baud Rate Mismatch: The code sets
Serial.begin(115200), but your IDE Serial Monitor dropdown is set to 9600. Change the IDE dropdown to 115200.2. USB Cable Fault: A degraded data line in your USB-C/Micro-USB cable is causing packet loss. Swap the cable.
3. Ground Loop: If powered via an external supply while connected to USB, a ground potential difference is corrupting the UART TX line. Disconnect external power.
fatal error: IRremote.h: No such file or directoryRanked Causes:
1. Wrong Sensor Type Confusion: You copied code meant for an IR Remote Receiver (like the VS1838B 38kHz demodulator) instead of an IR Proximity Sensor. The TCRT5000 does not use the IRremote library. Delete the
#include <IRremote.h> line and use the raw digitalRead() code provided above.2. Missing Library: If you actually are using a 38kHz remote receiver, you need to install the 'IRremote' library via the Arduino Library Manager.
Ranked Causes:
1. Trimpot Misadjusted: The blue potentiometer is tuned too far, keeping the LM393 comparator permanently latched. Turn it counter-clockwise until the onboard LED turns off.
2. Target Object Absorption: You are testing with a black, matte object (like electrical tape or dark rubber). 950nm IR light is heavily absorbed by black pigments. Test with a white piece of paper first to verify the circuit.
3. AO Wired to Digital Pin: If your analog reading is stuck at exactly 1023 or 0 and never moves, you have likely plugged the AO wire into a standard digital pin (like D3) instead of an ADC-capable pin (A0-A5).
Extending and Simplifying the Build
Depending on your final application, you will want to scale this circuit up or strip it down.
How to Simplify (Line Following / Basic Obstacle)
If you only need a binary 'obstacle present' signal (e.g., for a basic robot bumper), delete all analog code. Disconnect the AO wire entirely. Rely solely on the DO pin and the hardware comparator. This frees up ADC channels and reduces code execution time, allowing your motor control loop to run faster.
How to Extend (Multi-Sensor Arrays & Interrupts)
For a line-following robot using 5 or 7 TCRT5000 modules, polling digitalRead() in a loop introduces latency. Instead, use hardware interrupts. On the Uno R4, pins 2 and 3 support interrupts. You can attach an Interrupt Service Routine (ISR) to the DO pins to instantly register a line-crossing event without blocking your main motor PID loop. Furthermore, if you need to map actual distance in millimeters, you must calibrate the analog output against known distances and fit a non-linear regression curve (the inverse-square law governs IR reflectance intensity).
Frequently Asked Questions
Can an infrared proximity sensor Arduino project detect clear glass?
No, standard 950nm TCRT5000 modules struggle heavily with clear glass. Glass is highly transparent to near-infrared light, meaning the IR passes through rather than reflecting back to the phototransistor. If you need to detect glass doors or transparent bottles, you must switch to an ultrasonic sensor (like the HC-SR04) or a Time-of-Flight (ToF) laser sensor like the VL53L0X, which rely on acoustic reflection or precise photon timing rather than diffuse IR reflectance.
What is the maximum range for a TCRT5000 infrared proximity sensor with Arduino?
The practical maximum range is roughly 25mm (1 inch), but the usable range for reliable analog distance estimation is only 2mm to 10mm. Beyond 15mm, the inverse-square drop-off in reflected IR intensity makes the analog signal indistinguishable from ambient noise. If your project requires detection beyond 30mm, you need to use a modulated IR receiver setup (like a Panasonic PIR or a dedicated IR distance sensor like the Sharp GP2Y0A21YK0F) which uses optical bandpass filtering to reject ambient light.
Why does my infrared proximity sensor Arduino code trigger falsely in sunlight?
Sunlight contains a massive amount of broadband electromagnetic radiation, including a heavy concentration of near-infrared light around the 900nm-1000nm spectrum. When direct or even bright indirect sunlight hits the TCRT5000's phototransistor, it saturates the sensor, pulling the analog voltage to ground and tricking the LM393 comparator into a false 'detected' state. To fix this, you must physically shield the sensor with an opaque shroud (like a piece of heat-shrink tubing over the LED/phototransistor pair) or switch to a 38kHz modulated IR sensor that ignores unmodulated ambient light.






