Can I use the GPIO as a pulse-width modulation output?
If so, how would I go about doing it and how many concurrent, distinct PWM outputs can I have?
Raspberry Pi Stack Exchange is a question and answer site for users and developers of hardware and software for Raspberry Pi. It only takes a minute to sign up.Sign up to join this community
As suggested by Alex Chamberlain, the WiringPi library appears to support both hardware PWM output on one or two GPIO pins depending on model, and software PWM on any of the other GPIO pins. Meanwhile the RPIO.PWM library does PWM by DMA on any GPIO pin. Effectively this is a halfway house between hardware and software PWM, providing a 1 µs timing resolution compared to 100 µs with WiringPi's Software PWM.
Which of these is suitable for your applications depends on how many PWM outputs you need and what performance you want out of those outputs.
If your application is tolerant of low-timing resolution and high jitter then you could use a software or DMA assisted timing loop. If you want higher precision / lower jitter PWM then you may need hardware assistance.
If you want to flash a bunch of LEDs with different human visible cadences (10's of hertz) with soft real-time response requirements then the software loop could handle as many PWM's as you have GPIO pins.
If you want to control a servo motor with hard real-time response requirements then you will need to use hardware PWM. Even then you may have problems ensuring a real-time response for the servo loop which ties encoder input to PWM output.
A stable servo loop need to read encoders at a regular rate (low jitter), write out revised PWM output values at a regular rate and the latency between these should be fixed (low jitter overall). If you can't do this, then you will have to undertune (soft tune) your motor to prevent it becoming unstable under load. This is hard to do with a multi-tasking operating system without low-level support.
If you need to run more servo loops than you have hardware PWM outputs, then you are probably going to need to offload them to another device to ensure hard real-time performance, relegating your Raspberry Pi to being a soft real-time supervisor.
One option, would be something like the Adafruit 16-Channel 12-bit PWM/Servo Driver - I²C interface - PCA9685 which would allow you to control 16 PWM outputs with just a few pins of GPIO for the I²C bus. For an example of its use, check out the I²C 16 Channel PWM/Servo Breakout - Working post on the Raspberry Pi forums.
Yes, there is one hardware PWM output on the Raspberry Pi, connected to P1-12 (GPIO18). Further, PWM outputs could be added using an I²C or SPI interface; some people have had success with this (forum post).
You can use the WiringPi library to control the PWM pin; you could look at the code to avoid including the entire library.
The Raspberry Pi is not suitable for any serious software PWM as Linux is not a real-time operating system.
Recent Pis have two hardware PWM channels. In addition hardware timed PWM pulses may be independently generated on all the GPIO connected to the 40 pin expansion header.
In practice this means there are two highly accurate PWM channels and all the other GPIOs may have Arduino style PWM (800 Hz, 0 off - 255 fully on).
Not quite a real-time OS, but RISC OS for Raspberry Pi is cooperative multitasking, so you can easily run an application that has 100% CPU so you can manage your timings much better. Just don't expect to do anything else but your own code.
I have found this library (pi-blaster) which claims to be "extremely efficient: does not use the CPU and gives very stable pulses."
I've not tested it yet, but will update as soon as I do (probably today)