How to Use PWM on Raspberry Pi: Simple Guide with Code
To use
PWM on Raspberry Pi, you can use the RPi.GPIO Python library to control the pulse width on a GPIO pin. Initialize PWM on a pin with a frequency, then start it with a duty cycle to control devices like LEDs or motors.Syntax
Using PWM with the RPi.GPIO library involves these steps:
GPIO.setmode(GPIO.BCM): Set pin numbering mode.GPIO.setup(pin, GPIO.OUT): Set the pin as output.pwm = GPIO.PWM(pin, frequency): Create PWM instance on the pin with frequency in Hz.pwm.start(duty_cycle): Start PWM with duty cycle (0-100%).pwm.ChangeDutyCycle(duty_cycle): Change duty cycle while running.pwm.stop(): Stop PWM.GPIO.cleanup(): Clean up GPIO settings.
python
import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) # Use BCM pin numbering pin = 18 GPIO.setup(pin, GPIO.OUT) # Set pin 18 as output pwm = GPIO.PWM(pin, 1000) # Create PWM on pin 18 at 1000Hz pwm.start(50) # Start PWM with 50% duty cycle # Change duty cycle later pwm.ChangeDutyCycle(75) pwm.stop() # Stop PWM GPIO.cleanup() # Reset GPIO
Example
This example smoothly changes the brightness of an LED connected to GPIO pin 18 using PWM. It increases the duty cycle from 0% to 100% and back, making the LED fade in and out.
python
import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BCM) pin = 18 GPIO.setup(pin, GPIO.OUT) pwm = GPIO.PWM(pin, 500) # 500Hz frequency pwm.start(0) # Start with LED off try: while True: for dc in range(0, 101, 5): # Increase duty cycle pwm.ChangeDutyCycle(dc) time.sleep(0.05) for dc in range(100, -1, -5): # Decrease duty cycle pwm.ChangeDutyCycle(dc) time.sleep(0.05) except KeyboardInterrupt: pass pwm.stop() GPIO.cleanup()
Common Pitfalls
Common mistakes when using PWM on Raspberry Pi include:
- Not setting the GPIO mode with
GPIO.setmode()before setup. - Forgetting to call
GPIO.cleanup()after the program ends, which can cause warnings on next run. - Using the wrong pin numbering system (BCM vs BOARD).
- Setting duty cycle values outside 0-100%, which causes errors.
- Trying to use PWM on pins that do not support hardware PWM (software PWM works on most pins but is less precise).
Example of wrong and right usage:
python
import RPi.GPIO as GPIO # Wrong: No setmode called pin = 18 GPIO.setup(pin, GPIO.OUT) # This will raise a warning or error # Right: GPIO.setmode(GPIO.BCM) GPIO.setup(pin, GPIO.OUT) pwm = GPIO.PWM(pin, 1000) pwm.start(50) pwm.stop() GPIO.cleanup()
Quick Reference
| Command | Description |
|---|---|
| GPIO.setmode(GPIO.BCM) | Set pin numbering to BCM mode |
| GPIO.setup(pin, GPIO.OUT) | Set pin as output |
| GPIO.PWM(pin, frequency) | Create PWM instance on pin with frequency in Hz |
| pwm.start(duty_cycle) | Start PWM with duty cycle (0-100%) |
| pwm.ChangeDutyCycle(duty_cycle) | Change duty cycle while running |
| pwm.stop() | Stop PWM signal |
| GPIO.cleanup() | Reset GPIO pins and clean up |
Key Takeaways
Always set GPIO mode with GPIO.setmode() before using pins.
Use GPIO.PWM(pin, frequency) to create PWM and start it with a duty cycle.
Duty cycle controls the power delivered; 0% is off, 100% is fully on.
Call GPIO.cleanup() after your program to avoid warnings and free pins.
Software PWM works on most pins but hardware PWM pins offer better precision.