EthicsComputerCourses
Join training +91 90532 10052

Relay Modules & DC Motors with Drivers

IoT & Arduino · Lesson 21 of 29 Intermediate 8 min read Updated

By the end of this lesson you will be able to switch a small 5 V water pump on and off with a relay module, read a relay's terminals correctly, and control a DC motor's speed and direction with a motor driver. You will also understand why an Arduino pin must never power a motor directly.

These skills move your projects from blinking lights to things that actually do work: pumps that water plants, fans that cool, and wheels that drive a robot.

Why a pin cannot drive a motor

An UNO R4 pin can handle about 8 mA. A small DC motor or pump needs a hundred milliamps or more just to run, and much more to start. Motors also misbehave electrically: when the current through a coil is switched off, the collapsing magnetic field produces a voltage spike, called back-EMF or an inductive kick, that can destroy a pin.

So we always use a middleman. Think of it as a railway signal cabin. The signal operator (the Arduino pin) moves a small lever. That lever controls the heavy points on the track (the motor current), which come from a completely separate source of power.

MiddlemanWhat it switchesBest for
Relay moduleOn/off only, with an isolated mechanical switchPumps, small DC loads, slow switching
MOSFET moduleOn/off and fast PWM, one directionLED strips, fans, pump speed
Motor driver (H-bridge)Speed and both directionsRobot wheels, motors that reverse

Part 1: Relay modules

A relay is a switch flipped by an electromagnet. When current flows through its coil, a small metal arm is pulled across and the switch contacts change position. The coil side and the contact side are not electrically connected, so the controlled circuit is isolated from the Arduino.

A relay module adds everything needed to drive the coil safely from a pin: a transistor, a protection diode across the coil (the flyback diode), and an LED. Many also have an optocoupler, which passes the signal using light for extra isolation.

TerminalNameConnection when the relay is offWhen on
COMCommonConnected to NCConnected to NO
NONormally openNot connectedConnected to COM
NCNormally closedConnected to COMNot connected

For a pump that should run only when commanded, use COM and NO. Then if the Arduino crashes, loses power or is unplugged, the pump stops. That is a safe default.

Step 1: Wire a 5 V pump through a relay module

PartPin or terminalConnects to
Relay moduleVCCArduino 5V
Relay moduleGNDArduino GND
Relay moduleINArduino D7
Pump supply (5 V USB power bank or adapter, separate from the Arduino)+Relay COM
Relay moduleNOPump red wire (+)
PumpBlack wire (-)Pump supply -

The pump's current never passes through the Arduino. Keep the pump supply's + wire away from the Arduino's pins. Check the pump's current rating in its listing, and make sure your supply can provide it with room to spare.

Step 2: Check whether your module is active LOW

Many relay modules switch on when IN is LOW. Find out before connecting the pump: run this sketch and listen for the click and watch the module's LED.

C++
const int RELAY_PIN = 7;
const bool ACTIVE_LOW = true;     // change to false if your module is active HIGH

void relayOn()  { digitalWrite(RELAY_PIN, ACTIVE_LOW ? LOW : HIGH); }
void relayOff() { digitalWrite(RELAY_PIN, ACTIVE_LOW ? HIGH : LOW); }

void setup() {
  pinMode(RELAY_PIN, OUTPUT);
  relayOff();                      // safe state first
  Serial.begin(9600);
  while (!Serial && millis() < 3000) { }
  Serial.println("relay OFF");
}

void loop() {
  relayOn();
  Serial.println("relay ON");
  delay(2000);
  relayOff();
  Serial.println("relay OFF");
  delay(2000);
}
Output
relay OFF
relay ON
relay OFF
relay ON
relay OFF

If the relay LED is lit when the monitor says OFF, your module is active HIGH: set ACTIVE_LOW to false. Hiding the logic in relayOn() and relayOff() means the rest of your code never has to think about it.

Step 3: Run the pump for a fixed time, safely

A pump should never run without a limit. This function runs it for a requested time but never beyond a hard maximum, using the guard idea from Electronics Safety First:

C++
const int RELAY_PIN = 7;
const unsigned long PUMP_MAX_MS = 8000;   // hard limit

void relayOn()  { digitalWrite(RELAY_PIN, LOW); }    // active-low module
void relayOff() { digitalWrite(RELAY_PIN, HIGH); }

unsigned long pumpFor(unsigned long ms) {
  if (ms > PUMP_MAX_MS) ms = PUMP_MAX_MS;   // clip unsafe requests
  relayOn();
  delay(ms);                                 // fine for a short, simple test
  relayOff();
  return ms;
}

void setup() {
  pinMode(RELAY_PIN, OUTPUT);
  relayOff();
  Serial.begin(9600);
  while (!Serial && millis() < 3000) { }
  Serial.print("Pumped for ");
  Serial.print(pumpFor(3000));
  Serial.println(" ms");
  Serial.print("Pumped for ");
  Serial.print(pumpFor(60000));
  Serial.println(" ms");
}

void loop() {
}
Output
Pumped for 3000 ms
Pumped for 8000 ms

The second request asked for a full minute, but the guard cut it to 8 seconds. Never let a pump run dry: it overheats. In the final project, the pump also stops if the water tank is empty.

Part 2: DC motors with a driver

A DC motor spins one way when current flows one way, and the other way when the current is reversed. Speed depends on the average voltage, which PWM controls. To do both, you need an H-bridge: four electronic switches arranged like the letter H around the motor, so current can be sent either way. A motor driver chip contains the H-bridge plus protection.

DriverNotes
TB6612FNGModern, efficient MOSFET driver for two small motors; a good choice for kits and robots
DRV8833Similar modern low-voltage dual driver
L298NOlder and very common in Indian kits; works, but wastes around 2 V or more as heat and gets warm

Step 4: Wire a TB6612FNG

PartPinConnects to
TB6612FNGVM (motor power)Battery pack + (for example 4 × AA, 6 V)
TB6612FNGVCC (logic power)Arduino 5V
TB6612FNGGND (all GND pins)Battery - and Arduino GND (common ground)
TB6612FNGPWMAArduino D5 (PWM)
TB6612FNGAIN1Arduino D4
TB6612FNGAIN2Arduino D3
TB6612FNGSTBYArduino D8 (HIGH = driver enabled)
TB6612FNGAO1, AO2The two motor wires

The driver's datasheet truth table, simplified:

AIN1AIN2Motor
HIGHLOWTurns one way (call it forward)
LOWHIGHTurns the other way
HIGHHIGHShort brake: stops quickly
LOWLOWCoasts to a stop

Step 5: Speed and direction in one function

A single number from -255 to 255 can describe both: the sign gives the direction and the size gives the speed.

C++
const int MOTOR_PWM = 5, MOTOR_IN1 = 4, MOTOR_IN2 = 3, MOTOR_STBY = 8;

void setMotor(int speed) {             // -255 .. 255
  speed = constrain(speed, -255, 255);
  bool forward = speed >= 0;
  digitalWrite(MOTOR_IN1, forward ? HIGH : LOW);
  digitalWrite(MOTOR_IN2, forward ? LOW : HIGH);
  analogWrite(MOTOR_PWM, abs(speed));
  Serial.print("speed ");
  Serial.print(speed);
  Serial.print(": AIN1=");
  Serial.print(forward ? 1 : 0);
  Serial.print(" AIN2=");
  Serial.print(forward ? 0 : 1);
  Serial.print(" PWM=");
  Serial.println(abs(speed));
}

void setup() {
  pinMode(MOTOR_PWM, OUTPUT);
  pinMode(MOTOR_IN1, OUTPUT);
  pinMode(MOTOR_IN2, OUTPUT);
  pinMode(MOTOR_STBY, OUTPUT);
  digitalWrite(MOTOR_STBY, HIGH);            // enable the driver
  Serial.begin(9600);
  while (!Serial && millis() < 3000) { }
  setMotor(200);  delay(2000);         // forward, fast
  setMotor(-120); delay(2000);         // reverse, slower
  setMotor(300);  delay(2000);         // too big: clipped to 255
  setMotor(0);                         // stop
}

void loop() {
}
Output
speed 200: AIN1=1 AIN2=0 PWM=200
speed -120: AIN1=0 AIN2=1 PWM=120
speed 255: AIN1=1 AIN2=0 PWM=255
speed 0: AIN1=1 AIN2=0 PWM=0

The motor runs forward fast, reverses slower, runs at full speed, then stops (PWM 0). Very low PWM values may only make the motor hum, because it needs a minimum voltage to start turning.

Common mistakes

  • Powering a motor or pump from the Arduino 5V pin. Use a separate supply and a common GND.
  • Using NC for a pump. If the Arduino fails, the pump would run. Use NO.
  • Not checking active LOW or HIGH. The relay works backwards, and the pump runs at start-up.
  • Forgetting STBY on the TB6612FNG. If it is LOW, the motor never moves.
  • Wiring mains to a relay module. Never. Use certified products and a qualified electrician.

Key points

  • Pins give signals, not power; relays, MOSFET modules and motor drivers switch the real current.
  • A relay module's COM-NO contacts close only when the relay is on, which is the safe choice for pumps.
  • Hide active LOW logic inside relayOn() and relayOff(), set it off first, and limit run times.
  • An H-bridge driver such as the TB6612FNG controls direction (AIN1/AIN2) and speed (PWM).
  • Motor supplies and the Arduino must share GND; this course never switches mains.

Exercise

Write rampTo(int target) for the TB6612FNG setup. It should change the motor speed from the current speed to target in steps of 50, calling setMotor() at each step with a 100 ms pause, and finish exactly at target. Starting from 0, what lines are printed for rampTo(180)?

Show solution
C++
int currentSpeed = 0;

void rampTo(int target) {
  while (currentSpeed != target) {
    if (currentSpeed < target) currentSpeed = min(currentSpeed + 50, target);
    else currentSpeed = max(currentSpeed - 50, target);
    setMotor(currentSpeed);              // setMotor() from Step 5
    delay(100);
  }
}

Calling rampTo(180) from 0 prints:

Output
speed 50: AIN1=1 AIN2=0 PWM=50
speed 100: AIN1=1 AIN2=0 PWM=100
speed 150: AIN1=1 AIN2=0 PWM=150
speed 180: AIN1=1 AIN2=0 PWM=180

min() stops the last step at exactly 180 instead of overshooting to 200. Gentle ramps reduce current spikes and are kinder to gears.

Quick Quiz

1. Which relay terminals should a pump use, so it stops if the Arduino fails?

2. Why can't an Arduino pin drive a DC motor directly?

3. On a TB6612FNG, AIN1 is LOW and AIN2 is HIGH. What does the motor do?

4. A project must switch a 230 V ceiling fan. What does this course recommend?

Learn IoT & Arduino with a mentor

Free lessons get you started. Our IoT & Embedded Systems training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call