Arduino: control relays for home automation
Drive a relay module from an Arduino to switch mains-powered devices. The most common home automation building block, with all the safety stuff included.
A relay is the chip-sized equivalent of a wall switch. You give it a low- voltage signal from the Arduino, and it switches a high-voltage circuit (e.g. a lamp, a fan, a pump). It is the bridge between “Arduino logic” and “real-world electrical things.”
This tutorial covers the safe wiring (mains electricity is dangerous if you mess up), the relay module options, and the basic control code.
Safety first
Mains voltage (110V AC in the US, 230V AC elsewhere) will kill you. Not “hurt you.” Kill you. If you are not 100% sure about your wiring, do not touch mains circuits. Use a low-voltage project (5V or 12V) for learning.
That warning out of the way, here is how to do it safely:
- Use a relay module with opto-isolation (more on this below).
- Keep mains wiring separate from low-voltage wiring.
- Use wire nuts or screw terminals, not solder, for mains connections.
- Mount the relay module in an enclosure.
- Add a fuse on the mains side.
What you need
- Arduino (Uno, Nano, etc.)
- 1-channel, 2-channel, or 4-channel relay module with opto-isolation
- Jumper wires
- Wire nuts or screw terminals
- The device you want to control (lamp, fan, etc.)
Relay module wiring
Most relay modules have three low-voltage pins on one side and three mains terminals on the other:
Low-voltage side (Arduino-facing):
- VCC: 5V from the Arduino
- GND: GND from the Arduino
- IN1, IN2, IN3, IN4: signal pins, one per relay
Mains side:
- COM: common (the live or hot wire goes here)
- NO: normally open (the device goes here when you want it off until the relay is activated)
- NC: normally closed (the device goes here when you want it on until the relay is activated)
For most projects, you use COM and NO. The device is off until the relay fires, then it turns on.
The wiring
For a single lamp:
Mains live wire ----[ fuse ]---- COM on relay
Lamp live wire ---- NO on relay
Mains neutral ---- Lamp neutral
Mains ground ---- Lamp ground (if the lamp has a ground wire)
If your relay module does not have an opto-isolator, the VCC, GND, and IN pins share a ground with the mains side. That is bad. The opto-isolator breaks that connection. Buy a module with an opto-isolator.
The code
Arduino (Uno, Nano, Mega)
#define RELAY_PIN 7
void setup() {
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW); // relay off initially
}
void loop() {
// Turn the relay on for 5 seconds, off for 5 seconds
digitalWrite(RELAY_PIN, HIGH);
delay(5000);
digitalWrite(RELAY_PIN, LOW);
delay(5000);
}
Upload it. The relay should click every 5 seconds, and the lamp (or fan, or whatever) should turn on and off with it.
ESP32 (Arduino)
#define RELAY_PIN 5 // any GPIO; pin 5 avoids the boot-strapping pins
void setup() {
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
}
void loop() {
digitalWrite(RELAY_PIN, HIGH);
delay(5000);
digitalWrite(RELAY_PIN, LOW);
delay(5000);
}
Same code. Pin 5 is a safe choice on the ESP32 (it is not a boot-strapping pin).
MicroPython (ESP32 or Pico)
from machine import Pin
import time
# ESP32: GPIO 5. Pico: GP5.
relay = Pin(5, Pin.OUT)
while True:
relay.value(1)
time.sleep(5)
relay.value(0)
time.sleep(5)
Same wiring as the Arduino version. Pin.value(1) is HIGH,
Pin.value(0) is LOW.
Raspberry Pi Python
from gpiozero import OutputDevice
from time import sleep
relay = OutputDevice(17) # BCM pin 17 (physical pin 11)
while True:
relay.on()
sleep(5)
relay.off()
sleep(5)
pip3 install gpiozero. The Raspberry Pi is a common pick for
relay-controlled home automation because it has enough horsepower to
run Home Assistant, Node-RED, or a small web UI, and the GPIO header
is well-documented for 5V relay modules. The same wiring rules apply:
keep the mains wiring separate from the Pi’s GPIO, and use a relay
module with opto-isolation.
Active HIGH vs. active LOW
Some relay modules are active HIGH (HIGH = relay on), others are active LOW (LOW = relay on, with a pull-down). Check the module’s documentation.
You can figure it out by setting the pin to HIGH in setup() and seeing if
the relay clicks:
void setup() {
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, HIGH); // does the relay click?
}
If it does, your module is active HIGH. If it does not, try LOW.
Multiple relays
#define RELAY1_PIN 7
#define RELAY2_PIN 8
#define RELAY3_PIN 9
void setup() {
pinMode(RELAY1_PIN, OUTPUT);
pinMode(RELAY2_PIN, OUTPUT);
pinMode(RELAY3_PIN, OUTPUT);
}
void loop() {
digitalWrite(RELAY1_PIN, HIGH);
delay(1000);
digitalWrite(RELAY2_PIN, HIGH);
delay(1000);
digitalWrite(RELAY3_PIN, HIGH);
delay(2000);
digitalWrite(RELAY3_PIN, LOW);
delay(1000);
digitalWrite(RELAY2_PIN, LOW);
delay(1000);
digitalWrite(RELAY1_PIN, LOW);
delay(2000);
}
Each relay is just a digital pin. The pattern is the same.
Why use a relay instead of a transistor
A relay provides galvanic isolation. The Arduino and the device you are controlling have no electrical connection. If something goes wrong on the mains side (short, surge), the Arduino is safe.
A transistor (e.g. a MOSFET) shares ground with the device. That is fine for low-voltage DC loads (LEDs, motors, fans at 12V) but not for mains.
Use a relay for:
- Mains voltage (110V/230V AC) devices
- Anything where isolation matters (medical, safety)
Use a MOSFET for:
- Low-voltage DC loads (LEDs, motors)
- High-frequency switching (PWM motor control)
Mechanical relays vs. solid-state relays
Mechanical relays (the kind in the cheap modules) have moving parts. They click. They have a limited lifetime (about 100,000 cycles). They are cheap and they handle high currents easily.
Solid-state relays (SSRs) have no moving parts. They are silent. They last much longer. They are more expensive and they tend to leak a tiny bit of current when off (which can make some devices flicker or hum).
For most home automation projects, mechanical relays are fine. SSRs are the right call for high-cycle applications (e.g. a PID temperature controller that switches a heater every second).
What to build next
- A wifi-controlled lamp (combine with the ESP32 MQTT tutorial).
- A scheduled outlet (relay turns on at sunset, off at midnight).
- A “wake up light” that gradually turns on a lamp over 30 minutes.
The wifi-controlled version is in the book Home Automation with Arduino. The wake-up light is in the book Arduino Fun Projects.