Learn

Detecting Metal with an Inductive Proximity Sensor on a Raspberry Pi 4B (NPN NO)

Wire an inductive NPN Normally-Open proximity sensor to a Raspberry Pi 4B through an external 4.7kΩ pull-up and read its real open-drain digital output in Python — plus how to simulate an approaching metal target for testing.

Note: the Proximity Sensor (Inductive, NPN NO) is a Premium-tier component in the simulator — you’ll need a Premium or VIP plan to use it there.

Try this directly in the free Raspberry Pi 4B simulator — no hardware or signup required. New to the GPIO header? Start with the interactive pinout guide.

What you’ll need

  • Raspberry Pi 4B
  • Proximity Sensor (Inductive, NPN NO)
  • Breadboard
  • Resistor (set to 4.7kΩ — the sensor's own external pull-up)

Step by step

  1. Drag Raspberry Pi 4B and a Breadboard onto the Canvas.
  2. Drag the Proximity Sensor (Inductive, NPN NO) onto the Canvas — like the Float Switch or HC-SR04, it connects only through drawn wires, not a breadboard.
  3. Hover over its 3 pins to confirm the labels: VCC, OUT, GND.
  4. Drag a Resistor onto the breadboard and select it — in its settings panel, set Resistance to 4.7 and the unit to kΩ.
  5. Wire VCC → a Pi 5V pin, and GND → a Pi GND pin.
  6. Wire OUT → a Pi GPIO pin you'll configure as an input (e.g. physical pin 37), and also OUT → one leg of the 4.7kΩ Resistor. Wire the Resistor's other leg → a Pi 3.3V pin — this is the external pull-up the sensor needs. This sensor's own output is open-drain (it can only ever pull the line LOW, never drive it HIGH itself), so without this pull-up, OUT has no defined level at all when nothing is detected.
  7. Go to the Code tab and write a script that polls the pin:
import RPi.GPIO as GPIO
import asyncio
 
GPIO.setmode(GPIO.BOARD)
OUT = 37 # adjust to match your wiring
 
GPIO.setup(OUT, GPIO.IN)
 
while not should_stop():
level = GPIO.input(OUT)
print("Metal detected!" if level == 0 else "Clear — no metal in range")
await asyncio.sleep(0.5)
  1. Click Start. The Console should print "Clear — no metal in range" repeatedly — with this sensor's default settings, no simulated target is close enough to trigger it.
  2. Click Stop, then select the sensor and open its settings panel. Set Target Distance to a value at or below the current Sensing Range (both default to a few millimeters — e.g. Sensing Range 3, Target Distance 2), then click Start again. The Console now prints "Metal detected!" instead, and on the Canvas the sensor's own onboard status LED lights up with its text reading TRIGGERED.
  3. Unlike the Float Switch's own click-to-toggle, this sensor's simulated state is set entirely through its settings panel — the same Stop → edit → Start pattern the HC-SR04's own Distance setting already uses. Try raising Target Distance back above Sensing Range and restarting to confirm it returns to "Clear."

What “working correctly” looks like

  • With the default settings (Sensing Range 3mm, Target Distance 20mm), GPIO.input() reads 1 (HIGH) — the pull-up resistor holds the line HIGH with nothing pulling it low.
  • Once Target Distance is set at or below Sensing Range and the simulation is restarted, GPIO.input() reads 0 (LOW) — the sensor's own open-drain output pulls the line down, overriding the 4.7kΩ pull-up — and the on-canvas status LED lights with the text reading TRIGGERED.
  • Setting Target Distance exactly equal to Sensing Range still counts as triggered — a real sensor detects a target at or within its own rated range, not only strictly closer than it.
  • A settings-panel change only takes effect after Stop then Start again — exactly like every other settings-driven sensor in this simulator (HC-SR04, DHT11), not a live drag/click.

If something’s wrong

  • GPIO.input() stays 1 (HIGH) even after lowering Target Distance below Sensing Range → make sure you clicked Stop and then Start again after editing the settings panel — the new values only take effect on the next run, not live.
  • GPIO.input() always reads 0 (LOW), even with the default "Clear" settings → double-check the Resistor's other leg actually reaches a real Pi 3.3V pin (not left dangling, and not accidentally wired to GND) — a pull-up with no real 3.3V source behind it can't hold the line HIGH.
  • Nothing changes at all, no matter the settings → confirm GND is genuinely wired back to the same Pi ground the pull-up's own reference uses — an isolated GND leaves the whole net with no defined state.
  • Expected a physical adjustment screw on the real sensor → most common, inexpensive 3-wire NPN NO barrel sensors of this type actually have a FIXED sensing distance set at the factory, with no user-accessible trimmer — that's a feature of pricier industrial units. This simulator's Sensing Range field is a testing convenience so you can exercise both the "detected" and "clear" branches of your own script, not a claim that every real version of this part has a dial to turn.