A standard 5V relay Arduino module uses an optocoupler and a transistor driver to let a low-current GPIO pin safely switch a high-power AC or DC load. For a typical SRD-05VDC-SL-C module, wire VCC to 5V, GND to GND, and the IN pin to a digital output. Because most of these modules are active-LOW, you must set the GPIO HIGH in your setup() function before setting it as an OUTPUT to prevent the relay from momentarily triggering on boot.

MAINS VOLTAGE WARNING: Switching AC mains (>50V AC / >120V DC) is lethal. Always de-energize the breaker, lock it out, and verify the circuit is dead with a CAT III multimeter before touching terminal screws. NEC-style guidance requires proper enclosures and strain relief; your local AHJ has final authority. If you are not experienced with mains wiring, hire a licensed electrician.

Module Variants and Contact Ratings

Not all relay modules are built for the same job. The ubiquitous blue Songle/SRD relays are fine for resistive loads like incandescent bulbs or heaters, but they will weld their contacts shut if you switch high inductive loads (like large motors) without a snubber circuit. Here is how the common modules compare on the bench.

Module Type Coil Voltage / Trigger Contact Rating (Resistive) Coil Current Draw Typical Price (2026)
1-Channel Standard (SRD-05VDC-SL-C) 5V DC / Active-LOW 10A @ 250VAC / 30VDC ~70mA $2.50
4-Channel Optocoupler (LCUS-4) 5V DC / Active-LOW 10A @ 250VAC / 30VDC ~280mA (all on) $6.00
1-Channel 12V (Songle SRD-12VDC) 12V DC / Active-LOW 10A @ 250VAC / 30VDC ~30mA $3.00
Solid State (Omron G3MB-202P) 5V DC / Active-HIGH 2A @ 240VAC (Zero-cross) ~15mA $4.50

Note: Inductive loads (motors, transformers) require derating the contact capacity by at least 50% compared to the resistive ratings listed above. See the Omron relay switching capacity guidelines for exact derating curves.

Parts List and Pin Mapping

This build targets the Arduino Uno R3 (ATmega328P). We are using a 4-channel 5V module with optocoupler isolation. For the logic side, 22 AWG solid core wire is ideal. For the mains load side, use minimum 14 AWG THHN copper wire rated for your circuit breaker, and always use ferrule crimps on stranded wire before inserting it into the module's screw terminals to prevent stray strands from causing a short.

Pin Mapping Table

Arduino Uno R3 Pin Relay Module Pin Function & Notes
5V VCC (JD-VCC side) Powers the optocoupler LEDs. Keep jumper ON if using single supply.
GND GND Common logic ground.
Digital 8 IN1 Channel 1 trigger (Active-LOW).
Digital 9 IN2 Channel 2 trigger (Active-LOW).
Digital 10 IN3 Channel 3 trigger (Active-LOW).
Digital 11 IN4 Channel 4 trigger (Active-LOW).

Step-by-Step Wiring Procedure

  1. De-energize and Verify: Turn off the mains breaker. Use a non-contact voltage tester and a multimeter to verify 0V across Line and Neutral.
  2. Configure the JD-VCC Jumper: Most 4-channel modules have a jumper linking 'VCC' and 'JD-VCC'. If you are powering the Arduino and the relay module from the same 5V USB source, leave this jumper ON. If you are using a separate 5V power supply for the relay coils to prevent Arduino brownouts, remove the jumper, connect the external 5V to JD-VCC, and connect the external GND to the module GND.
  3. Wire the Logic Side: Connect Arduino 5V to module VCC, Arduino GND to module GND, and Digital pins 8-11 to IN1-IN4.
  4. Wire the Load Side (Mains): Strip 1/4 inch of insulation from your 14 AWG THHN wire. Connect the Line (hot) wire from your breaker to the COM (Common) terminal of Channel 1. Connect the wire leading to your load (e.g., a lamp) to the NO (Normally Open) terminal. Leave NC (Normally Closed) empty for standard on/off control.
  5. Secure and Enclose: Tug-test all screw terminals. Mount the module in a grounded, non-flammable project enclosure with proper cable glands for strain relief.

Safe-Boot Arduino Code

The code below targets the Arduino Uno R3. It uses a non-blocking millis() approach based on the BlinkWithoutDelay pattern, ensuring your main loop remains free to read sensors or handle network requests. Crucially, it sets the pins HIGH before configuring them as outputs to prevent the relay from fluttering on boot.


// Target Board: Arduino Uno R3 (ATmega328P)
// Module: 4-Channel 5V Relay (Active-LOW)

const int RELAY_1 = 8;
const int RELAY_2 = 9;
const int RELAY_3 = 10;
const int RELAY_4 = 11;

// Timing variables for non-blocking toggles
unsigned long previousMillis = 0;
const long interval = 5000; // Toggle every 5 seconds
bool relayState = false;

void setup() {
  Serial.begin(9600);
  
  // CRITICAL: Set pins HIGH (OFF state for active-LOW) BEFORE setting pinMode
  // This prevents the relay from momentarily triggering while the pin floats during boot
  digitalWrite(RELAY_1, HIGH);
  digitalWrite(RELAY_2, HIGH);
  digitalWrite(RELAY_3, HIGH);
  digitalWrite(RELAY_4, HIGH);
  
  pinMode(RELAY_1, OUTPUT);
  pinMode(RELAY_2, OUTPUT);
  pinMode(RELAY_3, OUTPUT);
  pinMode(RELAY_4, OUTPUT);
  
  Serial.println("System Initialized. Relays SAFE (OFF).");
}

void loop() {
  unsigned long currentMillis = millis();
  
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    relayState = !relayState; // Toggle state
    
    if (relayState) {
      // Turn ON (Active-LOW requires writing LOW)
      digitalWrite(RELAY_1, LOW);
      Serial.println("Relay 1 ENGAGED");
    } else {
      // Turn OFF
      digitalWrite(RELAY_1, HIGH);
      Serial.println("Relay 1 DISENGAGED");
    }
  }
}

Debugging: The First Three Things to Check When It Fails

When your relay module misbehaves, do not immediately blame the code. Hardware and power delivery are the usual culprits. Here are the first three things to check, ranked by likelihood.

1. Power Sag and Brownouts (The Arduino Resets)

Symptom: The Arduino restarts randomly, or if you are using an ESP32 instead of an Uno, the serial monitor spits out the exact error string: Brownout detector was triggered.
Cause: A standard USB port supplies roughly 500mA. A 4-channel relay module draws ~70mA per coil. If you trigger all four relays while powering sensors and an LCD screen, you exceed the USB current limit, causing the voltage to drop below the microcontroller's minimum threshold.
Fix: Remove the JD-VCC jumper and power the relay module's VCC/JD-VCC pins from a dedicated 5V 2A wall adapter. Tie the grounds together.

2. Logic Inversion (Relay is ON when it should be OFF)

Symptom: The load powers on immediately when the Arduino boots, and turns off when your code tells it to turn on.
Cause: You missed the active-LOW logic. Most optocoupler modules sink current through the optocoupler LED when the GPIO pin is pulled to GND (LOW).
Fix: Verify your code. digitalWrite(pin, LOW) turns the relay ON. digitalWrite(pin, HIGH) turns it OFF. Also, ensure you implemented the safe-boot sequence shown in the code above.

3. Contact Welding or Flyback Failure (Load Stays ON Permanently)

Symptom: The relay clicks audibly when triggered, but the connected load (like a motor or pump) never turns off, even when the Arduino is unplugged.
Cause: Switching inductive loads generates a massive reverse voltage spike (flyback) when the contacts open. This arc melts the internal metal contacts, welding them together permanently.
Fix: Replace the relay. To prevent recurrence, install an RC snubber network (e.g., 100 ohm resistor in series with a 0.1µF capacitor) across the load terminals, or use a Solid State Relay (SSR) which has no physical contacts to weld.

How to Extend or Simplify the Build

Depending on your end goal, a mechanical relay module might be overkill or under-specced. Here is how to adapt the architecture.

Simplify for DC Loads: If you are only switching 12V or 24V DC loads like LED strips or PC fans, ditch the mechanical relay. Use a logic-level N-channel MOSFET like the IRLZ44N. It requires zero coil current, makes no audible clicking noise, and supports high-frequency PWM dimming that would instantly destroy a mechanical relay.

Extend for High Channel Counts: The Arduino Uno only has a limited number of digital pins. If you need to control 8, 16, or 32 relays for a complex irrigation or lighting matrix, do not use shift registers (which can glitch on boot). Instead, use an MCP23017 I2C GPIO expander. It gives you 16 additional I/O pins using only the two I2C lines (A4/A5 on the Uno), and it features hardware address pins so you can daisy-chain up to eight expanders for 128 total relay channels.

Upgrade for Smart Home Integration: If you want to control these relays via MQTT or a smartphone app, swap the Arduino Uno R3 for an ESP32 DevKit V1. The ESP32 operates at 3.3V logic, which is perfectly sufficient to trigger the optocoupler LEDs on a standard 5V relay module (they typically trigger at anything above 2.5V). Just ensure you power the ESP32 and the relay module from a robust 5V supply to avoid the brownout errors mentioned in the debugging section.

For more information on safe wiring practices and enclosure requirements, always consult the NFPA 70 National Electrical Code (NEC) guidelines regarding low-voltage control circuits and mains isolation.