DEV Community

Cover image for ESP32 S3 - DRV8833 DC Motor Driver
Arduino ESP32 Raspberry Pi Tutorials
Arduino ESP32 Raspberry Pi Tutorials

Posted on Originally published at newbiely.com

ESP32 S3 - DRV8833 DC Motor Driver

The DRV8833 is a small dual H-bridge driver that lets your ESP32 S3 spin DC motors forward, backward, fast or slow, using only its 3.3V GPIO pins for control. A GPIO pin can only supply a few milliamps, nowhere near what a hobby motor needs, so the driver sits between the two: logic signals in, real motor current out from a separate supply. You'll start with one motor, then add a second and turn the pair into a simple robot car.

The full tutorial, with every detail and the line-by-line code explanation, is on our site: ESP32 S3 - DRV8833 DC Motor Driver

What you need

Wiring

ESP32 S3 - DRV8833 DC Motor Driver wiring diagram

Motor A connects to OUT1/OUT2, with its inputs IN1 and IN2 wired to GPIO11 and GPIO10 on the ESP32 S3. Power for the motor comes from a separate 5V adapter through a DC power jack into VCC, never from the board's own 3.3V or 5V pin, since a motor's start-up current spike can reset or damage the ESP32 S3. The EEP (nSLEEP) pin ties to the board's 3.3V pin to keep the driver awake, and the adapter ground, DRV8833 ground and ESP32 S3 ground all connect together so the control signals have a common reference.

How it works

Each DRV8833 channel is controlled by two input pins instead of a separate speed pin. PWM on IN1 with IN2 held LOW spins the motor forward, PWM on IN2 with IN1 LOW spins it in reverse, both LOW lets it coast, and both HIGH brakes it by shorting the motor. Since analogWrite() works on almost any ESP32 S3 GPIO, either input pin can carry the PWM signal. For a two-motor robot, driving the left and right channels independently gives forward, backward, and in-place turns by running one wheel forward while the other runs backward.

Code

The one-motor sketch wraps the truth table into a motorA(speed) helper that takes a signed value from -255 to 255: positive for forward, negative for reverse, zero to coast. A motorABrake() helper sets both inputs HIGH for a fast stop. The loop ramps the motor up, holds full speed, coasts, reverses at about 70%, then brakes, printing each stage to the Serial Monitor.

The two-motor version adds a setChannel() function to drive either channel from a signed speed, with forward(), backward(), turnLeft(), turnRight() and stopAll() combining both channels into car-like moves.

esp32-s3-drv8833-dc-motor-driver.ino

/*
 * This ESP32 S3 code was developed by newbiely.com
 *
 * This ESP32 S3 code is made available for public use without any restriction
 *
 * For comprehensive instructions and wiring diagrams, please visit:
 * https://newbiely.com/tutorials/esp32-s3/esp32-s3-drv8833-dc-motor-driver
 */

// ESP32 S3 pins wired to the DRV8833 inputs of channel A (motor A)
// Any ESP32 S3 GPIO can output PWM, so both pins can control speed.
#define PIN_AIN1  11 // ESP32 S3 GPIO11 connected to IN1 of the DRV8833 module
#define PIN_AIN2  10 // ESP32 S3 GPIO10 connected to IN2 of the DRV8833 module

// Set the motor speed and direction.
// speed: -255 (full reverse) ... 0 (coast) ... 255 (full forward)
// We only use analogWrite() on these pins. 0 means LOW and 255 means HIGH.
void motorA(int speed) {
  speed = constrain(speed, -255, 255);
  if (speed > 0) {           // forward: PWM on IN1, IN2 stays LOW
    analogWrite(PIN_AIN1, speed);
    analogWrite(PIN_AIN2, 0);
  } else if (speed < 0) {    // reverse: IN1 stays LOW, PWM on IN2
    analogWrite(PIN_AIN1, 0);
    analogWrite(PIN_AIN2, -speed);
  } else {                   // coast: both inputs LOW, motor spins down freely
    analogWrite(PIN_AIN1, 0);
    analogWrite(PIN_AIN2, 0);
  }
}

// Brake: both inputs HIGH, the driver shorts the motor and it stops fast
void motorABrake() {
  analogWrite(PIN_AIN1, 255);
  analogWrite(PIN_AIN2, 255);
}

void setup() {
  Serial.begin(115200);
  pinMode(PIN_AIN1, OUTPUT);
  pinMode(PIN_AIN2, OUTPUT);
  motorA(0);  // start with the motor stopped
  Serial.println("DRV8833 one-motor test started");
}

void loop() {
  // 1. Forward: ramp the speed up slowly from 0 to full
  Serial.println("Forward: speeding up");
  for (int speed = 0; speed <= 255; speed += 5) {
    motorA(speed);
    delay(40);
  }

  // 2. Hold full speed for 2 seconds
  Serial.println("Forward: full speed");
  delay(2000);

  // 3. Coast: let the motor slow down by itself
  Serial.println("Coast: motor free-runs to a stop");
  motorA(0);
  delay(2000);

  // 4. Reverse at about 70% speed
  Serial.println("Reverse: 70% speed");
  motorA(-180);
  delay(2000);

  // 5. Brake: stop quickly
  Serial.println("Brake: fast stop");
  motorABrake();
  delay(1000);

  motorA(0);  // release the brake (coast) before the next cycle
  Serial.println("----- cycle done -----");
  delay(1000);
}
Enter fullscreen mode Exit fullscreen mode

Things that go wrong

If the motor doesn't turn or behaves oddly, check that all grounds, the adapter, the DRV8833 and the ESP32 S3, are actually tied together; without a shared ground the control signals have no reference. Keep the motor supply under 10.8V and never power a motor from the board's 3.3V or 5V pin. With two motors starting together, current draw spikes, so use a supply rated for at least 1A. If the chip gets hot to the touch during long runs, let it rest or add a small heatsink, and always unplug the supply before changing wiring.

Full tutorial

The complete tutorial - wiring diagram, code explanation and troubleshooting - is here: https://newbiely.com/tutorials/esp32-s3/esp32-s3-drv8833-dc-motor-driver

Top comments (0)