Decimate signal by 64

I have a 16bit SAR ADC sampling at 6.4kHz. The Anti-Aliasing Filter is a active 4th order Bessel lowpass (2x LTC6081) with -3dB at 200Hz and -80dB at 3.2kHz.

Now I want to decimate these 6.4kHz to 100Hz. The uC is a 8bit RISC (Atmel AVR) running at 20Mhz.

My first idea was multiple digital bessel biquad filters and downsampling by a factor of 2 but this performs horribly. Then I read about half-band and polyphase filters but I don't have any experience in these topics.

So my primary question is: how should I downsample my 6.4kHz signal to 100Hz?

• In the meanwhile I calculate the mean over 64 samples (which should be the equivalent to a MTA with 64 samples and downsample by factor 64) until I have enough computational power to implement Marcus' answer
– Andy
Aug 14 '18 at 14:36

So, yes, since your decimation is a power of two, going through cascaded half-bands is a clever thing to do!

First of all, what's special about a half-band filter? If you implement a filter of 1/2 bandwidth as FIR, then you can choose to design it so that the transition width's center is exactly at ¼ the sampling rate – that allows for symmetry, and that in turn gives you a FIR filter where every other coefficient is zero.

Zero coefficients don't need to be summed. This gives you the steepness of a $K$-tap filter at the cost of $\frac K2$!

Now, let's look at the fact that you're decimating by a factor of 2:

That means that you throw away every other output sample. Polyphase decomposition of your filter allows you to write your single filter as a sum of two alternatively "fed" filters, so that instead of calculating $K$ products and sums per time step, you calculate $\frac K2$. That's another effort reduction by a factor of 2.

So, what you do is:

1. you pick an existing decimating FIR filter implementation in C or assembly, or write it yourself (it's but a simple for-loop). GNU Radio has one; it's in C++, and uses optimized filter kernels, but it might help illustrate how you split up one filter into $K$ subfilters to reduce the load by a factor of $K$ in a $K$-decimating FIR.
2. You design a half-band filter. You probably don't need something fantastic; make sure you get as many zeros in there as sensible.
3. you concatenate $\log_2 64=6$ of these (in fact, that's only nearly efficient; read that article, it's good).

General comment: Using an 8-bit microcontroller to process 16 bit numbers is a bad idea through and through. Atmegas are usually more expensive than similarly peripheral-equipped ARM counterparts, and really, they aren't even remotely adapted to DSP loads. Don't do that to yourself. This task is easy even on a cheap 20 MHz ARM Cortex-M0, and you could have a Cortex-M4F for the price of a larger ATMega. That would have a floating point unit; not that you need that for any of this (you can do all these calculations in fixed point, like you'd have to do it on your AVR), but it does make one's life easier further down the processing chain. I assume you use an AVR "because you already have that, and have experience with that"; but believe me, you're shooting yourself in the knee. More suitable MCUs are cheap, and so are development boards (they literally start at 2$) sufficient to connect your ADC to them. • which development board at 2$ ? the mini blue one from aliexpress ? Aug 13 '18 at 15:43
• @Fat32 sadly, exactly that. point being: if you can interface the ADC with an ATMega, you can do so as well with a bare bone STM32L01… Aug 13 '18 at 20:47
• Thank you very much for this detailed answer. I have to think about this some days. And you are absolutely right that an Atmega is a very bad design decission at that point. The reason for this was the huge existing codebase. I also hat a look at the dsPIC33 family but have no experience yet.
– Andy
Aug 14 '18 at 12:33
• DSPIC33 is ... 16 bit. And, that architecture is only 18 years old today, not 23 like the AVR core;) no, really, handling 16bit ADC values pretty much says you want a 32 bit CPU. And DSPIC really is worst case on the effort/benefit and cost/benefit scale at this point – why use a 16 bit core for wider numerical types? Back in 1999, having that might have been the only way to manage silicon complexity, but really, ARM cores with considerable speeds can be had for a handful of dollars. I wouldn't set my money on a 16bit horse in 2018. Aug 14 '18 at 16:52
• Thank you again for this insight. I think I should really try to get hands on a Cortex-M4F evaluation board.
– Andy
Aug 16 '18 at 10:48