A relay module in robotics allows a microcontroller running on 3.3V or 5V logic to switch high-voltage AC or DC loads—lights, pumps, motors, heaters, solenoids—that its GPIO pins could never drive directly. Relays are the bridge between your Arduino or ESP32 control circuit and the high-power world. This guide covers relay working principles, wiring to microcontrollers, flyback protection, solid-state relays (SSR), and practical robotics applications with complete code examples.
Table of Contents
- How a Relay Works
- Relay Module Breakdown
- Wiring to Arduino & ESP32
- Active HIGH vs Active LOW
- Arduino & ESP32 Code
- Solid State Relays (SSR)
- Robotics Applications
- Recommended Products
- FAQ
How a Relay Works
An electromechanical relay is an electromagnetic switch. The core components are:
- Coil: An electromagnet powered by 5V or 12V DC. When energised, it produces a magnetic field.
- Armature: A movable iron lever attracted by the magnetic field.
- Contacts: Three terminals: COM (common), NO (normally open), NC (normally closed).
When the coil is de-energised: COM is connected to NC (circuit is closed through NC).
When the coil is energised: The armature pulls down, connecting COM to NO (circuit closes through NO).
Key specifications:
- Coil voltage: 5V DC (most modules), 12V DC, or 24V DC
- Coil current: 70–100 mA (too high for direct GPIO — requires transistor or optocoupler driver)
- Contact rating: 10A @ 250V AC, 10A @ 30V DC (typical 5V modules)
Relay Module Breakdown
A typical 5V relay module (SRD-05VDC-SL-C or equivalent) includes:
- Relay: The mechanical switch itself
- NPN transistor (S8050 or BC817): Buffers the GPIO signal — provides enough base current to drive the relay coil without exceeding GPIO source current limits
- Flyback diode (1N4007): Absorbs the inductive voltage spike when the coil turns off. Without this, the spike (can exceed 100V) would damage the transistor and potentially the microcontroller
- Optocoupler (EL817 or PC817): Found on better-quality modules. Provides galvanic isolation — even if the high-voltage side is damaged, the microcontroller is protected
- Status LEDs: One LED per relay showing coil energised/de-energised state
Wiring to Arduino & ESP32
// Single relay module wiring:
// Relay Module → Arduino/ESP32
// VCC → 5V (NOT 3.3V — relay coil needs 5V)
// GND → GND
// IN → GPIO pin
// For ESP32 (3.3V logic with 5V relay module):
// Use modules with optocoupler — the input side accepts 3.3V-5V logic
// OR: Use a 3.3V relay module (some available but rarer)
// OR: Use level shifter between ESP32 and relay IN pin
// Load wiring (AC mains 230V — safety critical):
// Live wire from socket → Relay COM terminal
// Relay NO terminal → Live wire to load (lamp, pump, etc.)
// Neutral wire → Neutral of load (directly, not through relay)
// Earth/Ground → Earth of load
// DC load wiring example (pump, 12V motor):
// 12V supply + → Relay COM
// Relay NO → Motor/Pump +
// Motor/Pump - → 12V supply -
// Motor and Arduino/ESP32 share common GND
Critical safety note for AC mains: Always switch the LIVE (phase) wire through the relay, not the neutral. In India, live is the left pin of a 3-pin socket (for Type D plugs). Verify with a non-contact voltage tester before connecting loads.
Active HIGH vs Active LOW
Relay modules come in two types:
- Active HIGH: IN=HIGH (3.3/5V) → relay ON. IN=LOW (0V) → relay OFF. Less common.
- Active LOW: IN=LOW (0V) → relay ON. IN=HIGH → relay OFF. Most common (uses NPN transistor).
Check your module’s datasheet or test empirically. Active LOW modules turn the relay ON briefly on boot (when GPIO is floating LOW) — a potential hazard for high-power loads. Use digitalWrite(RELAY_PIN, HIGH) in setup() before pinMode to ensure relay is OFF on boot.
Arduino & ESP32 Code
// Arduino relay control (active LOW module)
#define RELAY1_PIN 7
#define RELAY2_PIN 8
#define RELAY3_PIN 9
#define RELAY4_PIN 10
void setup() {
// IMPORTANT: Set output HIGH first to prevent relay on during boot
digitalWrite(RELAY1_PIN, HIGH);
digitalWrite(RELAY2_PIN, HIGH);
digitalWrite(RELAY3_PIN, HIGH);
digitalWrite(RELAY4_PIN, HIGH);
pinMode(RELAY1_PIN, OUTPUT);
pinMode(RELAY2_PIN, OUTPUT);
pinMode(RELAY3_PIN, OUTPUT);
pinMode(RELAY4_PIN, OUTPUT);
Serial.begin(9600);
Serial.println("Relay controller ready");
}
// Helper functions
void relayOn(int pin) { digitalWrite(pin, LOW); }
void relayOff(int pin) { digitalWrite(pin, HIGH); }
bool relayState(int pin) { return digitalRead(pin) == LOW; }
void loop() {
if (Serial.available()) {
char cmd = Serial.read();
switch (cmd) {
case '1': relayOn(RELAY1_PIN); Serial.println("R1 ON"); break;
case '!': relayOff(RELAY1_PIN); Serial.println("R1 OFF"); break;
case '2': relayOn(RELAY2_PIN); Serial.println("R2 ON"); break;
case '@': relayOff(RELAY2_PIN); Serial.println("R2 OFF"); break;
case 'A': // All on
for (int p : {RELAY1_PIN, RELAY2_PIN, RELAY3_PIN, RELAY4_PIN})
relayOn(p);
break;
case 'Z': // All off
for (int p : {RELAY1_PIN, RELAY2_PIN, RELAY3_PIN, RELAY4_PIN})
relayOff(p);
break;
}
}
}
// ESP32 version with Wi-Fi control:
// (Same relay code, add WebServer and handle HTTP GET /relay?id=1&state=on)
// ESP32 relay with web server control
#include <WiFi.h>
#include <WebServer.h>
const char* SSID = "YourWiFi";
const char* PASS = "YourPassword";
WebServer server(80);
const int relayPins[] = {25, 26, 27, 14};
const int NUM_RELAYS = 4;
void handleRelay() {
if (!server.hasArg("id") || !server.hasArg("state")) {
server.send(400, "text/plain", "Missing id or state parameter");
return;
}
int id = server.arg("id").toInt() - 1; // 1-indexed to 0-indexed
String state = server.arg("state"); // "on" or "off"
if (id = NUM_RELAYS) {
server.send(400, "text/plain", "Invalid relay ID");
return;
}
if (state == "on") {
digitalWrite(relayPins[id], LOW);
server.send(200, "text/plain", "R" + String(id+1) + " ON");
} else {
digitalWrite(relayPins[id], HIGH);
server.send(200, "text/plain", "R" + String(id+1) + " OFF");
}
}
void setup() {
for (int i = 0; i < NUM_RELAYS; i++) {
digitalWrite(relayPins[i], HIGH); // All OFF on boot
pinMode(relayPins[i], OUTPUT);
}
WiFi.begin(SSID, PASS);
while (WiFi.status() != WL_CONNECTED) delay(500);
server.on("/relay", handleRelay);
server.begin();
Serial.println("Server at " + WiFi.localIP().toString());
}
void loop() { server.handleClient(); }
// Control via browser: http://192.168.1.x/relay?id=1&state=on
Solid State Relays (SSR)
SSRs use TRIAC or SCR semiconductor switches instead of mechanical contacts:
- Advantages: No mechanical wear, silent operation, fast switching (zero-crossing), no arcing
- Disadvantages: Higher cost (₹200–500 each vs ₹30–80 for EMR), generate heat (require heatsink above 10A), can only handle AC loads (DC SSRs exist but rarer)
// SSR module wiring:
// Control side (DC input):
// 3-32V DC input
// 3V from ESP32 GPIO → Control+
// GND → Control-
// Load side (AC output, mains rated):
// Load+ → Output 1
// Output 2 → Supply+
// (Same as EMR but with + heatsink)
// SSR is active HIGH (unlike most EMR modules)
// GPIO HIGH = load ON, GPIO LOW = load OFF
#define SSR_PIN 12
void relaySSR(bool on) { digitalWrite(SSR_PIN, on ? HIGH : LOW); }
Robotics Applications
- Irrigation robot: Switch a 12V pump based on soil moisture sensor reading
- Agricultural sprayer: Actuate spray nozzle solenoid valves at GPS waypoints
- Welding/plasma robot: Control high-voltage torch enable signal safely from Arduino
- Conveyor belt: Start/stop a 230V AC motor based on sensor inputs
- Smart charging station: Disconnect battery charger when full (prevents overcharging in swarm dock)
- Emergency stop: Hardware E-stop relay cuts power to all motors when triggered, regardless of software state
ESP32 all-in-one controller. Add relay modules to GPIO pins for high-voltage peripheral switching in smart robot and automation projects.
View ESP32 Driver Board on Zbotic →
Power your relay control circuit from a 9V battery for portable operation, while relay’s NO contact switches mains-powered loads independently.
View Battery on Zbotic →
FAQ
Can I use a 5V relay module directly with an ESP32 (3.3V)?
Depends on the module. Modules with optocouplers generally accept 3.3V–5V input and work fine. Modules without optocouplers (direct transistor drive) may not switch reliably at 3.3V. Test first, or use a module rated for 3.3V input logic.
My relay clicks repeatedly on its own. What causes this?
Usually voltage sag causing the coil voltage to dip below the hold-in voltage while the relay is supposed to be ON. Add a 100µF capacitor across the 5V rail near the relay module. Also check that the 5V supply can source the relay coil current (typically 70–100 mA) plus all other loads.
How do I switch a 3-phase AC motor with a relay?
Use three single-pole relays (one per phase), all controlled by the same GPIO signal. Ensure all three relays have identical operating voltage and switching time to minimise phase imbalance. For motors over 1 HP, use purpose-built contactors rather than relay modules.
What is the lifetime of an electromechanical relay?
Typically 100,000–1,000,000 operations depending on load current. At the rated 10A resistive load, most modules specify 100,000 operations. For frequent switching (e.g., PWM at 1 Hz), switch to a MOSFET or SSR instead — mechanical relays cannot handle high switching frequencies.
Add comment