Engineering · Raspberry Pi · Project 47 of 47 · Industrial automation · Advanced
Light-curtain safety interlock
A conveyor motor may run only while the light curtain is clear and the emergency stop is released. Any interruption stops it, and an operator must press Start again.

CAUTION: 230 V single-phase mains. The relay in this project switches a mains load (Live and Neutral, 230 V AC, 50 Hz in India). Mains can kill. Practise with the simulator or a low-voltage lamp. Build the mains side only with a qualified electrician, in a closed insulated box, behind a fuse or MCB and a 30 mA RCCB. Never touch the relay screw terminals while anything is connected.
Machine safety. This project only shows signalling and logic. A real emergency stop must cut power through hard-wired safety-rated contacts and relays and must never depend on software or a Raspberry Pi.
Parts in this circuit
| Part | Type |
|---|---|
| Light curtain | Beam sensor |
| Emergency stop | Push button |
| Start | Push button |
| Conveyor motor | Relay module |
| Running | LED |
| Safety stop | LED |
Wiring, pin by pin
Red = 5 V, orange = 3.3 V, black = GND, other colours = signals. “Pin” is the position on the 40-pin header; the GPIO number is what the code uses. Power the Pi from a 5.1 V supply and wire with the power off.
| # | Colour | From (part and leg) | To (header pin) |
|---|---|---|---|
| 1 | Red | Light curtain - VCC | Pin 2 (5V) |
| 2 | Coloured | Light curtain - OUT | Pin 11 (GPIO17) |
| 3 | Black | Light curtain - GND | Pin 6 (GND) |
| 4 | Coloured | Emergency stop - Signal | Pin 29 (GPIO5) |
| 5 | Black | Emergency stop - GND | Pin 9 (GND) |
| 6 | Coloured | Start - Signal | Pin 13 (GPIO27) |
| 7 | Black | Start - GND | Pin 14 (GND) |
| 8 | Coloured | Conveyor motor - IN | Pin 15 (GPIO22) |
| 9 | Black | Conveyor motor - GND | Pin 20 (GND) |
| 10 | Red | Conveyor motor - VCC | Pin 4 (5V) |
| 11 | Coloured | Running - anode + | Pin 16 (GPIO23) |
| 12 | Black | Running - cathode - | Pin 25 (GND) |
| 13 | Coloured | Safety stop - anode + | Pin 18 (GPIO24) |
| 14 | Black | Safety stop - cathode - | Pin 30 (GND) |
Python code (gpiozero)
from gpiozero import Button, OutputDevice, LED
from time import sleep
curtain = Button(17) # beam broken = pressed
estop = Button(5) # latched when pressed
start = Button(27)
motor = OutputDevice(22, active_high=False)
green = LED(23)
red = LED(24)
running = False
tripped = False
while True:
safe = not curtain.is_pressed and not estop.is_pressed
if not safe:
if running or not tripped:
print("SAFETY STOP: curtain broken or emergency stop pressed")
running = False
tripped = True
elif start.is_pressed:
if tripped:
print("Safety circuit is clear again. Motor restarted by Start")
tripped = False
if not running:
print("Motor RUNNING")
running = True
motor.value = running
green.value = running
red.value = tripped
sleep(0.02)
How the code works
- safe is true only when the beam is clear and the e-stop is released.
- Any unsafe moment sets running to False and tripped to True. The motor stays off even if the beam clears again.
- Only a press on Start restarts the motor, and only while it is safe.
You will learn
- An interlock: a condition that must hold for running
- Latching a fault until the operator acts
- Why a restart is a deliberate action
Try this
- Press Start. Then click the beam sensor. The motor must stop and stay stopped.
- Latch the emergency stop and press Start. Nothing should run.
- Release the e-stop and press Start again.
On a real Pi
- This shows the idea only. A real light curtain (Type 2 or 4, EN 61496) and a safety relay with redundant monitored contacts must do the safety job. A Raspberry Pi program must not.
- Do a risk assessment for the machine before you use any guard.
- Test the light curtain every shift with a test rod, as the manual says.
Parts to buy
The links open a search on each store, so you see what is in stock today. Check the model, voltage and price before you order.
| # | Item | Qty | Buy / compare |
|---|---|---|---|
| 1 | Raspberry Pi 4 Model B about 4000 to 9000 INR | 1 | Robu.in Amazon.in ThinkRobotics |
| 2 | Official 15 W USB-C power supply (5.1 V, 3 A) Do not use an old phone charger | 1 | Robu.in Amazon.in ThinkRobotics |
| 3 | microSD card 32 GB, class 10 / A1 (with Raspberry Pi OS) And a card reader to write it | 1 | Robu.in Amazon.in ThinkRobotics |
| 4 | 5 mm LED, red | 1 | Robu.in Amazon.in ThinkRobotics |
| 5 | 5 mm LED, green | 1 | Robu.in Amazon.in ThinkRobotics |
| 6 | 330 ohm resistor, 1/4 W One per LED | 2 | Robu.in Amazon.in ThinkRobotics |
| 7 | Tactile push button (12 mm, with cap) | 1 | Robu.in Amazon.in ThinkRobotics |
| 8 | Emergency stop push button, NC contact (22 mm) | 1 | Robu.in Amazon.in ThinkRobotics |
| 9 | 1-channel 5 V relay module with optocoupler 10 A 250 V AC contacts | 1 | Robu.in Amazon.in ThinkRobotics |
| 10 | 230 V AC small fan | 1 | Robu.in Amazon.in ThinkRobotics |
| 11 | Closed ABS enclosure (IP54) for the mains side | 1 | Robu.in Amazon.in ThinkRobotics |
| 12 | 3-way screw terminal block (rated 10 A) | 1 | Robu.in Amazon.in ThinkRobotics |
| 13 | MCB 6 A single pole and RCCB 30 mA (by an electrician) Mains protection | 1 | Robu.in Amazon.in ThinkRobotics |
| 14 | IR beam / break-beam sensor pair (3.3 V compatible) | 1 | Robu.in Amazon.in ThinkRobotics |
| 15 | Dupont jumper wires, male-to-female, 20 cm (pack of 40) | 1 | Robu.in Amazon.in ThinkRobotics |
| 16 | Breadboard 830 points For resistors and shared GND / 5 V | 1 | Robu.in Amazon.in ThinkRobotics |
This is a learning tool. The simulator checks the program logic, not the electrical design. Never put more than 3.3 V on a GPIO pin.