ESP ↔ Relay Wiring
Pin-by-pin wiring guide for all ESP boards and relay modules with power safety and testing.
ESP ↔ Relay Wiring Guide
Complete pin-by-pin guide for connecting ANY ESP board to ANY relay module. No electronics experience required — just follow the tables!
1. Identify Your ESP Board
| Board Name | Chip | USB Chip | Voltage | Relay-Safe GPIOs | Photo Clue |
|---|---|---|---|---|---|
| NodeMCU ESP8266 | ESP8266 | CP2102 / CH340 | 3.3V logic, Vin=5V | D1(5), D2(4), D5(14), D6(12), D7(13) | Small, narrow, blue PCB |
| ESP32 DevKit V1 | ESP32 | CP2102 | 3.3V logic, Vin=5V | 2, 4, 5, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 25, 26, 27, 32, 33 | Wider, 30-pin or 38-pin |
| ESP32-S2 | ESP32-S2 | Native USB | 3.3V logic, Vin=5V | 1–18, 33–42 | USB-C, single-core |
| ESP32-S3 | ESP32-S3 | Native USB | 3.3V logic, Vin=5V | 1–21, 35–48 | USB-C, dual-core |
| ESP32-C3 | ESP32-C3 | Native USB | 3.3V logic, Vin=5V | 0–10, 18, 19, 20, 21 | Small, RISC-V, USB-C |
| ESP32-C6 | ESP32-C6 | Native USB | 3.3V logic, Vin=5V | 0–7, 10–15, 18–23 | USB-C, Wi-Fi 6 + Thread |
Avoid these GPIOs on ESP32: GPIO 0, 6–11 (flash), GPIO 34–39 (input-only on classic ESP32).
2. Identify Your Relay Module
| Module | Channels | Trigger | Isolation | Typical Use |
|---|---|---|---|---|
| 1-channel | 1 | Active LOW (usually) | Optocoupler | Single light/fan |
| 2-channel | 2 | Active LOW | Optocoupler | Light + fan |
| 4-channel | 4 | Active LOW | Optocoupler | Full room |
| 8-channel | 8 | Active LOW | Optocoupler | Multiple rooms |
| SSR (Solid State) | 1 | Active HIGH | Built-in | Silent, no click |
Relay Module Pins Explained
| Pin | What it does |
|---|---|
| VCC | Power for the relay coil — connect to 5V (from ESP Vin or external) |
| GND | Ground — connect to ESP GND |
| IN1 (IN2, IN3...) | Signal pin — connect to ESP GPIO |
| COM | Common — one wire from mains goes here |
| NO (Normally Open) | Connects to COM when relay ON — use this for lights |
| NC (Normally Closed) | Connects to COM when relay OFF — rarely used |
3. Wiring Diagrams
3A — ESP32 DevKit V1 → 4-Channel Relay
ESP32 DevKit V1 4-Channel Relay Module
┌──────────────┐ ┌───────────────────┐
│ │ │ │
│ Vin (5V) ──┼─────────── │── VCC │
│ GND ──┼─────────── │── GND │
│ │ │ │
│ GPIO 2 ──┼─────────── │── IN1 (Light 1) │
│ GPIO 4 ──┼─────────── │── IN2 (Light 2) │
│ GPIO 5 ──┼─────────── │── IN3 (Light 3) │
│ GPIO 18 ──┼─────────── │── IN4 (Fan) │
│ │ │ │
└──────────────┘ └───────────────────┘
Firmware pin config (matches default):
const DevicePin DEVICES[] = {
{ "d1", 2, true }, // IN1 — Living Room Light
{ "d4", 4, true }, // IN2 — Bedroom Light
{ "d8", 5, true }, // IN3 — Kitchen Light
{ "d2", 18, true }, // IN4 — Fan
};
3B — ESP8266 NodeMCU → 4-Channel Relay
NodeMCU ESP8266 4-Channel Relay Module
┌──────────────┐ ┌───────────────────┐
│ │ │ │
│ Vin (5V) ──┼─────────── │── VCC │
│ GND ──┼─────────── │── GND │
│ │ │ │
│ D1 (GPIO5) ─┼─────────── │── IN1 (Light 1) │
│ D2 (GPIO4) ─┼─────────── │── IN2 (Light 2) │
│ D5 (GPIO14)─┼─────────── │── IN3 (Light 3) │
│ D6 (GPIO12)─┼─────────── │── IN4 (Fan) │
│ │ │ │
└──────────────┘ └───────────────────┘
Firmware pin config for ESP8266:
const DevicePin DEVICES[] = {
{ "d1", 5, true }, // D1 — Living Room Light
{ "d4", 4, true }, // D2 — Bedroom Light
{ "d8", 14, true }, // D5 — Kitchen Light
{ "d2", 12, true }, // D6 — Fan
};
3C — ESP32-S3 / C3 → 2-Channel Relay
⚠️ Avoid GPIO 0 (boot), GPIO 2 (may be USB-D– on S3), GPIO 19–20 (USB on S3).
ESP32-S3 / C3 2-Channel Relay Module
┌──────────────┐ ┌───────────────────┐
│ │ │ │
│ 5V ──┼─────────── │── VCC │
│ GND ──┼─────────── │── GND │
│ │ │ │
│ GPIO 4 ──┼─────────── │── IN1 (Light) │
│ GPIO 5 ──┼─────────── │── IN2 (Fan) │
│ │ │ │
└──────────────┘ └───────────────────┘
4. Power Safety
⚠️ Critical Rules
ESP GPIOs are 3.3V — Most relay modules have optocouplers that work fine with 3.3V signals. If your relay doesn't trigger, check rule #3.
Power the relay VCC from 5V, NOT 3.3V — The relay coil needs 5V. Use the ESP's Vin pin (which passes USB 5V through), or use an external 5V power supply.
If relay doesn't respond to 3.3V signal — Some cheap relays need 5V logic. Solutions:
- Use a logic level shifter (3.3V → 5V)
- Use a relay module that explicitly supports 3.3V trigger (most optocoupler-isolated ones do)
- Connect relay VCC to 3.3V (but coil may be weak — not recommended)
Never connect mains power (110V/220V AC) while testing — Test with relay clicks only first. Wire mains only after everything works reliably.
External power for 4+ channel relays — If using 4 or more relays, power the relay VCC from an external 5V supply (not from the ESP's Vin), sharing GND with the ESP.
Power Source Options
| Source | When to Use | How |
|---|---|---|
| USB cable (5V from computer) | Testing/development | Just plug in USB — Vin pin provides 5V |
| Phone charger (5V 2A) | Permanent installation with 1-2 relays | Plug into ESP USB port |
| External 5V supply | 4+ relays or high-power relays | Connect 5V→relay VCC, GND→shared GND |
5. Testing Procedure
Step-by-Step Relay Verification
Before powering on:
- Double-check all wiring matches the diagram above
- Ensure VCC → 5V (not 3.3V)
- Ensure GND is shared between ESP and relay module
- No mains/AC wires connected yet
After uploading firmware & connecting:
- Open the Fantom Interio app → Smart Home Hub → Connections → ESP32
- Click 🚀 Smart Connect
- Wait for connection (green progress = good)
- Scroll down to Relay Health Check section
- Click 🔍 Detect Relays — you should see your relay channels listed
- Click ⚡ Quick Check (Ping) → each relay shows ✅ (responding) or ❌ (no response)
- Click 🔌 Physical Test (Pulse) → you should hear each relay click (ON for 0.2 seconds, then OFF)
What Each Result Means
| Status | LED | Meaning | Action |
|---|---|---|---|
| ✅ Responding | Green | Relay channel detected and firmware responded | Working! |
| ⏳ Untested | Gray | Haven't tested yet | Run the test |
| ❌ No Response | Red | Relay didn't respond to command | Check wiring (see §6) |
| ⚠️ Error | Yellow | Communication error | Reconnect and retry |
6. Troubleshooting
Problem → Cause → Fix
| Problem | Likely Cause | Fix |
|---|---|---|
| Can't connect at all | Wrong WiFi credentials | Edit WIFI_SSID / WIFI_PASS in firmware, re-upload |
| Connected but relay doesn't click | Wrong GPIO pin number | Verify pin matches the physical wire. Use relayTest ping to check |
| Relay clicks but device doesn't turn on | Wiring on relay output side (COM/NO) | For lights: wire LIVE → COM, NO → Light. Neutral direct to light |
| Relay chatters (clicks rapidly) | Insufficient power to relay coil | Use external 5V supply for relay VCC, not ESP Vin |
| Works for a while then stops | WiFi drops / ESP overheating | Add WiFi.setSleep(false); (already in firmware), ensure ventilation |
| "No response" on physical test | GPIO pin is input-only or used by flash | Change to a safe GPIO (see board table in §1) |
| Relay triggers in reverse | Active HIGH relay (rare) | Change activeLow to false for that device in firmware |
| Only some relays work | Loose jumper wire | Reseat DuPont/jumper wires, try different GPIO |
| ESP keeps rebooting | Drawing too much current from GPIO | Never power relay coil from GPIO — always from VCC/5V |
Serial Monitor Debugging
Open Arduino IDE → Tools → Serial Monitor (115200 baud) to see:
[WiFi] Connecting... Done!
IP:192.168.1.42
[MQTT] Connecting... OK! ← or [WS] Client connected!
[TEST] Pulsed d1 ← Physical test triggered
[MQTT] d1 → ON ← Device command received
If you don't see these messages, check:
- Correct board selected in Arduino IDE
- Correct COM port / USB port
- Baud rate is 115200
7. Adding More Relay Channels
To control more devices, just add entries to the DEVICES[] array.
ESP32 — Up to 8 channels
const DevicePin DEVICES[] = {
{ "d1", 2, true }, // GPIO2 — Relay 1 (Living Room Light)
{ "d4", 4, true }, // GPIO4 — Relay 2 (Bedroom Light)
{ "d8", 5, true }, // GPIO5 — Relay 3 (Kitchen Light)
{ "d2", 18, true }, // GPIO18 — Relay 4 (Fan)
// Add more (safe ESP32 GPIOs):
{ "d10", 19, true }, // GPIO19 — Relay 5
{ "d11", 21, true }, // GPIO21 — Relay 6
{ "d12", 22, true }, // GPIO22 — Relay 7
{ "d13", 23, true }, // GPIO23 — Relay 8
};
// Physical switch pins (ESP32): 32, 33, 25, 26
ESP8266 — Up to 4 channels
⚠️ ESP8266 does NOT have GPIO 18, 19, 21, 22, 23. Use the pins below.
const DevicePin DEVICES[] = {
{ "d1", 5, true }, // D1 (GPIO5) — Relay 1 (Living Room Light)
{ "d2", 4, true }, // D2 (GPIO4) — Relay 2 (Bedroom Light)
{ "d3", 14, true }, // D5 (GPIO14) — Relay 3 (Kitchen Light)
{ "d4", 12, true }, // D6 (GPIO12) — Relay 4 (Fan)
};
// Physical switch pins (ESP8266): 10(SD3), 0(D3/FLASH), 13(D7), 3(RX)
// ⚠️ GPIO 0 is FLASH button — hold LOW to enter flash mode
// ⚠️ GPIO 3 (RX) blocks serial upload — disconnect when flashing
ESP32-S3 / C3 / C6
const DevicePin DEVICES[] = {
{ "d1", 4, true }, // GPIO4 — Relay 1
{ "d2", 5, true }, // GPIO5 — Relay 2
{ "d3", 6, true }, // GPIO6 — Relay 3
{ "d4", 7, true }, // GPIO7 — Relay 4
};
// Avoid: GPIO 0 (boot), GPIO 2 (may be USB on S3), GPIO 19-20 (USB on S3)
- The
idmust match the device ID in the Fantom Interio app - Pick safe GPIOs from the table in §1
- Use
activeLow: truefor standard relay modules (active LOW trigger)
8. Quick Reference Card
┌─────────────────────────────────────────────────────┐
│ ESP ↔ RELAY QUICK REFERENCE │
├─────────────────────────────────────────────────────┤
│ │
│ ESP Vin (5V) ────────── Relay VCC │
│ ESP GND ────────── Relay GND │
│ ESP GPIO X ────────── Relay IN1 │
│ ESP GPIO Y ────────── Relay IN2 │
│ ... ... │
│ │
│ Relay COM ─── Live wire (from switch/mains) │
│ Relay NO ─── To device (light/fan) │
│ │
│ activeLow = true → LOW = relay ON (typical) │
│ activeLow = false → HIGH = relay ON (SSR) │
│ │
│ Board │ Relay GPIOs │ Switch GPIOs │
│ ─────────────┼──────────────────┼─────────────────│
│ ESP32 │ 2, 4, 5, 18 │ 32, 33, 25, 26 │
│ ESP8266 │ 5, 4, 14, 12 │ 10, 0, 13, 3 │
│ ESP32-S3/C3 │ 4, 5, 6, 7 │ 8, 9, 10, 11 │
│ │
│ Test: Fantom Interio App → Smart Home Hub → ⚡ Flash │
│ → 🚀 Smart Connect → Relay Health Check │
│ │
└─────────────────────────────────────────────────────┘