25kHz PWM signal to analog voltage (DC) using low-pass filter: Weird output

Summary: A 25kHz PWM signal (5VDC peak Vpp), using a simple RC low-pass filter, needs to be converted to an analog voltage to be measured using an Arduino MEGA 2560. The filter (with a cutoff frequency of ~25Hz) is assembled on a breadboard with component values of C = 2000uF and R = 3.24Ohms). The analog voltage is read by the Arduino using the analogRead function; however, the output changes from 1023 to 0 for PWM duty cycles of 100% to 50% (and below) instead of 100% to 0% (expected full range). Please advise on any possible mistakes I may have made. Thanks!!!


Let me explain my project to make it clear why I am trying this approach for PWM measurement. Computers (in my case, servers) control the speed of chassis DC fans (4-wire) using a PWM signal based on CPU temperature. I am trying to cool multiple servers stacked on top of each other by a single bank of larger external fans (internal chassis fans are removed). Since each individual server creates a PWM output, I want to measure each signal, compare the values (post conversion to analog DCV and read by the Arduino) and create a PWM signal to the external fans using the Arduino. Please explain why the filter only works between 100% and 50% duty cycles instead of the entire range (100-0). Thank you!!!

Are there issues with my selection of cutoff frequency or components values? I will post a picture of my test setup soon.

You must have the resistor value of 150 ohms or more or you'll burn out
the Arduino pin. That large a capacitance is effectively a short circuit so
the Arduino is putting out far beyond its absolute maximum current trying to
drive it.

Try 6.8uF and 1k ohm.

Mark,

Thanks for the quick response - I will try the values you recommended. I didn't understand your comment on capacitance.

Thanks!

I didn't understand your comment on capacitance

While the capacitive reactance of 2000uF at 25Hz is 3.18 ohms the over all load being driven by the arduino is going to be just over 6R. This is way too low to be driven by a logic pin. In other words the input impedance of the filter is way too low.

The absolute value of filter component values are as important as the relative values.

Grumpy_Mike:

I didn't understand your comment on capacitance

While the capacitive reactance of 2000uF at 25Hz is 3.18 ohms the over all load being driven by the arduino is going to be just over 6R.

No, the impedance seen by the Arduino is 3.24 ohms, since it isn't outputing a 25 Hz sinewave!

Thanks for the response fellas. As promised, attached is a picture of my setup. The 25kHz PWM signal is supplied by a function generator. The filter is assembled on the breadboard and the output voltage is read by analog pin #8 on the Arduino.

Do you guys have any theories why the filter only works between 100% to 50%? Thanks again!!!

Try the tool here
http://sim.okawa-denshi.jp/en/CRlowkeisan.htm
The capacitor looks like a dead short as it charges up.
With a resistor of 3.24ohm, you are practically shorting the output to Gnd.
Try 62K and 0.1uF instead. The current required is much less to change the charge of the capacitor.

Update: I have since tried the following combinations of C and R - (10uF & 680 Ohms) and (4.7uF & 1.5 kOhms). There is no change whatsoever in the response - it still works only between 100% and 50% duty cycles (corresponding output voltage is 5V to 0V).

CrossRoads - I'll try your suggested values next. Thanks for your input.

Yeah, those resistors are too small, letting too much current flow, dragging the generator output down.

Be aware that a signal generator might have a different output
impedance from an Arduino pin, but even that doesn't explain non-linear
response - there must be some non-linear element in the circuit.

Update: I have since tried the last suggested combination of 66 kOhms (couldn't find 62k at Radioshack, so had to put two 33k resistors in series) and 0.1uF components. There is no change whatsoever; I still see the output signal go from 5V to 0V in response to duty cycles from 100% to 50%. The output stays zero between 50% and 0%.

Thanks for continuing to provide input. Hopefully, this issue gets resolved soon.

This is a real low pass filter case.
You have to consider that there are several influences... one importamt point is that you should not simply charge the capacitor, you also have to discharge it...
The complexity is well discussed here: how determine the RC time constant in PWM digital to analog low-pass filter? - Electrical Engineering Stack Exchange

Hi bankaienator

Have you tried changing the frequency from 25kHz? Does this change the readings you get?

Also, is the 0 reading at EXACTLY 50% duty cycle? It seems a bit of a coincidence.

Lastly, do you have access to an oscilloscope to check the signal going into the RC and that reaching the Arduino?

Regards

Ray

If you're controlling a PWM signal based on CPU temperature ... could this explain the 50-100% control range? The filter wouldn't be the problem for an abrupt cut-off at 50%.
You should manually be able to control the PWM throughout its full range. Check if the variable type for CPU temperature is the problem ... use "unsigned" to eliminate negative numbers.

Update: Based on Ray's input I tried different combinations of resistors and capacitors at my disposal to try different cutoff frequencies. Also, I replaced the Arduino with a datalogger to read the output voltage. See the attached image for the results at different duty cycles (25kHz and 5.25Vpp). As before, we see the output drop from 5.2V to 0V between 100% and 50%. However, it is interesting to observe the that voltages become negative at 30% and 0% and mirror the magnitudes at the positive end.

Have a look and let me know what you think.

May 13 - Different Cutoff Frequencies.PNG

From you're test results it looks like in fact there is full range control with 0V at center point (50% duty).
EDIT: The circuit looks to be connected OK.

Your function generator for PWM control ... is it set to the correct PWM mode so that the signal is 0 to +5V with 0-100% duty? Or is it -5V to 0 for 0-50% duty and 0 to +5V from 50-100% duty?

Looks like the signal generator may be giving an output that alternates between -5V and +5V, rather than 0V and +5V.

So at 50%, the positive and negative going parts of a cycle cancel out and give 0V.

Hi bankaienator

I looked again at the photo you posted, and found the manual for the Agilent 33210A you are using:

http://www.google.co.uk/url?sa=t&rct=j&q=&esrc=s&source=web&cd=3&ved=0CE4QFjAC&url=http%3A%2F%2Fwww.physics.rutgers.edu%2Fugrad%2F326%2Fhp_33210a_User_guide.pdf&ei=QWR0U4DkCYSVPcrDgLgH&usg=AFQjCNFk4qHZ_42nyNDtZq8_dnB7skA6Pw&sig2=FKSnHgT6xxO8PmxoCr3E5A&bvm=bv.66699033,d.ZWU

The indication on the Agilent display is that your waveform is alternating about a 0V DC offset, which is the default for the Agilent.

Check out pages 20 and 21 of the manual for how to set the signal limits to 0V and +5V, and see if that helps.

Also, for testing, it looks like the square wave output from the Agilent can have its duty cycle varied easily. This might be a good place to start.

All the best

Ray