I have a PWM signal going into an ADC.

After the ADC the signal is being filtered using an IIR single pole filter.

Performance is exactly what I want with one exception. The purpose of the filter is to average a voltage at the ADC that represents a current. For high duty cycles getting an estimation of the average current with the low pass filter is trivial. For low duty cycles the average can sometimes be zero or fluctuate too much, meaning the filter gives imprecise values at low duty cycles.

I would like to avoid this without too much complexity. Any ideas?


The frequency of the PWM being measured can be between 0 and 250Hz. I have DMA running the ADC values to a buffer, I'm not sure what the actual adc cycle rate is but the filter loop is 10kHz. The chip is running at 16Mhz while the ADC has a prescaler of 6, so the ADC clock rate should be 2.6MHz. I'm currently doing 12bit ADC but less is possible with 28 cycles per conversion.

Increasing the sample rate is one thing. I will do that but the issue in my mind relates to the rate at which the signal decays. For 90% of the signal period the filter will be averaging using the value zero as an input, regardless of what the sample rate is. I'm more concerned about this.

enter image description here

  • \$\begingroup\$ How many samples per second are you reading from your ADC? \$\endgroup\$ Sep 11 at 0:45
  • \$\begingroup\$ Is it possible, instead, to use a counter peripheral and avoid the use of a filter? \$\endgroup\$ Sep 11 at 5:18
  • \$\begingroup\$ You mean like input capture? Totally possible. \$\endgroup\$
    – Tony
    Sep 11 at 5:47
  • \$\begingroup\$ @Tony Then I'd suggest that method. Usually, you can get great time resolution and they include a way of stopping the counting using hardware. So precise and repeatable. Consider that approach, perhaps. \$\endgroup\$ Sep 11 at 7:06

1 Answer 1


Your maximum PWM frequency is 250 Hz, but your sample rate is only 10 kHz. This gives a ratio of 40 samples per pulse.

A sample rate of 10 kHz is equivalent to one sample every 100 uSec. That is the smallest resolution in the time domain you can have with that sample rate. If you have a pulse that is, say 80 uSec long, it might be completely missed in your samples. Or it might not. It all depends upon whether the sample taken happens when the pulse is high or not. Similarly, if your pulse were 120 uSec long, it might be sampled once. Or it might be sampled twice.

That means that you can resolve the duty ratio of a 250 Hz PWM signal only down to 1/40th of 250 Hz. 32 is \$2^5\$. That is, you can represent a natural number from 0-31 with a 5 bits. 40 is slightly more, but most of the natural numbers from 0-40 can be represented by 5 bits. So we will say that the resolution of your overall system is approximately 5 significant bits.

If you have, say an 8 bit ADC, the lower 3 bits will not be significant, i.e. they will be noise, more or less random. If you have a 12 bit ADC, the lower 7 bits will not be significant. If you have a 16 bit ADC, the lower 11 bits will not be significant.

Note, it doesn't matter how many conversions your ADC does per second. It matters how many conversions are read and processed. Conversions that are made but then ignored don't help.

Possible solutions include

  • using an analog low pass filter before your ADC.
  • using a higher ADC sample rate
  • using a clock and a counter to measure the on-time of your PWM signal, rather than an ADC.
  • \$\begingroup\$ 10kHz is the rate at which I access the samples. The chip is running at 16Mhz while the ADC has a prescaler of 6, so the clock rate should be 2.6MHz. I'm currently doing 12bit ADC but less is possible. Can you explain the notion of 40 samples per pulse being equivalent to 5 significant bits, I don't understand what that means or how you arrived there. \$\endgroup\$
    – Tony
    Sep 11 at 1:19
  • \$\begingroup\$ @Tony I have made additions to my answer, that I hope help. \$\endgroup\$ Sep 11 at 1:37
  • \$\begingroup\$ I increased the ADC clock to 21MHz and set the cycles per sample to 15 for 10bit ADC. I'm shuttling the values using DMA and reading them using STM Studio trace, for some reason there has been no improvement whatsoever. I'm wondering now if freertos couldn't be interfering with the trace. \$\endgroup\$
    – Tony
    Sep 12 at 5:09
  • \$\begingroup\$ @Tony are you still accessing the samples at 10 kHz? What is important is not the number of ADC conversions per second, but the number of samples actually read and used per second. \$\endgroup\$ Sep 12 at 10:32
  • \$\begingroup\$ I've tried accessing at a faster rate, 100khz, 1Mhz. What happens is I get multiple values in a row that don't change, while the same aliasing behavior is taking place. That is I'm oversampling a low fidelity signal, so the issue for me is most likely within the ADC clock. \$\endgroup\$
    – Tony
    Sep 12 at 22:23

Your Answer

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

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