Community project
ESP32 Eight-Channel Relay Tester
This guide builds an eight-channel relay tester that validates each relay independently using an ESP32 microcontroller. The tester uses NPN transistors as low-side switches to control a JD-VCC relay module, allowing safe verification of relay operation without connecting any load circuits. Readers will receive a complete wiring diagram, parts list, and step-by-step assembly instructions.
The firmware cycles through each relay channel, energizing them one at a time and logging results to the serial monitor. This systematic approach makes it easy to identify any faulty relays or wiring issues before deploying the module in a real application. No external load or mains power is required—just the ESP32, relay module, transistors, resistors, and a regulated 5 V power supply.
Wiring diagram

Gather all the parts
Assemble it in 6 steps
1. Leave the relay screw terminals empty for the first test
Do not connect lamps, motors, wall power, or any other load to the relay screw terminals yet. This first test only checks that each relay clicks and its small channel light turns on.
- Place the relay module where you can see all eight small channel indicator lights.
- Do not put wall power on the relay terminals while learning this test — a wiring mistake can cause electric shock, fire, or damage.
2. Place the eight resistors and transistors
Put the eight 1 kΩ resistors and eight 2N2222 transistors on a breadboard, leaving space between each channel. Keep each resistor with its matching transistor: R1 with Q1 through R8 with Q8. Before wiring, check the data sheet or package marking for your exact transistor’s flat-side pin order; different 2N2222 package styles can have different leg orders. Identify the base, collector, and emitter before applying power.
- Mark the transistor channels 1 through 8 with tape so the matching wires do not get mixed up.
- Putting a transistor in with the wrong legs connected can prevent the relay from working and can stress the ESP32 output pin.
3. Wire the eight ESP32 control paths
With the ESP32 unplugged, wire GPIO16 → R1 → Q1 base (control), GPIO17 → R2 → Q2 base (control), GPIO18 → R3 → Q3 base (control), GPIO19 → R4 → Q4 base (control), GPIO21 → R5 → Q5 base (control), GPIO22 → R6 → Q6 base (control), GPIO23 → R7 → Q7 base (control), and GPIO25 → R8 → Q8 base (control). Each resistor must be in series between its ESP32 pin and transistor base; it limits the small control current.
- A resistor has no positive or negative end, so either leg can face the ESP32.
- Do not connect an ESP32 GPIO straight to a transistor base without its 1 kΩ resistor — the resistor protects the ESP32 pin.
4. Connect the transistor outputs to the relay inputs
Connect Q1 collector → relay IN1 (signal), Q2 collector → IN2 (signal), Q3 collector → IN3 (signal), Q4 collector → IN4 (signal), Q5 collector → IN5 (signal), Q6 collector → IN6 (signal), Q7 collector → IN7 (signal), and Q8 collector → IN8 (signal). Connect every transistor emitter → ESP32 GND (ground). These transistors pull a relay input down to ground to turn its channel on.
- Keep the channel numbers matched from resistor to transistor to relay input; this makes the click sequence easy to verify.
- Do not connect the relay’s 5 V VCC terminal to any ESP32 GPIO or to the ESP32 3V3 terminal — 5 V on an ESP32 signal pin can damage it.
5. Power the relay board from the external 5 V supply
Connect external supply +5V → relay VCC (relay input-side power) and external supply +5V → relay JD-VCC (relay coil power). Connect external supply GND → relay GND (ground) and external supply GND → ESP32 GND (shared ground). If the module has a VCC-to-JD-VCC jumper fitted, remove it before making these two separate +5 V connections. The ESP32 remains powered from its USB cable.
- Use a regulated 5 V supply rated for at least 2 A because all eight relays can be switched on together during the test.
- Make sure +5 V and GND are not swapped — swapped power can damage the relay board. Do not feed the external 5 V supply into the ESP32 3V3 pin.
6. Run the relay click test
Plug the ESP32 into USB, then turn on the external 5 V relay supply. Press Schematik’s Deploy button. The program switches relay 1 through relay 8 on one at a time, then turns all eight on briefly before repeating.
- You should hear one click at a time and see the matching relay indicator light. The serial output names the channel currently being tested.
- If a relay stays on unexpectedly, unplug the ESP32 USB cable and turn off the external 5 V supply before changing wires.
Review all connections
1. Connections between "supply5v_1" and "ESP32"
2. Connections between "relay8_1" and "ESP32"
3. Connections between "q1" and "ESP32"
4. Connections between "q2" and "ESP32"
5. Connections between "q3" and "ESP32"
6. Connections between "q4" and "ESP32"
7. Connections between "q5" and "ESP32"
8. Connections between "q6" and "ESP32"
9. Connections between "q7" and "ESP32"
10. Connections between "q8" and "ESP32"
11. Connections between "r1" and "ESP32"
12. Connections between "r2" and "ESP32"
13. Connections between "r3" and "ESP32"
14. Connections between "r4" and "ESP32"
15. Connections between "r5" and "ESP32"
16. Connections between "r6" and "ESP32"
17. Connections between "r7" and "ESP32"
18. Connections between "r8" and "ESP32"
Deploy the firmware
#include <Arduino.h>
// ESP32 eight-channel relay test through eight 2N2222 transistor switches.
// Each ESP32 HIGH passes through a 1 kΩ base resistor, turns its 2N2222 on,
// and pulls the matching active-low relay input to ground.
// Forward declarations
void setAllRelays(bool on);
const uint8_t RELAY_1_PIN = 16;
const uint8_t RELAY_2_PIN = 17;
const uint8_t RELAY_3_PIN = 18;
const uint8_t RELAY_4_PIN = 19;
const uint8_t RELAY_5_PIN = 21;
const uint8_t RELAY_6_PIN = 22;
const uint8_t RELAY_7_PIN = 23;
const uint8_t RELAY_8_PIN = 25;
const uint8_t relayPins[] = {
RELAY_1_PIN, RELAY_2_PIN, RELAY_3_PIN, RELAY_4_PIN,
RELAY_5_PIN, RELAY_6_PIN, RELAY_7_PIN, RELAY_8_PIN
};
const uint8_t RELAY_COUNT = sizeof(relayPins) / sizeof(relayPins[0]);
const unsigned long RELAY_ON_MS = 700;
const unsigned long GAP_MS = 300;
const unsigned long ALL_ON_MS = 1000;
const unsigned long ROUND_PAUSE_MS = 3000;
void setAllRelays(bool on) {
for (uint8_t i = 0; i < RELAY_COUNT; i++) {
digitalWrite(relayPins[i], on ? HIGH : LOW);
}
}
void setup() {
Serial.begin(115200);
for (uint8_t i = 0; i < RELAY_COUNT; i++) {
pinMode(relayPins[i], OUTPUT);
digitalWrite(relayPins[i], LOW); // Transistor off: relay input stays high, relay off.
}
Serial.println("8-channel relay test ready. No mains load is required for this test.");
}
void loop() {
for (uint8_t i = 0; i < RELAY_COUNT; i++) {
Serial.printf("Testing relay %u\n", i + 1);
digitalWrite(relayPins[i], HIGH);
delay(RELAY_ON_MS);
digitalWrite(relayPins[i], LOW);
delay(GAP_MS);
}
Serial.println("Testing all relays together");
setAllRelays(true);
delay(ALL_ON_MS);
setAllRelays(false);
Serial.println("Round complete; all relays off.");
delay(ROUND_PAUSE_MS);
}Remix this project
Make it yours in one click
Open a full copy of this project in your own Schematik workspace — diagram, code, parts, and assembly steps included. Swap the sensor, add features, or redesign the whole thing with AI. The author's original stays untouched.




