First, lets define pulse width modulation (PWM.) It refers to the duty cycle (how long the line is high vs how long it is low) of a pulse stream.
A duty cycle of 50% looks like this:
A duty cycle of 25% looks like this:
And 75% looks like this:
What use is this for controlling motors? If you have ever tried controlling a motor by simply turning it on and off, you quickly realize how little control you have. Your robot goes from stopped to zooming at full speed with nothing in between. If, however, you use PWM to power your motor, then it will be on at full power very briefly and then off, repeatedly. With PWM you can provide much finer motor control and have your robot move at whatever speed you like. The higher the duty cycle of the pulse stream, the more power your motor will output.
There are several ways to produce PWM signals from the Raspberry Pi. The simplest is to turn a GPIO pin on and off in a loop with delays controlling the pulse width. This is very CPU intensive and not always consistent. You can use libraries or device drivers to produce PWM from the GPIO that will be consistent and will use virtually no CPU. Or, you can use external hardware to produce PWM.
Here is how I have done it in the past. (I haven't built a robot using a Pi yet, but did it with simpler microcontrollers years ago.) Use six GPIO pins:
- Enable (motor is on or off)
- Direction (forward or reverse)
- Power 0
- Power 1
- Power 2
- Power 3
The four power bits control the duty cycle of a pulse stream and allow 16 different power levels. Below is a block diagram of the circuit I used to do this.
I used a 555 chip for the pulse generator, a 74161 counter, and a 7485 comparator. Other chips can be used to achieve similar results. I built my own H bridge circuit back then, but I recommend checking out some of the motor controller chips available now, such as the SN754410 chip.