Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.

IR obstacle sensor with ESP32 DevKit V1 — 3.3 V wiring and counter

Run an FC-51 style IR obstacle sensor from the ESP32 DevKit V1 3V3 pin so OUT stays at 3.3 V, read it on GPIO18 and count objects passing the beam.

Arduino C++Verified — core esp32 3.3.12, 3 Nov 2026Compile-only

Community draft — report a mistake

The IR obstacle module bounces infrared off anything in front of it and gives a clean digital LOW when something is within range. It is used in line-following and obstacle-avoiding robots, hand-wave switches and simple object counters.

On the ESP32 DevKit V1 the key point is the supply: the module’s output follows VCC, so running it from 3V3 keeps the signal at a safe level with no divider. The sketch counts each object that breaks the beam.

Wiring

ESP32 DevKit V1Only the pins used are shown · 3.3 V logicIR obstacle avoidance sensor (FC-51)GNDD183V3VCCGNDOUT
Every connection
ESP32 DevKit V1IR obstacle avoidance sensor (FC-51)WireNotes
3V3VCCredOUT is pulled up to VCC on the module — at 3V3 it can never exceed 3.3 V.
GNDGNDblack
D18OUTgreenLOW = obstacle (the module’s green LED lights).

3.3–5 V part, 3.3 V board. OUT is pulled up to VCC, so power the module from 3.3 V on ESP32 and Pico (it works fine there) and from 5 V on Uno.

Board quirks

  • Power it from 3V3, not VIN. The comparator output is pulled up to VCC, so at 5 V it would put 5 V on the GPIO. The module works fine at 3.3 V, with a slightly shorter range.
  • Set the range with the blue potentiometer while watching the green LED, not the serial output. Typical range is 2–15 cm, less on black or shiny surfaces.
  • Sunlight and halogen lamps contain lots of infrared and can trigger it constantly — shade the sensor for outdoor or window-side use.
  • GPIO18 is a plain GPIO (also VSPI SCK). If your project uses SPI, D27, D32 or D33 work just as well; avoid D2, D12 and D15 because the module holds OUT at a fixed level during reset.

Code

ir-obstacle-esp32.inoArduino C++Open in PlaygroundOpen in PlaygroundFlash
// IR obstacle sensor module (FC-51 style) on an ESP32 DevKit V1.
// VCC → 3V3, GND → GND, OUT → D18 (GPIO18). OUT goes LOW when an obstacle is in range.

constexpr uint8_t OBSTACLE_PIN = 18;

bool lastBlocked = false;
uint32_t count = 0;

void setup() {
  Serial.begin(115200);
  pinMode(OBSTACLE_PIN, INPUT);  // the module has its own pull-up to VCC (3.3 V here)
  Serial.println("IR obstacle sensor on GPIO18 — wave a hand in front of it");
}

void loop() {
  bool blocked = digitalRead(OBSTACLE_PIN) == LOW;
  if (blocked && !lastBlocked) {
    count++;
    Serial.printf("Obstacle detected (#%lu)\n", (unsigned long)count);
  } else if (!blocked && lastBlocked) {
    Serial.println("Path clear");
  }
  lastBlocked = blocked;
  delay(10);
}

Expected serial output

Serial Monitor · 115200Output
IR obstacle sensor on GPIO18 — wave a hand in front of it
Obstacle detected (#1)
Path clear
Obstacle detected (#2)
Path clear

Common errors

Always “Obstacle detected”

Range pot turned too far, or ambient IR (sunlight, a nearby remote). Turn the pot anticlockwise until the green LED goes out with nothing in front.

Never detects anything

Range pot fully anticlockwise, or the IR LED and photodiode bent so they face each other. Point both straight ahead.

Counts one object several times

Edges of the object flicker across the threshold. Add a 50 ms dead time after each detection, or debounce like a push button.

↑↓ to move · Enter to open