Bit-banging pulse density modulation
In the last article, I described how to implement a bit-bang pulse-width modulator (PWM) using a single microcontroller port pin, a timer interrupt, and some firmware. One of the issues that came about was we needed a lot of microprocessor MIPS (millions of instructions per second) in order to have any reasonable bandwidth for our PWM controller. We either needed more processor power (to sample and do the calculations more often), or we just had to resign ourselves that a cheap single-bit digital-to-analog converter (DAC) will always be relegated to the slow speed near DC domain.
I also hinted that there really is a better method for implementing a cheap single-bit DAC. This "better" method is the pulse density modulation (PDM).
As I mentioned in the last article, the PWM is a method where a pulse width is varied for a fixed PWM frequency to attain an analog output ranging from 0 to 100 percent. In the PDM case, we keep the pulse width fixed and vary, in time, the number of pulses sent out by the controller. Figure 1 shows how a pulse density modulator maintains a fixed pulse width and modulates the density in order to affect an analog output.
Click on image to enlarge.
Figure 1: using pulse density modulation to affect an analog output.
In the last article, I briefly described the PWM, and the idea behind the PWM, and dived straight into demonstrating how to implement the PWM in code. We did an analysis of how to do the filter component selection for a simple RC filter. One of the things that arose from the analysis was either the RC time constant needed to be very large, or we needed to drastically increase the sampling frequency in order to get an acceptable voltage ripple from our single-bit D-to-A converter.
For DC applications, it seems as if the single-bit PWM DAC will probably be suitable. However, what if we wish to have some better response? One solution to this problem is to increase the sampling frequency. The other solutions involve adding more poles to the low-pass filter (thus defeating reduced component cost) or to reduce the RC time constant (thus living with a higher amount of noise induced by the increased ripple).
Approaching this in a typical engineer-problem style, I'm going to describe the problem first and then propose a solution, instead of describing the PDM and jumping into code. Let's go back and review some hardware considerations.