Relay board on an Arduino Uno
A four-channel relay board chasing four lamps from pins 2 to 5. Active low, so LOW is on, and the pins are written HIGH before they become outputs. The whole build, an Arduino Uno and 9 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.
Teaching? Assign it to your class in one click.
Intermediate About 15 minutes to build and run. Runs in your browser. Free, and no account needed.
The parts retail for about $36. On Mokxi they're free.
What you'll learn
- Why a pin cannot switch a load directly, but a relay can
- Active low inputs: LOW is on
- Writing a pin HIGH before making it an output
- COM, NO and NC contacts on a relay
- Hiding hardware details inside a small helper function
- Difficulty: Intermediate
- Time: About 15 minutes
- Board: Arduino Uno R3
- Parts: 13
How it works
The four-channel relay board has one input pin per channel, IN1 to IN4, wired to Arduino pins 2 to 5. Each relay connects supply to one lamp through a 220 ohm resistor and a yellow LED. When a relay clicks on, its lamp lights.
This board is active low. A channel turns on when its pin goes LOW and off when it goes HIGH. The sketch hides that behind relayOn, so the rest of the code can say true for on.
The sketch chases the lamps. Each one lights for 250 ms in order, then a pause of 600 ms follows. The sketch also toggles pins 6, 7 and 8 for a motor demo, which this circuit leaves unwired.
Parts list
13 parts, plus the jumper wires. They retail for about $36; on Mokxi they're free.
- 1 × Arduino Uno R3In Starter Kit, Claw Machine Kit, Vending Machine Kit.
- 1 × Half breadboard
- 1 × Relay board, four channels
- 4 × Resistor, 220 ΩIn Starter Kit, Claw Machine Kit, Halloween Prop Kit.
- 4 × LED, yellowIn Starter Kit, Halloween Prop Kit, Logic Lab Kit.
- 2 × Power
Wiring table
Every connection, pin by pin, read from the circuit itself. Each row joins the pin on the left to the pin on the right, by a jumper wire or a breadboard strip.
| Part and pin | Connects to |
|---|---|
| Relay board, four channels pin IN4 | Arduino Uno R3 pin 5 |
| Relay board, four channels pin IN3 | Arduino Uno R3 pin 4 |
| Relay board, four channels pin IN2 | Arduino Uno R3 pin 3 |
| Relay board, four channels pin IN1 | Arduino Uno R3 pin 2 |
| LED, yellow (1) pin C | Arduino Uno R3 pin GND |
| LED, yellow (2) pin C | Arduino Uno R3 pin GND |
| LED, yellow (3) pin C | Arduino Uno R3 pin GND |
| LED, yellow (4) pin C | Arduino Uno R3 pin GND |
| Relay board, four channels pin GND | Ground |
| Relay board, four channels pin VCC | Supply |
| Resistor, 220 Ω (4) pin 1 | Relay board, four channels pin NO1 |
| Relay board, four channels pin COM1 | Supply |
| Relay board, four channels pin COM2 | Supply |
| Relay board, four channels pin COM3 | Supply |
| Relay board, four channels pin COM4 | Supply |
| Resistor, 220 Ω (3) pin 1 | Relay board, four channels pin NO2 |
| Resistor, 220 Ω (2) pin 1 | Relay board, four channels pin NO3 |
| Resistor, 220 Ω (1) pin 1 | Relay board, four channels pin NO4 |
| LED, yellow (1) pin A | Resistor, 220 Ω (1) pin 2 |
| LED, yellow (2) pin A | Resistor, 220 Ω (2) pin 2 |
| LED, yellow (3) pin A | Resistor, 220 Ω (3) pin 2 |
| LED, yellow (4) pin A | Resistor, 220 Ω (4) pin 2 |
The code
The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.
// Relay board: three ways to switch things a pin cannot.
//
// pins 2 to 5 IN1 to IN4 of the four-channel board: four lamps
// pins 6, 7 IN1 and IN2 of the two-channel board: motor A both ways
// pin 8 the DPDT relay's transistor, through 1 k: motor B both ways
//
// Two circuits run this sketch: "Relay board" wires the lamps, and "Relays
// reverse a motor" wires the two motors. Whatever a circuit leaves unwired
// is simply a pin toggling with nothing on it.
//
// # Active low
//
// The relay boards are active low: an optocoupler's LED sits between VCC and
// each IN pin, so a channel is ON when its pin is LOW. relayOn() hides that,
// and setup() writes every pin HIGH *before* making it an output, because the
// other order leaves each pin low for an instant and every relay clicks on at
// power-up.
//
// # Two relays make an H bridge
//
// Motor A sits between the two channels' COMs. Each NC is on ground and each
// NO on 5 V. Both released: both ends on ground, which is a brake. Channel 1
// in: that end goes to 5 V and the motor turns. Channel 2 in instead: the
// other way. Both in: both ends on 5 V, a brake again, and never a short,
// because each COM is only ever on one contact.
//
// # One coil, two poles
//
// The DPDT relay does the same with one coil, because its two poles move
// together: the motor between the COMs, the supply crossed over between the
// NOs and the NCs. It is a bare relay, so its 40 mA coil hangs off 5 V
// through a 2N2222, with a 1N4007 across it for the kick.
//
// Relays are slow: 10 ms to pull in, 5 ms to let go. Nothing here asks more of
// them than a few clicks a second.
const int LAMPS[] = {2, 3, 4, 5};
const int MOTOR_A[] = {6, 7};
const int DPDT = 8;
void relayOn(int pin, bool on) {
digitalWrite(pin, on ? LOW : HIGH);
}
void setup() {
for (int pin = 2; pin <= 7; pin++) {
digitalWrite(pin, HIGH); // off, before it is even an output
pinMode(pin, OUTPUT);
}
pinMode(DPDT, OUTPUT);
digitalWrite(DPDT, LOW);
Serial.begin(115200);
Serial.println("Mokxi Uno: relays three ways");
}
void chase() {
for (int i = 0; i < 4; i++) {
relayOn(LAMPS[i], true);
delay(250);
relayOn(LAMPS[i], false);
}
}
void loop() {
Serial.println("motor A forward, motor B forward");
relayOn(MOTOR_A[0], true);
digitalWrite(DPDT, LOW);
chase();
Serial.println("both motors braked");
relayOn(MOTOR_A[0], false);
delay(600);
Serial.println("motor A reverse, motor B reverse");
relayOn(MOTOR_A[1], true);
digitalWrite(DPDT, HIGH);
chase();
relayOn(MOTOR_A[1], false);
delay(600);
}
Code walkthrough
The key functions of the sketch, and what each one does.
relayOn sketch.ino
Takes a pin and true or false. It writes LOW to turn a channel on and HIGH to turn it off. Because the board is active low, this one line is the only place that fact lives. If you swap to an active high board, you change it here and nowhere else.
void relayOn(int pin, bool on) {
digitalWrite(pin, on ? LOW : HIGH);
}setup sketch.ino
For pins 2 to 7 it writes HIGH first and calls pinMode second. The other order would leave each pin LOW for an instant, and every relay would click on at power up. Writing HIGH first keeps them off from the start. Then it sets pin 8 as an output and starts the Serial Monitor.
void setup() {
for (int pin = 2; pin <= 7; pin++) {
digitalWrite(pin, HIGH); // off, before it is even an output
pinMode(pin, OUTPUT);
}
pinMode(DPDT, OUTPUT);
digitalWrite(DPDT, LOW);
Serial.begin(115200);
Serial.println("Mokxi Uno: relays three ways");
}chase sketch.ino
Loops through the four lamp pins in LAMPS. Each lamp is switched on, held for 250 ms, then switched off before the next one starts. Only one lamp is on at a time, so you see a light moving along the row.
void chase() {
for (int i = 0; i < 4; i++) {
relayOn(LAMPS[i], true);
delay(250);
relayOn(LAMPS[i], false);
}
}Troubleshooting
The usual mistakes with this circuit, and the fix for each.
- All lamps are on when the sketch starts, or the logic seems backwards This project
The relay board is active low. LOW turns a channel on. UserelayOninstead of callingdigitalWritewith HIGH to mean on. - A relay clicks but its lamp stays dark This project
Check that the lamp wire goes from NO, not NC, through the resistor to the LED anode, and that the LED cathode reaches ground. COM needs the supply. - The lamps light in the wrong order This project
IN1 to IN4 must go to pins 2 to 5 in that order, matching theLAMPSlist. - The relay clicks on at startup, or does the opposite of what the code says. Relay board
These boards are active low: LOW turns the relay on and HIGH turns it off. Set the pin HIGH before pinMode OUTPUT so the relay does not pulse on at boot. - The board resets or relays chatter when they switch. Relay board
Power the relay coils from a separate 5 V supply that can handle all four (about 70 mA each), and join the grounds. Mains loads are dangerous, so use low voltage for learning. - The LED is dim, burns out, or the pin reads wrong because the resistor value is off. Resistor
Read the color bands again. A 220 ohm to 330 ohm resistor suits a typical LED on 5 V. 10k is a common pull-up or pull-down value. Check with a multimeter if unsure. - A pull-up or pull-down resistor is missing, so the input floats and reads random values. Resistor
Tie the input to 5 V or ground through about 10k. Or use INPUT_PULLUP and wire the switch to ground. - The LED does not light, or it lights once and then dies. LED
LEDs have polarity. The longer leg (anode) goes toward the positive side. Always add a series resistor, about 220 ohms to 1 k ohm on a 5 V pin.
Change it and keep it
Open it in the editor, change the circuit or the code, and keep your version in a free account.