I want to filter sensor signals for a data acquisition application on an ATmega microcontroller. The interesting parts of the signal are in the range 0-5Hz, and I'd like to leave these mostly unchanged, but strongly attenuate 50Hz power line hum and anything above that.
The signal will later be evaluated in the time domain, especially the time and amplitude of large peaks (typically lasting well over a second), and the area under those peaks.
Since the signal is generated by a different device with its own power supply, I expect to see some power supply hum as well as general noise.
In order to minimize hardware components I plan to use a simple RC filter (-3dB at 18Hz) for antialiasing, combined with a fairly high sample rate (> 1kHz), and then apply digital filtering. The signal will then be sent on to a PC at a much lower sampling rate (probably <10Hz). However, I'm not very experienced with filtering, so I'm a bit overwhelmed with the choices available.
Given the fast sampling rate and very limited CPU power, filters that require many floating point operations would at best be a good deal of work to implement. I played around with filter design tools a bit and looked at the properties of Butterworth and Bessel filters or just chaining several first-order filters in a row (since they can be implemented very efficiently), and finally found an interesting section about the humble "moving average" filter on dspguide.com.
After playing around in Octave a bit, it seems to me that by chaining four moving average filters, two with 1/50s and two with 1/60s window, would give me
- around 0.5dB attenuation at 5Hz, the outer limit of what might still be interesting signal
- over 100dB attenuation at both 50Hz and 60Hz, even if the frequency is 1% off
- over 80dB attenuation for anything above 100Hz
- linear phase shift in the signal band, for a fixed delay of <40ms
This looks very promising, but since I only started playing with all of this very recently, I'm not completely sure my results are valid. Is this a good filter for my task, or would you recommend something else?
There might also still be noise left in the range of 5Hz to 50Hz which would cause aliasing when the signal is sampled at 10Hz by the PC. Then again, I don't expect to see much noise in that range and don't want to needlessly distort the signal. Should I just send the latest sample, or perhaps take the average of all samples between two "PC sample points"? What would you recommend?
Edit to address Oscar's questions:
I don't think there will be much signal above 5Hz and the SNR should be pretty good without any filtering already, but I'll try recording some examples soon. Different environments and different source equipment for the signal could also look quite different, though.
At the moment, a different device that we use for the same purpose samples the input at only 2Hz without extra filtering after the A/D, but the A/D module in that device seems to filter quite a bit already. Trying to get the requirements, I got the "at most 5Hz" figure from a colleague (though I'm not even sure if he meant samplerate or nyquist frequency), so I adjusted the sample rate up in order to remain consistent.
I'll probably have to handle four channels sampled at 12 bits, and the filtering is the only CPU-intensive task the controller has to perform. The number of cycles per sample is a tradeoff against sample rate (ammount of aliasing) and code maintainability (perform calculations while communicating with the ADC?), but I think 400 cycles would be a pretty good result.
I can't push the full sample rate to the PC, but 100-200sps per channel should be ok.