0
0
Iot-protocolsHow-ToBeginner · 3 min read

Control DC Motor Speed with Raspberry Pi Using PWM

You can control a DC motor speed with a Raspberry Pi by using PWM (Pulse Width Modulation) on a GPIO pin connected to a motor driver. By adjusting the PWM duty cycle in Python, you change the motor speed smoothly.
📐

Syntax

To control motor speed, use the RPi.GPIO library to set up PWM on a GPIO pin. The key parts are:

  • GPIO.setup(pin, GPIO.OUT): Set the pin as output.
  • pwm = GPIO.PWM(pin, frequency): Create PWM on the pin with a frequency (e.g., 1000 Hz).
  • pwm.start(duty_cycle): Start PWM with a duty cycle (0-100%).
  • pwm.ChangeDutyCycle(duty_cycle): Change speed by adjusting duty cycle.
  • pwm.stop(): Stop PWM when done.
python
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
motor_pin = 18
GPIO.setup(motor_pin, GPIO.OUT)

pwm = GPIO.PWM(motor_pin, 1000)  # 1000 Hz frequency
pwm.start(0)  # Start with 0% duty cycle (motor off)

# To change speed:
pwm.ChangeDutyCycle(50)  # 50% speed

# When finished:
pwm.stop()
GPIO.cleanup()
💻

Example

This example shows how to gradually increase and then decrease the speed of a DC motor connected to GPIO pin 18 using PWM.

python
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
motor_pin = 18
GPIO.setup(motor_pin, GPIO.OUT)

pwm = GPIO.PWM(motor_pin, 1000)  # 1 kHz frequency
pwm.start(0)  # Motor off initially

try:
    # Gradually increase speed
    for duty_cycle in range(0, 101, 10):
        pwm.ChangeDutyCycle(duty_cycle)
        print(f"Speed: {duty_cycle}%")
        time.sleep(0.5)

    # Gradually decrease speed
    for duty_cycle in range(100, -1, -10):
        pwm.ChangeDutyCycle(duty_cycle)
        print(f"Speed: {duty_cycle}%")
        time.sleep(0.5)

finally:
    pwm.stop()
    GPIO.cleanup()
Output
Speed: 0% Speed: 10% Speed: 20% Speed: 30% Speed: 40% Speed: 50% Speed: 60% Speed: 70% Speed: 80% Speed: 90% Speed: 100% Speed: 100% Speed: 90% Speed: 80% Speed: 70% Speed: 60% Speed: 50% Speed: 40% Speed: 30% Speed: 20% Speed: 10% Speed: 0%
⚠️

Common Pitfalls

  • Not using a motor driver: Raspberry Pi GPIO pins cannot power motors directly; always use a motor driver or transistor circuit.
  • Incorrect GPIO pin mode: Use GPIO.BCM or GPIO.BOARD consistently and set pins as output.
  • Forgetting to clean up: Always call GPIO.cleanup() to reset pins after running your program.
  • Using wrong PWM frequency: Too low frequency can cause motor noise; 1 kHz is a good start.
  • Duty cycle out of range: Duty cycle must be between 0 and 100.
python
import RPi.GPIO as GPIO

# Wrong: Trying to power motor directly without driver
GPIO.setmode(GPIO.BCM)
motor_pin = 18
GPIO.setup(motor_pin, GPIO.OUT)
GPIO.output(motor_pin, GPIO.HIGH)  # This can damage Pi

# Right: Use PWM with motor driver
pwm = GPIO.PWM(motor_pin, 1000)
pwm.start(50)  # 50% speed

# Remember to cleanup
pwm.stop()
GPIO.cleanup()
📊

Quick Reference

To control DC motor speed with Raspberry Pi:

  • Use a motor driver circuit (e.g., L298N, L293D).
  • Connect motor driver input to Raspberry Pi GPIO pin.
  • Use RPi.GPIO library to create PWM on that pin.
  • Adjust PWM duty cycle (0-100%) to change speed.
  • Always clean up GPIO pins after use.

Key Takeaways

Use PWM on a GPIO pin with a motor driver to control DC motor speed.
Adjust the PWM duty cycle between 0 and 100 to set motor speed smoothly.
Never power motors directly from Raspberry Pi pins; always use a driver.
Set GPIO pins correctly and clean up after your program to avoid issues.
A frequency around 1 kHz is effective for quiet and smooth motor control.