Arduino - DC Motor Shield

This tutorial instructs you how to control a DC motor using Arduino with the Motor Shield Rev3. In detail, we will learn:

Arduino DC Motor Shield

About Motor Shield Rev3

The Arduino Motor Shield Rev3 is based on the L298P dual full-bridge driver IC, which allows you to drive two DC motors (or one stepper motor) with full control over direction, speed, and braking.

The shield provides the following features:

  • Two motor channels (A and B): Each channel can independently drive one DC motor.
  • Direction control: Set the motor to spin forward or backward using a digital pin.
  • PWM speed control: Adjust the motor speed from 0 to 255 using a PWM pin.
  • Brake control: Engage or release the brake on each channel using a digital pin.
  • Current sensing: Read the current drawn by each motor via analog pins.

The Motor Shield Rev3 is designed for the Arduino Uno form factor and stacks directly on top of the Arduino board - no breadboard or complex wiring needed.

Pin Mapping

Function Channel A Channel B
Direction D12 D13
PWM (Speed) D3 D11
Brake D9 D8
Current Sensing A0 A1

External Power

The Motor Shield Rev3 requires an external power source for the motors. Connect your power source (6-12V) to the power screw terminals on the shield. The power from the external source drives the motors, while the Arduino can be powered separately via USB or its own power supply.

Wiring Diagram

First, mount the Arduino Motor Shield Rev3 on top of the Arduino Uno, aligning the pins carefully.

Then, connect the DC motor to Channel A using the screw terminals on the shield. The channels are marked next to the screw terminals.

Finally, connect the external power source (e.g., 2x 3.7V Li-Ion batteries) to the power screw terminals on the shield.

Arduino DC Motor Shield wiring diagram

This image is created using Fritzing. Click to enlarge image

Library Installation

  • Connect the Arduino board to your computer with a USB cable.
  • Open Arduino IDE, select the right board and port.
  • Navigate to the Libraries icon on the left bar of the Arduino IDE.
  • Search "DIYables_DC_Motor", then find the DIYables_DC_Motor library by DIYables.
  • Click Install button to install the latest version of the library.
Arduino DC Motor Shield library

Note: This library is self-contained with no external dependencies.

Basic Structure

Every sketch using the DC Motor library follows this basic structure:

#include <DIYables_DC_Motor.h> DIYables_DC_Motor motor(MOTOR_CH_A); // Use Channel A void setup() { motor.begin(); // Initialize motor pins } void loop() { motor.run(MOTOR_FORWARD, 100); // Run forward at speed 100 delay(2000); motor.brake(); // Stop the motor delay(1000); }

motor.begin() initializes the direction, PWM, and brake pins. After that, use motor.run() to set direction and speed, and motor.brake() to stop the motor. No loop() call on the motor object is needed - the motor runs continuously until you change its state.

Arduino Code - Channel A Motor Control

The following code demonstrates how to control a DC motor on Channel A: alternating direction every 2 seconds with braking in between.

/* * Created by ArduinoGetStarted.com * * This example code is in the public domain * * Tutorial page: https://arduinogetstarted.com/tutorials/arduino-dc-motor-shield */ /* * DIYables_DC_Motor - ChannelA Example * * This example demonstrates how to control a DC motor connected to * Channel A of the Arduino Motor Shield Rev3. The motor alternates * direction every 2 seconds with braking in between. * * Channel A pins: D12 (Direction), D3 (PWM), D9 (Brake), A0 (Current) * * Tutorial: https://diyables.io/motor-shield * * TESTED HARDWARE: * - Arduino Uno R3 * - Arduino Uno R4 WiFi * - Arduino Uno R4 Minima * - Arduino Mega * - Arduino Due * - Arduino Giga * - DIYables STEM V3: https://diyables.io/stem-v3 * - DIYables STEM V4 IoT: https://diyables.io/stem-v4-iot * - DIYables STEM V4B IoT: https://diyables.io/stem-v4b-iot * - DIYables STEM V4B Edu: https://diyables.io/stem-v4-edu * - DIYables MEGA2560 R3: https://diyables.io/atmega2560-board * - It is expected to work with other boards */ #include <DIYables_DC_Motor.h> DIYables_DC_Motor motor(MOTOR_CH_A); bool directionState = false; void setup() { Serial.begin(9600); motor.begin(); Serial.println("Motor Shield - Channel A"); } void loop() { // Toggle direction each cycle directionState = !directionState; int direction = directionState ? MOTOR_FORWARD : MOTOR_BACKWARD; // Run motor with speed 30 (out of 255) motor.run(direction, 30); Serial.print("Running "); Serial.println(directionState ? "FORWARD" : "BACKWARD"); delay(2000); // Brake the motor motor.brake(); Serial.println("Braking"); delay(2000); }

Quick Steps

  • Mount the Motor Shield Rev3 on the Arduino board.
  • Connect the DC motor to Channel A screw terminals.
  • Connect the external power source.
  • Connect the Arduino board to your computer with a USB cable.
  • Open Arduino IDE, select the right board and port.
  • Copy the above code and paste it to the editor of Arduino IDE.
  • Click Upload button on Arduino IDE to upload code to Arduino.
  • Open the Serial Monitor to see the motor status messages.

The motor spins forward for 2 seconds at speed 30, brakes for 2 seconds, then spins backward for 2 seconds, and repeats.

Motor API Summary

Method Description Example
run(direction, speed) Set direction and speed, release brake motor.run(MOTOR_FORWARD, 100)
setSpeed(speed) Set PWM speed (0-255) motor.setSpeed(150)
setDirection(direction) Set direction only motor.setDirection(MOTOR_BACKWARD)
brake() Activate brake and set speed to 0 motor.brake()
release() Release brake motor.release()
readCurrent() Read raw ADC from current sensing pin motor.readCurrent()

Arduino Code - Channel B Motor Control

The following code demonstrates how to control a DC motor on Channel B.

/* * Created by ArduinoGetStarted.com * * This example code is in the public domain * * Tutorial page: https://arduinogetstarted.com/tutorials/arduino-dc-motor-shield */ /* * DIYables_DC_Motor - ChannelB Example * * This example demonstrates how to control a DC motor connected to * Channel B of the Arduino Motor Shield Rev3. The motor alternates * direction every 2 seconds with braking in between. * * Channel B pins: D13 (Direction), D11 (PWM), D8 (Brake), A1 (Current) * * Tutorial: https://diyables.io/motor-shield * * TESTED HARDWARE: * - Arduino Uno R3 * - Arduino Uno R4 WiFi * - Arduino Uno R4 Minima * - Arduino Mega * - Arduino Due * - Arduino Giga * - DIYables STEM V3: https://diyables.io/stem-v3 * - DIYables STEM V4 IoT: https://diyables.io/stem-v4-iot * - DIYables STEM V4B IoT: https://diyables.io/stem-v4b-iot * - DIYables STEM V4B Edu: https://diyables.io/stem-v4-edu * - DIYables MEGA2560 R3: https://diyables.io/atmega2560-board * - It is expected to work with other boards */ #include <DIYables_DC_Motor.h> DIYables_DC_Motor motor(MOTOR_CH_B); bool directionState = false; void setup() { Serial.begin(9600); motor.begin(); Serial.println("Motor Shield - Channel B"); } void loop() { // Toggle direction each cycle directionState = !directionState; int direction = directionState ? MOTOR_FORWARD : MOTOR_BACKWARD; // Run motor with speed 30 (out of 255) motor.run(direction, 30); Serial.print("Running "); Serial.println(directionState ? "FORWARD" : "BACKWARD"); delay(2000); // Brake the motor motor.brake(); Serial.println("Braking"); delay(2000); }

Quick Steps

  • Connect the DC motor to Channel B screw terminals (instead of Channel A).
  • Copy the above code and paste it to the editor of Arduino IDE.
  • Click Upload button on Arduino IDE to upload code to Arduino.
  • Open the Serial Monitor.

The behavior is identical to Channel A - the only difference is the channel used.

Arduino Code - Both Channels

The following code demonstrates how to control two DC motors simultaneously, one on each channel.

/* * Created by ArduinoGetStarted.com * * This example code is in the public domain * * Tutorial page: https://arduinogetstarted.com/tutorials/arduino-dc-motor-shield */ /* * DIYables_DC_Motor - BothChannels Example * * This example demonstrates how to control two DC motors simultaneously, * one on Channel A and one on Channel B of the Arduino Motor Shield Rev3. * * Channel A pins: D12 (Direction), D3 (PWM), D9 (Brake), A0 (Current) * Channel B pins: D13 (Direction), D11 (PWM), D8 (Brake), A1 (Current) * * Tutorial: https://diyables.io/motor-shield * * TESTED HARDWARE: * - Arduino Uno R3 * - Arduino Uno R4 WiFi * - Arduino Uno R4 Minima * - Arduino Mega * - Arduino Due * - Arduino Giga * - DIYables STEM V3: https://diyables.io/stem-v3 * - DIYables STEM V4 IoT: https://diyables.io/stem-v4-iot * - DIYables STEM V4B IoT: https://diyables.io/stem-v4b-iot * - DIYables STEM V4B Edu: https://diyables.io/stem-v4-edu * - DIYables MEGA2560 R3: https://diyables.io/atmega2560-board * - It is expected to work with other boards */ #include <DIYables_DC_Motor.h> DIYables_DC_Motor motorA(MOTOR_CH_A); DIYables_DC_Motor motorB(MOTOR_CH_B); void setup() { Serial.begin(9600); motorA.begin(); motorB.begin(); Serial.println("Motor Shield - Both Channels"); } void loop() { // Both motors forward motorA.run(MOTOR_FORWARD, 100); motorB.run(MOTOR_FORWARD, 100); Serial.println("Both FORWARD"); delay(2000); // Brake both motors motorA.brake(); motorB.brake(); Serial.println("Both BRAKING"); delay(1000); // Both motors backward motorA.run(MOTOR_BACKWARD, 100); motorB.run(MOTOR_BACKWARD, 100); Serial.println("Both BACKWARD"); delay(2000); // Brake both motors motorA.brake(); motorB.brake(); Serial.println("Both BRAKING"); delay(1000); // Motors in opposite directions motorA.run(MOTOR_FORWARD, 150); motorB.run(MOTOR_BACKWARD, 150); Serial.println("A FORWARD, B BACKWARD"); delay(2000); // Brake both motors motorA.brake(); motorB.brake(); Serial.println("Both BRAKING"); delay(1000); }

Quick Steps

  • Connect one DC motor to Channel A and another to Channel B.
  • Copy the above code and paste it to the editor of Arduino IDE.
  • Click Upload button on Arduino IDE to upload code to Arduino.
  • Open the Serial Monitor.

Both motors run forward together, then backward together, then in opposite directions - with braking pauses in between.

Arduino Code - Current Sensing

The following code demonstrates how to read the current drawn by a DC motor using the built-in current sensing pin.

/* * Created by ArduinoGetStarted.com * * This example code is in the public domain * * Tutorial page: https://arduinogetstarted.com/tutorials/arduino-dc-motor-shield */ /* * DIYables_DC_Motor - CurrentSensing Example * * This example demonstrates how to read the current drawn by a DC motor * connected to Channel A of the Arduino Motor Shield Rev3. * * The Motor Shield Rev3 provides current sensing via analog pins: * Channel A: A0 * Channel B: A1 * * Tutorial: https://diyables.io/motor-shield * * TESTED HARDWARE: * - Arduino Uno R3 * - Arduino Uno R4 WiFi * - Arduino Uno R4 Minima * - Arduino Mega * - Arduino Due * - Arduino Giga * - DIYables STEM V3: https://diyables.io/stem-v3 * - DIYables STEM V4 IoT: https://diyables.io/stem-v4-iot * - DIYables STEM V4B IoT: https://diyables.io/stem-v4b-iot * - DIYables STEM V4B Edu: https://diyables.io/stem-v4-edu * - DIYables MEGA2560 R3: https://diyables.io/atmega2560-board * - It is expected to work with other boards */ #include <DIYables_DC_Motor.h> DIYables_DC_Motor motor(MOTOR_CH_A); void setup() { Serial.begin(9600); motor.begin(); Serial.println("Motor Shield - Current Sensing"); } void loop() { // Run motor forward motor.run(MOTOR_FORWARD, 100); // Read and print current sensing value int current = motor.readCurrent(); Serial.print("Current sensing (raw ADC): "); Serial.println(current); delay(500); }

Quick Steps

  • Connect a DC motor to Channel A.
  • Copy the above code and paste it to the editor of Arduino IDE.
  • Click Upload button on Arduino IDE to upload code to Arduino.
  • Open the Serial Monitor.
  • Observe the raw ADC current sensing value updating every 500 ms.

Current Sensing Notes

The Motor Shield Rev3 provides current sensing through analog pins A0 (Channel A) and A1 (Channel B). The readCurrent() method returns a raw ADC value. To convert to actual current (in amps), you need to apply the appropriate conversion factor based on the shield's current sensing circuitry.

Arduino Code - Custom Pins

The following code demonstrates how to create a motor object with custom pin assignments instead of using the predefined channel constants.

/* * Created by ArduinoGetStarted.com * * This example code is in the public domain * * Tutorial page: https://arduinogetstarted.com/tutorials/arduino-dc-motor-shield */ /* * DIYables_DC_Motor - CustomPins Example * * This example demonstrates how to create a motor object with * custom pin assignments instead of using the predefined channels. * * Tutorial: https://diyables.io/motor-shield * * TESTED HARDWARE: * - Arduino Uno R3 * - Arduino Uno R4 WiFi * - Arduino Uno R4 Minima * - Arduino Mega * - Arduino Due * - Arduino Giga * - DIYables STEM V3: https://diyables.io/stem-v3 * - DIYables STEM V4 IoT: https://diyables.io/stem-v4-iot * - DIYables STEM V4B IoT: https://diyables.io/stem-v4b-iot * - DIYables STEM V4B Edu: https://diyables.io/stem-v4-edu * - DIYables MEGA2560 R3: https://diyables.io/atmega2560-board * - It is expected to work with other boards */ #include <DIYables_DC_Motor.h> // Custom pin assignment: direction=12, pwm=3, brake=9, currentSensing=A0 DIYables_DC_Motor motor(12, 3, 9, A0); bool directionState = false; void setup() { Serial.begin(9600); motor.begin(); Serial.println("Motor Shield - Custom Pins"); } void loop() { // Toggle direction each cycle directionState = !directionState; int direction = directionState ? MOTOR_FORWARD : MOTOR_BACKWARD; // Run motor motor.run(direction, 30); Serial.print("Running "); Serial.println(directionState ? "FORWARD" : "BACKWARD"); delay(2000); // Brake the motor motor.brake(); Serial.println("Braking"); delay(2000); }

Quick Steps

  • Adjust the pin numbers in the constructor to match your wiring.
  • Copy the above code and paste it to the editor of Arduino IDE.
  • Click Upload button on Arduino IDE to upload code to Arduino.

This approach is useful when using a non-standard motor driver or a modified pin configuration.

Troubleshoot

If the code is not working, there are some common issues you can troubleshoot:

  • Motor not spinning: Check that the motor is properly connected to the correct channel's screw terminals.
  • Wrong channel: Make sure the pin definitions in your code match the channel you connected the motor to (Channel A or Channel B).
  • No power: Verify that the external power source is connected and working. The motor needs external power - USB alone is not enough for motor operation.
  • Weak or no rotation: Increase the speed value in setSpeed() or run(). A very low speed (e.g., below 20) may not be enough to overcome the motor's starting torque.
  • Direction reversed: Simply swap the two motor wires on the screw terminal, or change MOTOR_FORWARD to MOTOR_BACKWARD in your code.

Platform Support

The library uses only Arduino standard APIs (pinMode, digitalWrite, analogWrite, analogRead) and supports all Arduino platforms (architectures=*).

The Best Arduino Starter Kit

※ OUR MESSAGES