569  DC Motors

Learning Objectives

After completing this chapter, you will be able to:

  • Understand DC motor operating principles and characteristics
  • Control DC motor speed using PWM (Pulse Width Modulation)
  • Implement bidirectional control using H-bridge circuits
  • Interface DC motors with ESP32 using L298N and TB6612 drivers
  • Implement PID control for precise speed regulation
  • Understand brushless DC (BLDC) motor control basics

569.1 DC Motor Fundamentals

DC motors provide continuous rotational motion, controlled by voltage and PWM for speed regulation.

Characteristics:

  • Simple speed control via PWM
  • Direction control via H-bridge
  • High speed, low precision
  • Requires motor driver for high current

%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#2C3E50', 'primaryTextColor': '#fff', 'primaryBorderColor': '#16A085', 'lineColor': '#16A085', 'secondaryColor': '#E67E22', 'tertiaryColor': '#ECF0F1'}}}%%
flowchart TB
    subgraph HBridge[H-Bridge Motor Control Circuit]
        VCC[+12V Motor Supply]
        MCU[ESP32 GPIO<br/>3.3V Signal<br/>20mA max]

        MCU -->|IN1 Signal| DRIVER[Motor Driver<br/>L298N/TB6612]
        MCU -->|IN2 Signal| DRIVER
        MCU -->|PWM Enable| DRIVER
        VCC -->|High Current| DRIVER

        DRIVER -->|Forward: IN1=HIGH, IN2=LOW| MOTOR1[Motor Spins<br/>Clockwise]
        DRIVER -->|Reverse: IN1=LOW, IN2=HIGH| MOTOR2[Motor Spins<br/>Counter-Clockwise]
        DRIVER -->|Brake: Both HIGH or Both LOW| MOTOR3[Motor Stops<br/>Braked]

        MOTOR1 --> GND1[Ground]
        MOTOR2 --> GND2[Ground]
        MOTOR3 --> GND3[Ground]
    end

    subgraph Control[PWM Speed Control]
        PWM0[0% Duty Cycle<br/>Motor OFF]
        PWM50[50% Duty Cycle<br/>Half Speed]
        PWM100[100% Duty Cycle<br/>Full Speed]
    end

    MCU -.->|PWM Controls Speed| Control

    style MCU fill:#2C3E50,stroke:#16A085,color:#fff
    style DRIVER fill:#16A085,stroke:#2C3E50,color:#fff
    style MOTOR1 fill:#E67E22,stroke:#2C3E50,color:#fff
    style MOTOR2 fill:#E67E22,stroke:#2C3E50,color:#fff
    style MOTOR3 fill:#7F8C8D,stroke:#2C3E50,color:#fff
    style VCC fill:#E67E22,stroke:#2C3E50,color:#fff
    style PWM0 fill:#ECF0F1,stroke:#2C3E50,color:#2C3E50
    style PWM50 fill:#16A085,stroke:#2C3E50,color:#fff
    style PWM100 fill:#27ae60,stroke:#229954,color:#fff

Figure 569.1: H-Bridge Motor Driver: Bidirectional DC Motor Control with PWM Speed

569.2 PWM Speed Control

PWM (Pulse Width Modulation) is the standard method for controlling DC motor speed:

  • Duty cycle = Percentage of time the signal is HIGH (ON)
  • Frequency = How many times per second the signal repeats (typically 500Hz-20kHz for motors)
  • Average power = Supply voltage x Duty cycle percentage

Why use PWM? Digital microcontrollers can’t produce true analog voltages. Instead, they rapidly switch between 0V and 5V. A motor responds to the average voltage over time, creating smooth control without complex analog circuits.

%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#2C3E50', 'primaryTextColor': '#fff', 'primaryBorderColor': '#16A085', 'lineColor': '#16A085', 'secondaryColor': '#E67E22', 'tertiaryColor': '#ECF0F1'}}}%%
gantt
    title PWM Duty Cycle Waveforms (5V Supply, 1kHz = 1ms period)
    dateFormat X
    axisFormat %L

    section 0% Duty
    OFF (0V avg) :0, 1000

    section 25% Duty
    HIGH (1.25V avg) :0, 250
    LOW :250, 1000

    section 50% Duty
    HIGH (2.5V avg) :0, 500
    LOW :500, 1000

    section 75% Duty
    HIGH (3.75V avg) :0, 750
    LOW :750, 1000

    section 100% Duty
    HIGH (5V avg) :0, 1000

Figure 569.2: PWM Duty Cycle Waveforms: Speed and Brightness Control at 1kHz

569.2.1 PWM Frequency Selection

WarningTradeoff: PWM Frequency Selection for Motor Control

Option A: Low PWM frequency (1 kHz): Minimal switching losses (<1% power loss), audible motor whine at 1kHz, coarse current ripple causing motor heating, suitable for high-inertia loads (fans, pumps), driver efficiency 95-98%

Option B: High PWM frequency (20 kHz): Switching losses increase to 3-5%, inaudible operation (above human hearing), smooth current with reduced ripple/heating, required for precision positioning (servos, gimbals), driver efficiency 90-95%

Decision Factors: For consumer products (smart blinds, HVAC dampers), use 20kHz to eliminate audible noise complaints. For industrial pumps where noise is acceptable and efficiency matters, use 1-5kHz. Stepper motors typically use 1-2kHz to maintain torque at steps.

569.3 L298N Motor Driver Implementation

The L298N is a popular dual H-bridge driver capable of controlling two DC motors or one stepper motor.

// L298N H-Bridge Motor Driver
#define MOTOR_IN1 26
#define MOTOR_IN2 27
#define MOTOR_EN 14  // PWM pin

// PWM Configuration
const int pwmFreq = 5000;      // 5 kHz
const int pwmChannel = 0;
const int pwmResolution = 8;   // 0-255

void setup() {
  Serial.begin(115200);

  // Configure pins
  pinMode(MOTOR_IN1, OUTPUT);
  pinMode(MOTOR_IN2, OUTPUT);

  // Configure PWM
  ledcSetup(pwmChannel, pwmFreq, pwmResolution);
  ledcAttachPin(MOTOR_EN, pwmChannel);

  Serial.println("DC Motor Controller Ready");
}

void loop() {
  // Forward at 50% speed
  motorControl(150, true);
  delay(2000);

  // Stop
  motorControl(0, true);
  delay(1000);

  // Backward at 75% speed
  motorControl(191, false);
  delay(2000);

  // Stop
  motorControl(0, true);
  delay(1000);

  // Gradual acceleration
  for(int speed = 0; speed <= 255; speed += 5) {
    motorControl(speed, true);
    delay(50);
  }

  // Gradual deceleration
  for(int speed = 255; speed >= 0; speed -= 5) {
    motorControl(speed, true);
    delay(50);
  }

  delay(1000);
}

void motorControl(int speed, bool forward) {
  // Constrain speed to 0-255
  speed = constrain(speed, 0, 255);

  // Set direction
  if (forward) {
    digitalWrite(MOTOR_IN1, HIGH);
    digitalWrite(MOTOR_IN2, LOW);
  } else {
    digitalWrite(MOTOR_IN1, LOW);
    digitalWrite(MOTOR_IN2, HIGH);
  }

  // Set speed
  ledcWrite(pwmChannel, speed);

  Serial.print("Motor: ");
  Serial.print(forward ? "Forward" : "Backward");
  Serial.print(" @ Speed ");
  Serial.println(speed);
}

void motorBrake() {
  // Short brake (both inputs HIGH)
  digitalWrite(MOTOR_IN1, HIGH);
  digitalWrite(MOTOR_IN2, HIGH);
  ledcWrite(pwmChannel, 255);
}

void motorCoast() {
  // Coast to stop (both inputs LOW)
  digitalWrite(MOTOR_IN1, LOW);
  digitalWrite(MOTOR_IN2, LOW);
  ledcWrite(pwmChannel, 0);
}

569.4 PID Motor Speed Control

For precise speed control, use a PID (Proportional-Integral-Derivative) controller with encoder feedback.

#include <PID_v1.h>

// Encoder pins
#define ENCODER_A 32
#define ENCODER_B 33

volatile long encoderCount = 0;
unsigned long lastTime = 0;
float currentRPM = 0;

// PID variables
double setpoint, input, output;
double Kp = 2.0, Ki = 5.0, Kd = 1.0;
PID motorPID(&input, &output, &setpoint, Kp, Ki, Kd, DIRECT);

void setup() {
  Serial.begin(115200);

  // Setup encoder
  pinMode(ENCODER_A, INPUT_PULLUP);
  pinMode(ENCODER_B, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(ENCODER_A), encoderISR, RISING);

  // Setup motor pins
  pinMode(MOTOR_IN1, OUTPUT);
  pinMode(MOTOR_IN2, OUTPUT);
  ledcSetup(pwmChannel, pwmFreq, pwmResolution);
  ledcAttachPin(MOTOR_EN, pwmChannel);

  // Configure PID
  setpoint = 100.0;  // Target 100 RPM
  motorPID.SetMode(AUTOMATIC);
  motorPID.SetOutputLimits(0, 255);
  motorPID.SetSampleTime(100);  // 100ms
}

void loop() {
  // Calculate RPM every 100ms
  unsigned long now = millis();
  if (now - lastTime >= 100) {
    // Calculate RPM (assuming 20 pulses per revolution)
    currentRPM = (encoderCount * 60.0 * 1000.0) / (20.0 * (now - lastTime));
    encoderCount = 0;
    lastTime = now;

    // Update PID
    input = currentRPM;
    motorPID.Compute();

    // Apply motor control
    motorControl((int)output, true);

    // Debug output
    Serial.print("Target: ");
    Serial.print(setpoint);
    Serial.print(" RPM | Current: ");
    Serial.print(currentRPM);
    Serial.print(" RPM | PWM: ");
    Serial.println(output);
  }
}

void encoderISR() {
  if (digitalRead(ENCODER_B) == HIGH) {
    encoderCount++;
  } else {
    encoderCount--;
  }
}

569.5 Worked Examples

NoteWorked Example: PWM Duty Cycle Calculation for DC Motor Speed Control

Scenario: You are designing a smart ceiling fan controller using an ESP32 and a 12V DC motor. The motor runs at 3000 RPM at full voltage and you need 5 discrete speed settings: Off, Low (600 RPM), Medium (1200 RPM), High (1800 RPM), and Max (3000 RPM).

Given:

  • Motor supply voltage: 12V DC
  • Motor no-load speed at 12V: 3000 RPM
  • PWM resolution: 8-bit (0-255)
  • PWM frequency: 5 kHz
  • Speed is approximately proportional to average voltage

Steps:

  1. Calculate target duty cycles for each speed:
    • Off: 0% duty cycle (0 RPM)
    • Low: 600/3000 = 20% duty cycle (600 RPM)
    • Medium: 1200/3000 = 40% duty cycle (1200 RPM)
    • High: 1800/3000 = 60% duty cycle (1800 RPM)
    • Max: 3000/3000 = 100% duty cycle (3000 RPM)
  2. Convert duty cycles to 8-bit PWM values (0-255):
    • Off: 0% x 255 = 0
    • Low: 20% x 255 = 51
    • Medium: 40% x 255 = 102
    • High: 60% x 255 = 153
    • Max: 100% x 255 = 255
  3. Account for motor startup threshold: Most DC motors require ~10-15% duty cycle to overcome static friction. Actual Low setting may need 25-30% (64-77) to reliably start from standstill.

Result: PWM values for 5-speed fan controller: 0 (Off), 64 (Low, adjusted), 102 (Medium), 153 (High), 255 (Max).

NoteWorked Example: DC Motor Sizing for IoT Conveyor Belt

Scenario: You need to select a DC motor for a small package sorting conveyor. The conveyor must move packages weighing up to 2 kg at 0.5 m/s using a 50mm diameter drive roller.

Given:

  • Maximum package mass: 2 kg
  • Conveyor speed: 0.5 m/s
  • Drive roller diameter: 50 mm (radius = 0.025 m)
  • Coefficient of friction (belt/roller): 0.3
  • Safety factor: 1.5
  • Available supply voltage: 24V DC
  • Gear efficiency: 85%

Steps:

  1. Calculate required roller angular velocity:
    • omega = v / r = 0.5 m/s / 0.025 m = 20 rad/s
    • Convert to RPM: 20 rad/s x (60 / 2 x pi) = 191 RPM at output shaft
  2. Calculate load torque at roller:
    • Force to move package: F = m x g x mu = 2 kg x 9.81 m/s^2 x 0.3 = 5.89 N
    • Torque at roller: T_load = F x r = 5.89 N x 0.025 m = 0.147 Nm
  3. Apply safety factor:
    • Required torque: T_required = 0.147 Nm x 1.5 = 0.22 Nm (220 mNm)
  4. Calculate motor power requirement:
    • Mechanical power: P_mech = T x omega = 0.22 Nm x 20 rad/s = 4.4 W
    • Account for gear efficiency: P_motor = 4.4 W / 0.85 = 5.2 W minimum
  5. Select motor and gear ratio:
    • Typical 24V DC motor: 6000 RPM no-load, 15 mNm stall torque
    • Required gear ratio: 6000 RPM / 191 RPM = 31:1
    • Torque multiplication: 15 mNm x 31 x 0.85 = 395 mNm (exceeds 220 mNm requirement)

Result: Select a 24V DC motor (6000 RPM, 15 mNm) with 31:1 planetary gearbox.

569.6 Worked Example: Sizing a Motor for a Smart Valve

Scenario: You are designing an IoT-controlled ball valve for a smart irrigation system. The valve is a 1-inch brass ball valve that requires 90 degree rotation to fully open or close. The system operates on 12V DC from a solar-charged battery and must complete valve actuation within 5 seconds.

Goal: Select and size an appropriate motor and gearbox combination.

Ball valve torque specifications (from valve datasheet):

  • Breakaway torque (unseating): 2.5 Nm (worst case with sediment buildup)
  • Running torque: 0.8 Nm
  • Seating torque: 1.5 Nm (ensures tight seal)

Design margin: Apply 1.5x safety factor: T_required = 2.5 Nm x 1.5 = 3.75 Nm

Angular displacement: 90 degrees = 0.25 revolutions

Required speed: omega_output = 0.25 rev / 5 s = 0.05 rev/s = 3 RPM

Option: DC Gearmotor (JGB37-520 12V)

Parameter JGB37-520 12V Requirement Status
Voltage 12V DC 12V DC Pass
No-load speed 10 RPM 3 RPM Pass (margin)
Rated torque 5 Nm 3.75 Nm Pass
Stall torque 15 Nm - Pass (safety)
No-load current 80 mA - OK
Rated current 400 mA - OK
Gear ratio 1:488 - -
Cost $12 - Budget

Selected: JGB37-520 12V DC gearmotor with L298N driver

Key decisions:

  1. DC gearmotor over stepper: 3x lower cost, 4x lower power consumption
  2. 1:488 gear ratio: Converts high-speed/low-torque to low-speed/high-torque
  3. Limit switch feedback: Prevents motor stall damage
  4. L298N module: Built-in flyback protection

569.7 Interactive Lab: DC Motor Control

NoteTry It Yourself: Control a DC Motor

What you’ll do: Control a DC motor’s speed and direction using an ESP32 and L298N driver.

What you’ll learn:

  • How to wire a DC motor to an H-bridge driver
  • How PWM duty cycle controls motor speed
  • How to reverse motor direction programmatically

Estimated time: 10 minutes

Interactive Challenges:

  1. Variable Speed Challenge: Add code to smoothly ramp up from 0% to 100% speed over 5 seconds
  2. Directional Control Challenge: Make the motor alternate between forward and reverse every 3 seconds
  3. Emergency Stop Challenge: Add a button that immediately stops the motor when pressed

569.8 Brushless DC (BLDC) Motor Control

Brushless DC (BLDC) motors have become the preferred actuator for high-performance IoT applications including drones, robotic arms, electric vehicles, and industrial automation.

569.8.1 Commutation Strategies

Six-Step (Trapezoidal) Commutation:

The simplest control method energizes two phases at a time:

Step Hall Sensors (H1 H2 H3) Active Phases Current Direction
1 1 0 1 A+, B- A to B
2 0 0 1 A+, C- A to C
3 0 1 1 B+, C- B to C
4 0 1 0 B+, A- B to A
5 1 1 0 C+, A- C to A
6 1 0 0 C+, B- C to B

Advantages: Simple implementation, low computational requirements

Disadvantages: Torque ripple (up to 14%), acoustic noise

Sinusoidal Commutation:

Applies continuously varying current to each phase for smoother operation:

  • I_A = I_m sin(theta)
  • I_B = I_m sin(theta - 120 degrees)
  • I_C = I_m sin(theta - 240 degrees)

Field-Oriented Control (FOC):

The most advanced control method for maximum efficiency and smooth operation.

569.8.2 Hardware Implementation

Recommended MCUs for IoT BLDC:

  • Entry level: STM32F103, ESP32 (6-step, basic sinusoidal)
  • Mid-range: STM32G4, ESP32-S3 (sinusoidal, basic FOC)
  • High-performance: STM32H7, TI C2000 (full FOC with observers)

569.9 What’s Next?

Now that you understand DC motor control, you’re ready to explore servo motors for precise angular positioning.

Continue to Servo Motors →