Zbotic Logo Zbotic Logo
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

  • Shop
  • About Us
  • Contact Us
  • Reseller
  • Blogs
020 69134444
1800 209 0998
[email protected]
Help Desk
Facebook Twitter Instagram Linkedin YouTube
Zbotic Logo Zbotic Logo
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

All departments
  • 3D Print Service
  • 3D Printer
  • Batteries & Chargers
  • Development Boards
  • Drone Parts
  • EBike parts
  • Sensor Modules
  • Electronic Components
  • Electronic Modules
  • IoT and Wireless
  • Mechanical Parts and Workbench Tools
  • Motors & Drivers & Pumps & Actuators
  • DIY and Robot Kits
  • Show more
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
Return to previous page
Home Motors & Actuators

DC Motor Speed Control: PWM, H-Bridge, and PID Explained

DC Motor Speed Control: PWM, H-Bridge, and PID Explained

April 1, 2026 /Posted by / 0

Precise DC motor speed control is fundamental to robotics, automation, and countless Arduino projects. Whether you are building a robot car, a conveyor belt, or a camera slider, understanding PWM, H-bridge drivers, and PID feedback loops will take your motor control from basic on/off switching to smooth, precise, and responsive operation. This guide covers all three concepts with practical wiring and Arduino code.

Table of Contents

  • PWM Speed Control Basics
  • H-Bridge for Direction Control
  • Practical Wiring Guide
  • Encoder Feedback for Closed-Loop Control
  • PID Speed Control Implementation
  • Advanced Techniques
  • Frequently Asked Questions

PWM Speed Control Basics

PWM (Pulse Width Modulation) is the most common method for controlling DC motor speed. Instead of varying the voltage directly, PWM rapidly switches the motor on and off. The ratio of on-time to total cycle time (duty cycle) determines the average voltage the motor sees.

  • 0% duty cycle (analogWrite 0): Motor off
  • 50% duty cycle (analogWrite 127): Motor at roughly half speed
  • 100% duty cycle (analogWrite 255): Motor at full speed

Arduino’s PWM pins operate at approximately 490Hz or 980Hz depending on the pin. This frequency is high enough that the motor smooths out the pulses through its own inductance, resulting in steady rotation rather than jerky on-off behaviour.

Simple PWM Speed Control


const int motorPin = 9;  // PWM pin
const int potPin = A0;   // Potentiometer

void setup() {
  pinMode(motorPin, OUTPUT);
}

void loop() {
  int potValue = analogRead(potPin);     // 0-1023
  int speed = map(potValue, 0, 1023, 0, 255);
  analogWrite(motorPin, speed);
}

Note: This only controls speed in one direction. You need a transistor or MOSFET to handle motor current — never connect a motor directly to an Arduino pin.

🛒 Recommended: 1.8V-12V 2A DC Motor PWM Speed Regulator — Standalone PWM speed controller module. Just connect motor, power supply, and adjust the knob.

H-Bridge for Direction Control

To control both speed and direction, you need an H-bridge circuit. The H-bridge uses four switches to route current through the motor in either direction. Motor driver ICs like the L298N, L293D, and TB6612FNG integrate complete H-bridges with protection circuitry.

Choosing a Motor Driver

Driver Channels Current Voltage Drop Best For
L293D 2 600mA 1.4-2.8V Small BO motors
L298N 2 2A 1.4-3V General robotics
TB6612FNG 2 1.2A 0.5V Efficient, battery-powered
BTS7960 1 43A Very low High-power motors
DRV8833 2 1.5A Low Compact builds
🛒 Recommended: DRV8833 2-Channel DC Motor Driver — Compact, efficient MOSFET-based driver with low voltage drop. Ideal for battery-powered robots.

Practical Wiring Guide

L298N + DC Motor + Arduino

  • Battery (+) → L298N +12V terminal
  • Battery (-) → L298N GND + Arduino GND
  • L298N ENA → Arduino pin 9 (PWM for speed)
  • L298N IN1 → Arduino pin 8 (direction)
  • L298N IN2 → Arduino pin 7 (direction)
  • Motor → L298N OUT1 and OUT2

Speed + Direction Control Code


const int ENA = 9, IN1 = 8, IN2 = 7;

void setup() {
  pinMode(ENA, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  Serial.begin(9600);
}

void motorControl(int speed) {
  // speed: -255 to 255
  if (speed >= 0) {
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
  } else {
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
    speed = -speed;
  }
  analogWrite(ENA, constrain(speed, 0, 255));
}

void loop() {
  motorControl(200);   // Forward at ~78% speed
  delay(2000);
  motorControl(-150);  // Reverse at ~59% speed
  delay(2000);
  motorControl(0);     // Stop
  delay(1000);
}

Encoder Feedback for Closed-Loop Control

Open-loop PWM control has a significant limitation: the motor speed changes with load. A motor running at 50% PWM might spin at 200 RPM with no load but drop to 100 RPM under load. Encoder feedback solves this by measuring actual speed.

A quadrature encoder produces two pulse trains (channels A and B) that are 90 degrees out of phase. This provides both speed (pulse frequency) and direction (which channel leads).

🛒 Recommended: 25GA-370 12V 200RPM DC Gear Motor with Encoder — Metal gear motor with built-in Hall effect encoder for precise closed-loop speed and position control.

PID Speed Control Implementation


// PID Motor Speed Control with Encoder
volatile long encoderCount = 0;
const int encoderA = 2; // Interrupt pin
const int ENA = 9, IN1 = 8, IN2 = 7;

// PID variables
float Kp = 2.0, Ki = 0.5, Kd = 0.1;
float setpointRPM = 150;
float integral = 0, lastError = 0;
unsigned long lastTime = 0;

void encoderISR() {
  encoderCount++;
}

void setup() {
  pinMode(encoderA, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(encoderA), encoderISR, RISING);
  pinMode(ENA, OUTPUT); pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT);
  digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW);
  Serial.begin(9600);
  lastTime = millis();
}

void loop() {
  unsigned long now = millis();
  if (now - lastTime >= 100) { // Update every 100ms
    noInterrupts();
    long count = encoderCount;
    encoderCount = 0;
    interrupts();

    // Calculate RPM (assume 11 pulses per revolution)
    float rpm = (count / 11.0) * (60000.0 / (now - lastTime));
    lastTime = now;

    float error = setpointRPM - rpm;
    integral += error * 0.1;
    integral = constrain(integral, -200, 200);
    float derivative = (error - lastError) / 0.1;
    lastError = error;

    float output = Kp * error + Ki * integral + Kd * derivative;
    int pwm = constrain((int)output, 0, 255);
    analogWrite(ENA, pwm);

    Serial.print("RPM:"); Serial.print(rpm);
    Serial.print(" PWM:"); Serial.println(pwm);
  }
}

Advanced Techniques

  • Soft start/stop: Ramp PWM gradually to prevent mechanical shock and current spikes.
  • PWM frequency tuning: Higher PWM frequencies reduce audible whine but may reduce efficiency. Use Timer registers to set custom frequencies.
  • Current limiting: Monitor motor current with an ACS712 sensor and reduce PWM if current exceeds safe limits.
  • Braking modes: Short the motor terminals (both IN1 and IN2 HIGH) for active braking, or leave floating for coast-to-stop.
🛒 Recommended: L298N Dual H-Bridge Motor Driver — The classic motor driver for learning DC motor speed and direction control with Arduino.

Frequently Asked Questions

Why does my motor not start at low PWM values?

Every motor has a minimum starting voltage/current. Below this threshold, the motor stalls. Typically, PWM values below 50-80 (out of 255) will not produce enough torque to overcome static friction. This is normal behaviour.

Can I use PWM to control an AC motor?

No, standard Arduino PWM is for DC motors only. AC motors require a Variable Frequency Drive (VFD) or a triac-based controller for speed control.

How does load affect motor speed without PID?

Significantly. A motor at 50% PWM might run at 200 RPM unloaded but only 100 RPM loaded. PID control compensates automatically by increasing PWM when speed drops below the setpoint.

What is the difference between coast and brake?

Coast (both inputs LOW) lets the motor spin freely to a stop. Brake (both inputs HIGH) shorts the motor terminals, creating back-EMF resistance that stops the motor quickly. Use brake when you need precise positioning.

Conclusion

DC motor speed control progresses from simple PWM (open-loop) through H-bridge direction control to PID closed-loop control with encoder feedback. Each level adds precision and capability. Start with basic PWM to understand the concept, add an H-bridge for bidirectional control, and implement PID when your project demands consistent speed regardless of load.

Find DC motors, drivers, and encoders at Zbotic.in.

Tags: Arduino, DC motor, H-bridge, PID, PWM
Share Post
  • Facebook
  • Linkedin
  • Whatsapp
Raspberry Pi Accessories: Must...
blog raspberry pi accessories must have add ons and where to buy in india 612653
blog diy reflow oven convert a toaster oven for smd assembly 612656
DIY Reflow Oven: Convert a Toa...

Related posts

Svg%3E
Read more

Gear Motor Guide: N20, JGB37, and Planetary Motors Compared

April 1, 2026 0
When your project needs more torque than a bare DC motor can provide, a gear motor is the answer. By... Continue reading
Svg%3E
Read more

Miniature Pump Hydroponics: Automated Nutrient Dosing System

April 1, 2026 0
Hydroponics grows plants in nutrient-rich water instead of soil, and automating the nutrient dosing process with peristaltic pumps and Arduino... Continue reading
Svg%3E
Read more

Drone Motor Testing: Thrust Stand Build and KV Measurement

April 1, 2026 0
If you are building a drone, selecting the right motor-propeller combination is critical for flight performance. A drone motor thrust... Continue reading
Svg%3E
Read more

Pump Selection Guide: Peristaltic, Submersible, and Diaphragm

April 1, 2026 0
When your Arduino project needs to move liquid — whether for automated plant watering, hydroponics, aquarium management, or a coffee... Continue reading
Svg%3E
Read more

Solenoid Guide: Door Locks, Valves, and Automation Projects

April 1, 2026 0
A solenoid is an electromechanical device that converts electrical energy into linear motion. When you energise the coil, a plunger... Continue reading

Add comment Cancel reply

Your email address will not be published. Required fields are marked

Facebook Twitter Instagram Pinterest Linkedin Youtube

Get the latest deals and more.

Download on Google Play Download on the App Store

Call us: 020 69134444 / 1800 209 0998

Monday - Saturday 09:30 AM - 06:00 PM
For Technical Supports Email: [email protected]
For Sales / Enquiries Email: [email protected]

  • My Account

    • Cart

    • Wishlist

    • Checkout

    • My Orders

    • Track Order

    • My Account

  • Information

    • FAQs

    • Blogs

    • Career

    • About Us

    • Contact Us

    • Payment Options

  • Policies

    • Privacy Policy

    • Terms & Conditions

    • GST Input Tax Credit

    • Shipping Return Policy

    • E-Waste Collection Points

    • Our Sitemap

© Zbotic.in is registered trademark of Moxie Supply Pvt Ltd – All Rights Reserved
Login
Use Phone Number
Use Email Address
Not a member yet? Register Now
Reset Password
Use Phone Number
Use Email Address
Register
Already a member? Login Now