Engineering · Raspberry Pi · Project 20 of 47 · Industrial automation · Intermediate
Machine stack light with start, stop and e-stop
A tower light shows the machine state like on a factory floor: yellow for ready, green for running, flashing red with a horn for an emergency stop.

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 |
|---|---|
| Stack light | Stack light |
| Horn | Buzzer |
| Start | Push button |
| Stop | Push button |
| E-stop | Push button |
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 | Coloured | Stack light - RED | Pin 15 (GPIO22) |
| 2 | Coloured | Stack light - YEL | Pin 16 (GPIO23) |
| 3 | Coloured | Stack light - GRN | Pin 18 (GPIO24) |
| 4 | Black | Stack light - GND | Pin 6 (GND) |
| 5 | Coloured | Horn - + | Pin 12 (GPIO18) |
| 6 | Black | Horn - - | Pin 9 (GND) |
| 7 | Coloured | Start - Signal | Pin 13 (GPIO27) |
| 8 | Black | Start - GND | Pin 14 (GND) |
| 9 | Coloured | Stop - Signal | Pin 29 (GPIO5) |
| 10 | Black | Stop - GND | Pin 20 (GND) |
| 11 | Coloured | E-stop - Signal | Pin 31 (GPIO6) |
| 12 | Black | E-stop - GND | Pin 25 (GND) |
Python code (gpiozero)
from gpiozero import Button, LED, Buzzer
from time import sleep
start = Button(27)
stop = Button(5)
estop = Button(6) # latched in = emergency (click it to latch or release)
red = LED(22)
yellow = LED(23)
green = LED(24)
horn = Buzzer(18)
state = None
def set_state(new):
global state
if new == state:
return
state = new
print("State:", state)
red.off()
yellow.off()
green.off()
horn.off()
if state == "READY":
yellow.on()
elif state == "RUNNING":
green.on()
elif state == "EMERGENCY":
red.blink(0.4, 0.4)
horn.beep(0.4, 0.4)
set_state("READY")
while True:
if estop.is_pressed:
set_state("EMERGENCY")
elif state == "EMERGENCY":
set_state("READY") # e-stop released: a new Start is needed
elif state == "READY" and start.is_pressed:
set_state("RUNNING")
elif state == "RUNNING" and stop.is_pressed:
set_state("READY")
sleep(0.05)
How the code works
- The program always has exactly one state. set_state() changes it, switches all lights off, then turns on only what that state needs.
- The e-stop is checked first in every loop, so it beats Start and Stop at any time.
- After the e-stop is released the machine goes to READY, not RUNNING. The operator must press Start again. This is a safety rule on real machines.
- The "if new == state: return" line stops the lights from being reset on every loop.
You will learn
- A state machine: READY, RUNNING and EMERGENCY
- The industrial colour code of a stack light
- Why e-stop release must not restart the machine
Try this
- Press Start, then click the e-stop, release it, and watch the lights.
- Add an amber flashing light for a warning state.
- Count how many times the machine has been started and print it.
On a real Pi
- IMPORTANT: a real e-stop must cut the power to the drives with hard-wired contacts and a safety relay. It must never depend on Python or on any software. This page shows only the signalling.
- Use normally-closed e-stop contacts so a cut wire also stops the machine.
- Stack light colours: red = stop or fault, yellow = attention or ready, green = running.
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 | Tactile push button (12 mm, with cap) | 2 | Robu.in Amazon.in ThinkRobotics |
| 5 | Emergency stop push button, NC contact (22 mm) | 1 | Robu.in Amazon.in ThinkRobotics |
| 6 | Active buzzer, 5 V | 1 | Robu.in Amazon.in ThinkRobotics |
| 7 | Stack light (tower lamp), 3 colour, 24 V | 1 | Robu.in Amazon.in ThinkRobotics |
| 8 | 3-channel relay or transistor driver board for the lamps | 1 | Robu.in Amazon.in ThinkRobotics |
| 9 | Dupont jumper wires, male-to-female, 20 cm (pack of 40) | 1 | Robu.in Amazon.in ThinkRobotics |
| 10 | 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.