DRV8833 – How To Use This Simple Motor Driver FAST!

Published by Dan on

What is a DRV8833?

The DRV8833 is an inexpensive chip used to drive either a pair of brushed motors or a single 4-wire stepper motor. It is the focus of this article because it is available on sites such as Aliexpress, EBay and Amazon on a small, breadboard (and therefore beginner) friendly package and allows you to power small motors easily and efficiently.

DRV8833 Specs

SpecDRV8833
Voltage tolerance3V – 10V
Maximum continuous current (per channel)1.5A
Maximum peak current (per channel)2.0A
Channels2
Over current protectionYES
Low power sleep mode availableYES

Pinout

An image with both the top and bottom of the DRV8833 PCB and the bottom of the PCB is labelled from the factory, the creator of the website labelled the top for ease of use.
PinFunction
EEPEnables or puts the module to sleep – by default we can leave this alone
OUT1Connect to motor A, any pole
OUT2Connect to motor A, any pole
OUT3Connect to motor B, any pole
OUT4Connect to motor B, any pole
ULTCommunicates a fault to the microcontroller – we can ignore this for basic operation
IN1Control for motor A, preferable to use a PWM capable pin on your microcontroller
IN2Control for motor A, preferable to use a PWM capable pin on your microcontroller
VCCConnect to power supply (3V – 10V compliant)
GNDConnect to ground
IN3Control for motor B, preferable to use a PWM capable pin on your microcontroller
IN4Control for motor A, preferable to use a PWM capable pin on your microcontroller

How to wire up the DRV8833 module

For brevity and simplicity, we’re going to leave the EEP and ULT pins disconnected, they are unneeded for basic operation.

The IN pins (1 thru 4) we will want to connect to our microcontroller on pins that can be set as outputs and if we want to vary the speed of the motors we are driving, we have to use pins that are compatible with PWM outputs.

The OUT pins work in pairs, our first motor should be connected to OUT1 & OUT2 – the polarity will not matter at this time, if the motor spins opposite the way you prefer, you can either switch it in the software or physically reconnect the motor opposite of how you connected it. For a second motor, simply connect it to OUT3 & OUT4.

Connect VCC to your power supply, being careful to supply at least 3 Volts and no more than 10 Volts. CAUTION – It is not a good idea to draw this voltage directly from a microcontroller as this voltage will be used to drive the motor(s) directly. Motors require a lot of current to function and under load will almost certainly be more than what the voltage regulator can provide, causing it to overheat and fail.

Connect GND to your power supply’s ground circuit and make sure the microcontroller you are using to control this board is also connected to the same ground. In other words, run a wire from the DRV8833’s ground to your microcontroller’s ground.

How to use the DRV8833 module

The way the module works is quite simple – all the IN pins expect a HIGH (presented with positive voltage) or a LOW (presented with a 0V / ground voltage) and when a pair of IN pins – IN1 & IN2 or IN3 & IN4 – have both a HIGH and a LOW, it will cause one of the motors to spin. See the chart below:

IN1IN2Result
LOWLOWMotor off
HIGHHIGHMotor off
LOWHIGHSpins clockwise
HIGHLOWSpins counterclockwise
Truth table for inputs vs. motor behavior

The chart also works if you replace IN1 & IN2 with IN3 & IN4 and it will apply to the second motor, usually considered to be Motor B

Driving the DRV8833 module from a microcontroller

Time for a practical example! To follow along, you will need:

  • Arduino Uno or clone
  • DRV8833 module
  • 2x N20 motors
  • Breadboard
  • Breadboard power supply

You can find links to these items here

We will wire it up as you see in the diagram and table below:

FromTo
Uno pin 11DRV8833 IN1
Uno pin 10DRV8833 IN2
Uno pin 9DRV8833 IN3
Uno pin 6DRV8833 IN4
Uno 5VPower supply 5V
Uno GNDPower supply ground
DRV8833 VCCPower supply 5V
DRV8833 GNDPower supply ground
DRV8833 OUT1Motor A +
DRV8833 OUT2Motor A –
DRV8833 OUT3Motor B +
DRV8833 OUT4Motor B –
Don’t get caught up on which wire is motor + or -, you can reverse those at will.

Here is the code I have written specifically for this example:

/* This is a simple sketch to allow you to get up and running quickly
 *  with a DRV8833 breakout board. To support my work check out my
 *  YouTube channel; https://www.youtube.com/SimpleElectronics or buy
 *  your DRV8833 using my affiliate link here: 
 *  https://s.click.aliexpress.com/e/_DEvY5zz
 */

// Setting up pins for the DRV8833 board to use as inputs. 
// (11, 10, 9, 6, 5 and 3 are PWM capable on UNO - using a PWM capable pin will
// allow us to control motor speed)

// Setting the 4 "signal" pins for the DRV8833 - sig1 and sig2 control one motor,
// sig3 and sig4 control another.
const int sig1 = 11;
const int sig2 = 10;
const int sig3 = 9;
const int sig4 = 6;


void setup() {
// Setting pinMode to outputs to communicate with the DRV8833 board

pinMode(sig1, OUTPUT);
pinMode(sig2, OUTPUT);
pinMode(sig3, OUTPUT);
pinMode(sig4, OUTPUT);

// Ensure that the output pins are set to a known state (LOW) so the motors don't start on their own
digitalWrite(sig1, LOW);
digitalWrite(sig2, LOW);
digitalWrite(sig3, LOW);
digitalWrite(sig4, LOW);

}

void loop() {
  
/*  This loop just steps between the different ways we can control the motors connected
 *  to the DRV8833 board for a second. Spin motor A counter-clockwise, then clockwise. 
 *  Spin motor B counter-clockwise, then clockwise. Then it will repeat the process at 
 *  half speed. Between the steps it will stop all the motors for a second.
 *  If your motor spins the opposite direction from what you expected, just reverse the
 *  polarity of your motor.
 *  Go look at the associated function below the loop to learn more about how the control
 *  works.
 */

motorA_CCW();
delay(1000);

stopAllMotors();
delay(1000);

motorA_CW();
delay(1000);

stopAllMotors();
delay(1000);

motorB_CCW();
delay(1000);

stopAllMotors();
delay(1000);

motorB_CW();
delay(1000);

stopAllMotors();
delay(1000);

motorA_CCW_Half();
delay(1000);

stopAllMotors();
delay(1000);

motorA_CW_Half();
delay(1000);

stopAllMotors();
delay(1000);

motorB_CCW_Half();
delay(1000);

stopAllMotors();
delay(1000);

motorB_CW_Half();
delay(1000);

stopAllMotors();
delay(1000);

}

void stopAllMotors() {

  // Setting the signals all to HIGH or all to LOW will stop them from turning
  digitalWrite(sig1, LOW);
  digitalWrite(sig2, LOW);
  digitalWrite(sig3, LOW);
  digitalWrite(sig4, LOW);
}

void motorA_CCW() {
  
  // Having one signal high and another low will cause the motor to turn at full speed
  // Changing which one is HIGH will change the spin direction
  digitalWrite(sig1, HIGH);
  digitalWrite(sig2, LOW);
}

void motorA_CW() {

  // Having one signal high and another low will cause the motor to turn at full speed
  // Changing which one is HIGH will change the spin direction
  digitalWrite(sig1, LOW);
  digitalWrite(sig2, HIGH);
}

void motorA_CCW_Half() {

  // We perform an analogWrite on whichever signal is HIGH to control the speed of the
  // motor, a value of 0 is OFF and 255 is max speed, equivalent of writing HIGH
  // changing which one is bring driven HIGH changes the direction of spin
  analogWrite(sig1, 127);
  digitalWrite(sig2, LOW);
}

void motorA_CW_Half() {

  // We perform an analogWrite on whichever signal is HIGH to control the speed of the
  // motor, a value of 0 is OFF and 255 is max speed, equivalent of writing HIGH
  // changing which one is bring driven HIGH changes the direction of spin
  digitalWrite(sig1, LOW);
  analogWrite(sig2, 127);
}

void motorB_CCW() {

  // Having one signal high and another low will cause the motor to turn at full speed
  // Changing which one is HIGH will change the spin direction
  digitalWrite(sig3, HIGH);
  digitalWrite(sig4, LOW);
}

void motorB_CW() {

  // Having one signal high and another low will cause the motor to turn at full speed
  // Changing which one is HIGH will change the spin direction
  digitalWrite(sig3, LOW);
  digitalWrite(sig4, HIGH);
}

void motorB_CCW_Half() {

  // We perform an analogWrite on whichever signal is HIGH to control the speed of the
  // motor, a value of 0 is OFF and 255 is max speed, equivalent of writing HIGH
  // changing which one is bring driven HIGH changes the direction of spin
  analogWrite(sig3, 127);
  digitalWrite(sig4, LOW);
}

void motorB_CW_Half() {

  // We perform an analogWrite on whichever signal is HIGH to control the speed of the
  // motor, a value of 0 is OFF and 255 is max speed, equivalent of writing HIGH
  // changing which one is bring driven HIGH changes the direction of spin
  digitalWrite(sig3, LOW);
  analogWrite(sig4, 127);
}

If it seems like an old or deprecated piece of code you can check here to see if this might be more updated.

Code explanation – how does it work?

Line by line explanation of the code.

const int sig1 = 11;
const int sig2 = 10;
const int sig3 = 9;
const int sig4 = 6;

First we declare variables which will not be modified by the code, constants, for each of the IN pins of the DRV8833, naming them simply, and then assigning them a pin on the microcontroller. We must choose a pin that is PWM capable if we are at all interested in controlling the speed that the motor will spin at. If all you want is a single direction, you only need 1 pin for each motor, and you would connect the other IN pin to ground.

This must be done outside the setup() and loop() functions – I usually put it all the way at the top of the code, under the #include statements, if there are any.


pinMode(sig1, OUTPUT);
pinMode(sig2, OUTPUT);
pinMode(sig3, OUTPUT);
pinMode(sig4, OUTPUT);

We have to configure the pins we declared to be outputs – so that we can send our signals to the DRV8833 board. This must be done inside the setup() function.


digitalWrite(sig1, LOW);
digitalWrite(sig2, LOW);
digitalWrite(sig3, LOW);
digitalWrite(sig4, LOW);

It is always good practice to force output pins into a predictable state inside of the setup() function. I would argue this is especially important when dealing with mechanical contrivances like motors, which can be a danger. In this case, we are forcing all outputs LOW which means none of the motors should turn at all.


motorA_CCW();
delay(1000);
stopAllMotors();
delay(1000);
motorA_CW();
delay(1000);
stopAllMotors();
delay(1000);
motorB_CCW();
delay(1000);
stopAllMotors();
delay(1000);
motorB_CW();
delay(1000);
stopAllMotors();
delay(1000);
motorA_CCW_Half();
delay(1000);
stopAllMotors();
delay(1000);
motorA_CW_Half();
delay(1000);
stopAllMotors();
delay(1000);
motorB_CCW_Half();
delay(1000);
stopAllMotors();
delay(1000);
motorB_CW_Half();
delay(1000);
stopAllMotors();
delay(1000);

This section, found inside the loop() function was a stylistic choice I made. Essentially I have created 9 functions, representing the ways to control motors using the DRV8833 in each direction. The code above simply makes the motor work as per the respective function for a second, stop it for a second and go onto the next function for a second. Once it stepped through all of the different functions, it will restart from the beginning. Unless you are making a YouTube tutorial, your loop() function will look very different to this one.


void stopAllMotors() {
  digitalWrite(sig1, LOW);
  digitalWrite(sig2, LOW);
  digitalWrite(sig3, LOW);
  digitalWrite(sig4, LOW);
}

This is the function I wrote to stop the rotation of both motors connected to the DRV8833. If you don’t want to use a function at all, you can just take the contents (the four lines of digitalWrite()) and plop it into your code. Essentially, we write a LOW OR a HIGH on both IN pins associated with the motor in question – you see all IN pins addressed here because my goal was to stop both motors. I chose LOW instead of HIGH for convention only here – to match what we did in the setup() function – either would work but I recommend you remain consistent in your code.


void motorA_CCW() {
  digitalWrite(sig1, HIGH);
  digitalWrite(sig2, LOW);
}
void motorA_CW() {
  digitalWrite(sig1, LOW);
  digitalWrite(sig2, HIGH);
}
void motorB_CCW() {
  digitalWrite(sig3, HIGH);
  digitalWrite(sig4, LOW);
}
void motorB_CW() {
  digitalWrite(sig3, LOW);
  digitalWrite(sig4, HIGH);
}

Here are the four main functions to make the motors spin full-speed. Again, you can just remove the functions, the important parts are the digitalWrite() lines. For each pair of inputs, write a HIGH to one and a LOW to the other and it will spin in one direction, reverse which was HIGH and which was LOW and the direction of the motor rotation changes as well. So as you can see I wrote out the ways to make each motor spin clockwise and counter-clockwise.

Don’t forget, unless you write something different, the motor will spin in perpetuity.


void motorA_CCW_Half() {
  analogWrite(sig1, 127);
  digitalWrite(sig2, LOW);
}
void motorA_CW_Half() {
  digitalWrite(sig1, LOW);
  analogWrite(sig2, 127);
}
void motorB_CCW_Half() {
  analogWrite(sig3, 127);
  digitalWrite(sig4, LOW);
}
void motorB_CW_Half() {
  digitalWrite(sig3, LOW);
  analogWrite(sig4, 127);
}

These four functions show how you can control the speed of rotation of the motor(s). all of the concepts of the above follow here – but the digitalWrite(x, HIGH) has been replaced with an analogWrite() statement, which allows us to send a PWM signal. An analogWrite() PWM value of 0 is the equivalent of a LOW value, where as a value of 255 is the equivalent of a HIGH signal. Anything in-between those will spin the motor proportionately with the value. In the above example, a value of 127 is roughly half the rotation speed. This is the reason we selected PWM capable pins to control the motor driver.

The PWM value does not have to be a fixed value and can be a variable in your code. You could, for example, perform an analogRead() of a potentiometer, which will return a value between 0-1024 and then use the map function to convert the value to 0-255 for use in the analogWrite() statement.

That should be more than enough information to get you started and creating projects limited only by your creativity! I hope you’ll consider ordering any parts you need for your project via my affiliate links, as that is the cheapest way for you to support my work. All of the following links are affiliate links, which may earn me a commission, but will not cost you any extra.