Saturday, May 12, 2012

Arduino PWM Filter

To get nice analog signals from the Arduino PWM pins it is necessary to filter the output.  Arduino PWM is somewhat slow, frequency of 15.6 kHz at 10 bit timer resolution (see this post on configuring the timer).  Luckily this is fine if you do not care about signals faster than 1 kHz.  Indeed I find that the Arduino can't really generate sine curves faster than about 0.1 kHz.  So it makes sense to just filter signals to maximally attenuate the PWM noise while retaining signals slower than 0.1 kHz.

This requires us to design a low-pass filter.  Now, doing some research, it is easy to find recipes for all kinds of analog filter designs, however, a simple RC filter does just fine for our needs.  I found a nice tutorial online explaining how the RC filter works.  The main formula needed is that the time constant of the RC circuit is related to the cutoff frequency as:  Tau = RC = 1/(2*pi*f)

So we have PWM at 15.6 kHz and we want to pass signals of 1 kHz, which means we should put our cutoff frequency at just a little above 1 kHz, say f = 2 kHz.  We get Tau = 1/(2*pi*2 kHz) = 8e-5 sec.  For a resistor of 1 kOhm, that gives a capacitor of 0.08 uF.  However, the attenuation of an RC filter is rather poor with only a -20 dB decrease per decade.  This means that for this cutoff we will be attenuating the PWM signal by only ~20 dB or ~10 times.  So a 5 V pwm will still show up as a ~500 mV signal on our output.  

To improve our results, I sometimes use a combination of a 1 kOhm resistor and a 1 uF capacitor with Tau = 1 msec.  This gives a cutoff frequency of 159 Hz, acceptable given that the Arduino has trouble with signals faster than 100 Hz and attenuates the PWM frequency significantly more (~-40dB) or only ~50 mV left of our 5 V PWM signal.

No comments:

Post a Comment