The Quick Answer: Wiring a 5V Relay Module to Arduino
When connecting a standard 1-channel 5V relay module to an Arduino, the direct answer is simple: connect the module VCC pin to the Arduino 5V pin, GND to GND, and the IN1 signal pin to a digital I/O pin (like D8). However, the physical 'click' of the relay does not guarantee your high-voltage load will switch. The most common point of failure for hobbyists is misunderstanding the optocoupler isolation jumper (JD-VCC) and miswiring the Normally Open (NO) versus Normally Closed (NC) screw terminals.
This guide targets the Arduino Uno R3 (ATmega328P) and the newer Uno R4 Minima. Both boards source enough current from their 5V rail to drive a single relay coil, but we will cover the exact voltage sag thresholds that cause silent failures. If you are switching mains voltage (120V/240V AC), always de-energize the circuit, lock out the breaker, and verify the lines are dead with a CAT III multimeter before touching the screw terminals. Local electrical codes may require a licensed electrician for permanent mains wiring.
Hardware Spec Sheet and Parts List
Before writing code, you need to know the exact electrical limits of the module on your bench. The ubiquitous blue 1-channel relay module uses a Songle SRD-05VDC-SL-C relay. Below is the data-dense specification sheet you need to reference when sizing your load and power supply.
| Parameter | Value / Rating | Engineering Notes |
|---|---|---|
| Coil Nominal Voltage | 5.0V DC | Must be supplied from Arduino 5V or external 5V source. |
| Coil Resistance | ~70 Ω | Draws approx. 71mA when energized. Safe for Arduino Uno 5V pin. |
| Pull-in (Must Operate) Voltage | ≤ 3.75V DC (75% of nominal) | If your Arduino 5V rail sags below 3.75V, the relay will chatter or fail to latch. |
| Max Contact Rating (AC) | 10A @ 250VAC / 15A @ 125VAC | Derate to 80% for inductive loads (motors, compressors) due to inrush current. |
| Flyback Diode | 1N4148 (Populated on module) | Protects the driving transistor from inductive voltage spikes when the coil de-energizes. |
| Optocoupler Isolation | PC817 (Populated on module) | Only active if the JD-VCC jumper is removed and external VCC is supplied. |
Most modules ship with a blue jumper cap connecting JD-VCC to VCC. In this state, the optocoupler is bypassed, and the relay coil shares the same ground and power plane as your Arduino. For basic hobby projects, leave it in place. If you are switching noisy industrial loads or want true galvanic isolation, remove the jumper, connect JD-VCC to an external 5V supply, and connect the module GND only to the external supply ground (not the Arduino ground). The Arduino signal pin will still trigger the optocoupler LED safely.
Required Parts
- Microcontroller: Arduino Uno R3 or Uno R4 Minima
- Relay Module: 1-Channel 5V Relay Module (Songle SRD-05VDC-SL-C)
- Wiring: 22 AWG solid core jumper wires (stranded wire will fray in the green screw terminals)
- Load: 120V AC desk lamp or 12V DC water pump (for testing)
- Tools: Multimeter with continuity mode, small flathead screwdriver
Pin Mapping and Wiring Steps
Proper wiring ensures the low-voltage logic side does not interfere with the high-voltage load side. Use the following pin mapping table for a standard 1-channel module.
| Relay Module Pin | Arduino Uno Pin | Function |
|---|---|---|
| VCC | 5V | Provides power to the optocoupler LED and relay coil (if JD-VCC jumpered). |
| GND | GND | Common ground reference for the control signal. |
| IN1 | D8 (Digital Pin 8) | Logic HIGH/LOW trigger. Active LOW on most standard modules. |
| COM (Common) | Load Line 1 (Hot/Positive) | The moving contact inside the relay. Connects to your power source. |
| NO (Normally Open) | Load Line 2 (Device Input) | Circuit is OPEN until relay triggers. Use this for standard on/off control. |
| NC (Normally Closed) | Not Used (Typically) | Circuit is CLOSED until relay triggers. Used for fail-safe applications. |
Step-by-Step Wiring Procedure
- Wire the Control Side: Connect Arduino 5V to Module VCC, Arduino GND to Module GND, and Arduino D8 to Module IN1.
- Prepare the Load Wires: Strip 1/4 inch of insulation from your load wires. Tin them with solder if using stranded wire to prevent loose strands from causing a short in the screw terminals.
- Wire the COM Terminal: Connect your AC Hot (or DC Positive) wire to the center COM screw terminal. Tighten firmly and give the wire a gentle tug to verify mechanical retention.
- Wire the NO Terminal: Connect the wire leading to your load (lamp/pump) to the NO terminal. (Do not use the NC terminal unless you specifically need the device to be ON when the Arduino is off).
- Complete the Load Circuit: Connect the AC Neutral (or DC Negative) directly to the other side of your load. The relay only switches the Hot/Positive leg.
Complete Arduino Code with State Tracking
The following C++ code is written for the Arduino Uno R3 / R4. It avoids the blocking delay() function, using millis() for non-blocking timing. It also includes serial error handling to catch invalid state commands and monitors for relay chatter.
// Target Board: Arduino Uno R3 / R4 Minima
// 5V Relay Module Control with Non-Blocking Timing and Serial Error Handling
#define RELAY_PIN 8
#define STATUS_LED LED_BUILTIN
#define RELAY_ACTIVE_LOW true // Most modules trigger on LOW
// State tracking variables
bool relayState = false;
unsigned long lastToggleTime = 0;
const unsigned long debounceDelay = 50; // ms
void setup() {
Serial.begin(115200);
while (!Serial) { ; } // Wait for serial port to connect (needed for native USB boards)
pinMode(RELAY_PIN, OUTPUT);
pinMode(STATUS_LED, OUTPUT);
// Initialize relay to OFF state
if (RELAY_ACTIVE_LOW) {
digitalWrite(RELAY_PIN, HIGH); // HIGH = OFF for active-low modules
} else {
digitalWrite(RELAY_PIN, LOW);
}
Serial.println('System Ready. Send \'ON\', \'OFF\', or \'TOGGLE\' via Serial Monitor.');
}
void loop() {
handleSerialCommands();
updateHardware();
}
void handleSerialCommands() {
if (Serial.available() > 0) {
String command = Serial.readStringUntil('\n');
command.trim();
command.toUpperCase();
if (command == 'ON') {
setRelayState(true);
} else if (command == 'OFF') {
setRelayState(false);
} else if (command == 'TOGGLE') {
setRelayState(!relayState);
} else {
// Error handling for invalid commands
Serial.print('ERR_INVALID_CMD: ');
Serial.println(command);
Serial.println('Valid commands: ON, OFF, TOGGLE');
}
}
}
void setRelayState(bool newState) {
if (newState == relayState) {
Serial.println('INFO: Relay already in requested state.');
return;
}
relayState = newState;
lastToggleTime = millis();
if (relayState) {
Serial.println('STATE_CHANGE: Relay Energized (ON)');
} else {
Serial.println('STATE_CHANGE: Relay De-energized (OFF)');
}
}
void updateHardware() {
// Apply state to physical pins
if (RELAY_ACTIVE_LOW) {
digitalWrite(RELAY_PIN, relayState ? LOW : HIGH);
} else {
digitalWrite(RELAY_PIN, relayState ? HIGH : LOW);
}
// Sync onboard LED for visual debugging
digitalWrite(STATUS_LED, relayState ? HIGH : LOW);
}
For deeper understanding of how microcontrollers handle digital I/O limits, refer to the official Arduino Digital Pins documentation. The code above ensures we never exceed the ATmega328P's 20mA per-pin limit because the relay module's input pin only drives an optocoupler LED (drawing ~2mA), not the relay coil directly.
Debugging: Relay Clicks but Load Doesn't Switch
The most frustrating failure mode on the bench is hearing the audible 'click' of the relay armature, but your load remains dead. If your serial monitor prints STATE_CHANGE: Relay Energized (ON) but your multimeter reads 'OL' (Open Loop) across the COM and NO terminals, you have a mechanical or wiring fault.
Here are the first three things to check when this exact failure occurs:
- Verify NO vs NC Wiring: This is the #1 beginner mistake. The screw terminals are typically arranged as NO-COM-NC. If you wired your load into the NC terminal, the circuit is closed when the Arduino is off, and opens (turns off) when the relay clicks on. Move the load wire to the NO terminal.
- Check for Pitted or Welded Contacts: If you previously used this relay to switch a high-inrush inductive load (like a motor or a halogen lamp transformer) without a snubber circuit, the internal contacts may have arced and welded together, or pitted so badly they no longer make physical contact. Fix: Replace the module. A Songle SRD-05VDC-SL-C costs less than $2. Do not attempt to open the sealed plastic relay housing to file the contacts.
- Measure Coil Voltage Under Load: The relay requires a minimum of 3.75V to pull in the armature fully. If your Arduino is powered via a weak USB port, the onboard 5V linear regulator may sag when the 71mA coil current is drawn. Fix: Put your multimeter probes on the module's VCC and GND pins while triggering the relay. If the voltage drops below 4.0V, power the Arduino with a 9V/1A wall adapter or supply the relay VCC from an external 5V buck converter.
Standard modules include a flyback diode across the coil to suppress inductive kickback. If you are building a custom relay circuit on a breadboard without a module, you must add a 1N4007 diode in reverse bias (cathode stripe to 5V, anode to the transistor drain). Failing to do this will send a high-voltage spike back into your Arduino's GPIO pin, permanently bricking the ATmega328P. For more on inductive kickback, see this All About Circuits guide on microcontroller relay driving.
Extending and Simplifying the Build
Once you have a single relay working reliably, you will likely want to scale the project. Here is how to adapt the hardware based on your specific load requirements.
How to Simplify: Switch to a MOSFET for DC Loads
If your load is strictly DC (e.g., a 12V water pump, LED strip, or PC fan) and draws less than 20A, delete the relay module entirely. Relays are mechanical, slow, noisy, and prone to contact wear. Instead, use a logic-level N-channel MOSFET like the IRLZ44N.
Wire the Arduino PWM pin to the MOSFET Gate (via a 220Ω resistor), the load to the Drain, and the Source to Ground. This gives you silent switching, infinite lifespan, and the ability to use analogWrite() for PWM speed/dimming control—something a mechanical relay cannot do.
How to Extend: Scaling to Multiple Relays
If you need to control 4, 8, or 16 AC loads (like in a home automation panel), do not use standard parallel relay modules. They consume one GPIO pin per relay and clutter your wiring harness.
Instead, use an I2C Relay Expander based on the PCF8574 or MCP23017 chip. These modules allow you to drive up to 8 relays using only two Arduino pins (SDA and SCL). Alternatively, for high-reliability industrial prototyping, look into the Component101 relay module database to find solid-state relay (SSR) modules, which use triacs to switch AC loads silently with zero moving parts.
By understanding the exact coil specifications, respecting the optocoupler isolation boundaries, and using non-blocking code with serial error tracking, your 5V relay module projects will transition from unreliable bench experiments to robust, deployable hardware.






