Digital filter description:

  1. The filter's input are sensor data and output will be provided to a PID controller.

  2. Sampling rate: 64kHz

  3. Noises spectrum: from DC to 10kHz

  4. Filter target: to get DC component only and reduce noises as much as possible.

  5. Characteristic of DC: it varies very slowly, say at 0.000001Hz.

More about the system

  1. The system input (ref or reference is zero). And actually the goal of the controller is to maintain the output of the system at zero.

  2. In this system, there are also disturbance and noises. The disturbance has the shape of roughly a ramp, however by nature more like random events at very low frequency

  3. The controller is a simple PI controller. It strives to compensate the influence from disturbance while get rid of noises.

  4. The noises are from sensors and the filter between controller and sensor is what I am looking for help about here.

enter image description here

My current way of filter design:

  1. The data will go into a decimator for decimation firstly. The decimator is an 320 tap average filter, which average every 320 data and exports one averaged result. The results will be at 200Hz.

  2. The averaged data will then further go into a 20 tap averaging decimator. The results will be at 10Hz.

  3. At last, the data at 10Hz will go into an IIR or again, a moving average filter. The final result shall ranges from 1Hz to 0.2Hz.

My concerns: Insufficient desgin

The averaging decimator may not be sharp enough, since they are basically FIR with same coefficients of 1/320. Since the filters are not sharp enough, decimation(downsampling) may introduce high frequency noises mapping into the filtered results.

The following diagram is the response for 1/320 averaging filter enter image description here

May not be bad

Since the several stages of decimation is basically averaging the signals. The results shall be DC component, since that is how DC is defined.

Advice needed

How to improve my current design?

  • \$\begingroup\$ Why aren't you using an IIR filter? \$\endgroup\$
    – user16324
    Commented Mar 21, 2016 at 14:16
  • \$\begingroup\$ @BrianDrummond For decimation stages or for last filtering stage? For the decimation stages, an FIR (in this case averaging) saves computation resources, since decimation only computes the result needed and does not care the dumped ones. However an IIR depends on history values and has to process all data. \$\endgroup\$ Commented Mar 21, 2016 at 14:18
  • \$\begingroup\$ @richieqianle I think a 320 taps FIR is something exaggerated. Perhaps using filter coefficients (instead of moving average filter 1/n_taps) and 32 taps or 64, you get better response and lower delay. \$\endgroup\$ Commented Mar 21, 2016 at 14:33
  • \$\begingroup\$ @MarkoBuršič Do you think that still be a problem if we only talk about DC component? And delay would not be a concern, only noise is. \$\endgroup\$ Commented Mar 21, 2016 at 14:35
  • 1
    \$\begingroup\$ @MarkoBuršič A moving average can be implemented much faster if you realize that everything in the fifo will always sum to the same value, except for the newest and the oldest. Each pass now simplifies to one add (new), one subtract (old), and one division (or multiplication by 1/N). That way the only thing stopping you is available memory for the fifo, not processing time. \$\endgroup\$
    – pipe
    Commented Mar 21, 2016 at 16:58

2 Answers 2


Your first problem is not insufficient design, but insufficient specification. Please note that 'as much as possible' is not a specification!

Rather than wondering whether any particular filter is sharp enough, and may introduce high frequency noises onto the results, it would be more constructive to specify how much attenuation is required at what frequencies, and then design a filter that gives this attenuation.

One of the first specification points is what the output sample rate should be. The lowest rate you mention is 10Hz, but then it is filtered after that. Is that the output rate, or does it come down? If your DC is varying at 1uHz, then even 10Hz could be considered to be rather over-sampled!

I'm not sure how you arrived at using a first stage filter of 320 taps?

Anyhow, deep decimation like you're doing here will typically involve two stages.

First stage - get a large reduction in sample rate down to a few times your final rate, using a crude low pass filter, to have deep rejection nulls around your final sampling rate, nulls wide enough to accommodate your final bandwidth. This filter runs frequently, so will need to be short. This could be a CIC filter, though that requires very high precision, can need bignums for a large rate change. A low order decimating FIR is perhaps a better choice for a software implementation.

Second stage - design a final filter that eliminates the noise that has been aliased by the crude first stage filter, and drops the rate to the final desired one. This filter runs rarely, so can be very long.

Where the output rate does oversample your required bandwidth by a large factor, you can afford to be very inefficient with your filter design. In these cases, it looks like the case you describe, an iterated first order IIR filter is a reasonable choice.

The beauty of a first order IIR filter is that the effective length is adjusted merely by setting the value of k in the recurrence relation. You can either iterate it to improve the steepness slightly, or simply oversample a lot to allow the poor stopband not to influence your results. There is the very real problem that a small k and/or large decimation ratio can run you into numeric precision problems if you are not careful.

This may not be the easiest filter to design by forum. I am happy to help you firm up your spec and help you design it offline, just for the lols.

  • \$\begingroup\$ Thank you very much for your reply Neil, I am learning CIC already now. 1. For the spec: our current design's noise Vpp(as described above) is 2.5 times higher than our competitors. I am not sure that I have a spec now, since the goal is the smaller the better. But I will try to come up one. Thanks Neil. \$\endgroup\$ Commented Mar 22, 2016 at 2:11
  • \$\begingroup\$ 2. The output rate comes down again after 10Hz. The final output frequency ranges from 0.2Hz to 1Hz. The output of the filter will go into a controller actually. 3. About first stage 320taps: Please check the "may not be bad" part of the post. I thought to get DC, averaging is the best way. Therefore I averaged every 320 data to get one result. 320 is used only because it matches MCU timer easier. \$\endgroup\$ Commented Mar 22, 2016 at 2:24
  • \$\begingroup\$ 4. Could you comment on that: to get DC, averaging is sufficient? If this is the case, do we still need a CIC? And if our platform is a fast 32bit MCU with DSP, is it reasonable to run CIC on it? 5. I really appreciate your kind help of designing the filter and firm the specs. Let's do that! \$\endgroup\$ Commented Mar 22, 2016 at 2:25
  • \$\begingroup\$ I'm a bit concerned by the throwaway line in one comment that the output goes into a controller. I don't know what a controller is. Is it feeding back to control what you're measuring? If so, you will have to expand the system under question to include the whole loop, and identify where the noise is 2.5x worse than what you want. The reason? A control loop is a low pass filter itself. You may have to change the loop dynamics if the noise is coming from the effector, or it may not be possible at all if the noise is in the sensor. \$\endgroup\$
    – Neil_UK
    Commented Mar 22, 2016 at 7:43
  • \$\begingroup\$ Oh Neil, I love your questions which are really good and reminds me a lot what I should learn. 1. I think noises are the main concern now: may come from filter added noise or lack of stopband attenuation. 2. Add all 64k samples together for 1 second is not enough, since that is how I am doing it right now. It has large noises. 3. I am using Matlab and am able to plot spectrums. 4. I shall learn about the controller bandwidth. I lack theory on that am now I am just tuning PID coefficients. \$\endgroup\$ Commented Mar 22, 2016 at 8:29

You have defined your DC as varying at 0.000001Hz. Are you aware that this is 1000000s, or 1.9 years? If that's truly your intention, with a sampling rate of 64000Hz, you need to average 64,000,000,000 samples to get your 1 DC measurement! I imagine you don't really mean such a low DC rate, but assuming something in the low Hz region, I suggest instead that you do this by analogue filtering and set your sample rate much lower. Let the analogue capacitor filtering take the strain, and do your digital sampling much more slowly to avoid wasting digital logic.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.