To switch AC mains loads with an Arduino and relay board, use an Arduino Uno R3 paired with a 5V opto-isolated relay module featuring the SRD-05VDC-SL-C relay. Never wire mains voltage directly to microcontroller GPIO pins, and always use the optocoupler and onboard driver transistor to protect your board from back-EMF and transients.
The Hardware Decision: Picking Your Arduino and Relay Board
Choosing the right combination of microcontroller and switching hardware depends entirely on your load type and current draw. Cheap relay modules are fantastic for resistive loads like incandescent bulbs or heaters, but they will weld their internal contacts shut if you use them to switch high-inrush inductive loads like large motors or transformers without proper snubber circuits.
| If Your Load Is... | Then Choose This Hardware | Why? |
|---|---|---|
| < 5A Resistive (Lamps, Heaters) | 1-Channel 5V SRD-05VDC-SL-C Module | Mechanical relays are cheap, provide total galvanic isolation, and handle resistive loads easily. |
| > 5A or Inductive (Motors, Pumps) | Solid State Relay (SSR) like Omron G3MB-202P | No moving parts to arc or weld. Zero-crossing SSRs prevent massive inrush current spikes. |
| Requires WiFi / Remote Control | ESP32 DevKit V1 + 3.3V Relay Module | ESP32 GPIO is 3.3V. Standard 5V relay optocouplers won't trigger reliably without a level shifter. |
Exact Parts List and Pin Mapping
Before you start stripping wires, verify you have the exact components listed below. Using a 12V relay module with a 5V Arduino is a common beginner mistake that results in the relay clicking weakly or not pulling in at all.
| Component | Exact Variant / Model | Approx. Cost | Notes |
|---|---|---|---|
| Microcontroller | Arduino Uno R3 (ATmega328P) | $27.00 | 5V logic, 40mA max per GPIO pin. |
| Relay Module | 5V 1-Channel Opto-Isolated (SRD-05VDC-SL-C) | $3.50 | Must have onboard optocoupler and flyback diode. |
| Power Supply | 5V 2A USB Barrel Jack Adapter | $6.00 | Powers the Arduino; relay coil draws ~70mA. |
| Wiring (Low Voltage) | 22 AWG Solid Core Hookup Wire | $12.00 | For Arduino to Relay module connections. |
| Wiring (Mains) | 14 AWG THHN or NM-B (Copper) | $0.50/ft | Rated for 15A/120VAC minimum. |
Pin Mapping Table
The standard 1-channel relay module uses an ACTIVE LOW logic trigger. This means the relay engages when the GPIO pin is pulled to GND (LOW), and disengages when it is HIGH.
| Arduino Uno R3 Pin | Relay Module Pin | Function |
|---|---|---|
| 5V | VCC | Powers the optocoupler LED and logic circuit. |
| GND | GND | Common ground reference. |
| Digital Pin 8 | IN (or Signal) | Control signal (Active LOW). |
Step-by-Step Mains Wiring and Safety Protocol
- De-energize and Verify: Turn off the breaker for the circuit you are tapping into. Test the Line (hot) and Neutral wires with a multimeter to confirm 0V AC.
- Prepare the Mains Wires: Strip 3/8 inch of insulation from your 14 AWG THHN or NM-B wires. Crimp on spade connectors or ferrules; do not wrap bare stranded wire around the relay screw terminals, as this creates a fire hazard from loose strands.
- Wire the Relay Switching Side: Connect the AC Line (Hot) wire to the COM (Common) terminal on the relay. Connect the wire going to your load (e.g., the lamp) to the NO (Normally Open) terminal. The Neutral wire bypasses the relay and connects directly to the load.
- Wire the Low Voltage Side: Connect Arduino 5V to VCC, GND to GND, and Pin 8 to IN. Keep these low-voltage wires physically separated from the mains wires to prevent capacitive coupling and noise.
- Enclose the Project: Never leave a mains-wired relay module exposed on a breadboard. Mount the Arduino and relay module inside a non-conductive ABS or polycarbonate project box with proper strain relief on the AC cord.
Complete Compilable Arduino Code
This code targets the Arduino Uno R3. It includes pin definitions, safe initial states (ensuring the relay is OFF on boot), and a Serial command parser with error handling for invalid inputs. Because most relay modules are Active LOW, writing a HIGH signal turns the relay OFF.
#define RELAY_PIN 8
#define BAUD_RATE 9600
// Track state to prevent redundant switching
bool relayState = false;
void setup() {
Serial.begin(BAUD_RATE);
// Configure pin and set to SAFE STATE (OFF) immediately
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, HIGH); // HIGH = OFF for Active Low modules
Serial.println("System Ready. Relay is OFF.");
Serial.println("Send 'ON' or 'OFF' via Serial Monitor.");
}
void loop() {
if (Serial.available() > 0) {
String cmd = Serial.readStringUntil('\n');
cmd.trim(); // Remove whitespace and carriage returns
if (cmd == "ON") {
if (!relayState) {
digitalWrite(RELAY_PIN, LOW); // LOW = ON
relayState = true;
Serial.println("SUCCESS: Relay ENGAGED");
} else {
Serial.println("INFO: Relay is already ON.");
}
}
else if (cmd == "OFF") {
if (relayState) {
digitalWrite(RELAY_PIN, HIGH); // HIGH = OFF
relayState = false;
Serial.println("SUCCESS: Relay DISENGAGED");
} else {
Serial.println("INFO: Relay is already OFF.");
}
}
else {
// Error handling for invalid serial commands
Serial.print("ERROR: '");
Serial.print(cmd);
Serial.println("' is not a valid command. Use ON or OFF.");
}
}
}
Debugging: First Three Things to Check When It Fails
When your Arduino and relay board setup doesn't work, the issue is almost always related to current limits, back-EMF, or terminal confusion. Here is your diagnostic path.
1. The Compiler Error: 'RELAY_PIN' was not declared
Exact Error String: error: 'RELAY_PIN' was not declared in this scope
Ranked Causes:
- You copied the
loop()code but forgot to copy the#define RELAY_PIN 8at the very top of the sketch. - You have a typo in the variable name (e.g.,
digitalWrite(Relay_Pin, LOW)with different capitalization). C++ is strictly case-sensitive.
Fix: Ensure the #define statement is at the global scope before void setup().
2. Hardware Failure: Arduino Resets When Relay Clicks
Symptom: The relay clicks once, the Arduino's power LED flickers, and the board reboots or freezes.
Ranked Causes:
- Missing or Failed Flyback Diode: The relay coil is an inductor. When power is cut, the collapsing magnetic field generates a massive reverse voltage spike (back-EMF). If the module lacks a flyback diode (or it's blown), this spike travels back up the 5V rail and browns out the ATmega328P.
- USB Power Starvation: The relay coil draws ~70mA. If your PC's USB port is underpowered, the sudden current draw drops the 5V rail below the ATmega's brownout detection threshold (typically 2.7V-4.3V).
Fix: Verify your relay module has a 1N4148 or similar diode across the coil. Power the Arduino via the barrel jack with a dedicated 5V 2A wall adapter instead of a weak USB port.
3. Hardware Failure: Relay Clicks but Load Doesn't Turn On
Symptom: You hear the mechanical click, the module's LED turns on, but your lamp stays dark.
Ranked Causes:
- Wired to NC instead of NO: You wired the load to the Normally Closed (NC) terminal. The circuit is closed when the relay is OFF, and opens when it clicks ON.
- Blown Internal Trace: You exceeded the 10A rating (or the realistic 5A PCB trace limit) and melted the internal copper trace on the module.
Fix: Move the load wire from NC to NO. Use a multimeter in continuity mode to verify the COM and NO terminals connect when the relay is energized.
Extending and Simplifying the Build
Once you have the basic mechanical relay working, you will quickly discover its limitations: the loud clicking noise, the contact arcing, and the limited lifespan (typically 100,000 mechanical cycles). Here is how to evolve the project based on your end goal.
How to Simplify: Upgrade to a Solid State Relay (SSR)
If you are switching a load frequently (like a sous-vide heater or a 3D printer bed) or want silent operation, ditch the mechanical SRD-05VDC-SL-C and use an Omron G3MB-202P Solid State Relay.
SSRs use an internal TRIAC or MOSFET to switch the AC load. They have no moving parts, generate no audible click, and feature built-in zero-crossing detection. Zero-crossing means the SSR only turns on or off when the AC sine wave crosses 0V, drastically reducing inrush currents and electromagnetic interference (EMI). Note: Standard SSRs like the G3MB-202P only work with AC loads; they will not switch DC.
How to Extend: Add WiFi and MQTT via ESP32
To control your relay from a smartphone or integrate it into Home Assistant, swap the Arduino Uno R3 for an ESP32 DevKit V1.
Because the ESP32 operates at 3.3V logic, a standard 5V relay module's optocoupler LED might not trigger reliably with only 3.3V. You have two options:
- Option A (Easiest): Buy a relay module specifically rated for 3.3V (the coil and optocoupler are tuned for lower voltage).
- Option B (The JD-VCC Trick): If using a 4-channel 5V relay module, remove the 'JD-VCC' jumper. Power the relay coils (JD-VCC and GND) from a separate 5V power supply, and connect the ESP32's 3.3V GPIO to the IN pins. The ESP32 only needs to sink ~2mA to trigger the optocoupler, which it can do safely at 3.3V.
By moving to an SSR for high-cycle loads or an ESP32 for network integration, you transform a basic workbench experiment into a robust, deployment-ready smart home node. Always prioritize galvanic isolation and proper mains enclosures to ensure your build survives long past the prototype phase.






