Analog read gives bad data when using fast PWM

So I'm using a diecimila board and taking inputs from 3 temp sensors connected to the analog pins 5,4,3. Based on each temp reading, a fan is turned on using PWM at either 0%, 50%, or 100% duty cycle (higher temp, higher duty). The PWM controls my MOSFETs that are controlling the ground lead. The fan is connected to +12V from my comp's psu and the MOSFET. My diecimila is getting power through my usb hub. Now the whole set up works great when the temp is low enough that the fan is set to be off, or when the fan is set to be 100%, its when the 50% is triggered where it all goes crazy.

Basically the analog temp readings are highly erratic when the PWM is actually.. PWMing. I did change timer1's prescaler to:TCCR1B = 0x09, this creates a PWM over 25kHz. I don't care exactly what the PWM is, i just need it over audible range (25kHz).

So from what I understand when you change any output pin from high to low, the voltages get a little hairy in the mv range..and can effect my analog reads. I do not have access to an oscilloscope sooo i am not sure how off they are....Seeing how i am changing sometimes 2 pins way over 25,000 times a sec i am a little lost on how to correct this... Will a voltage regulator on my temp sensors help out? This anomaly does not happen when i used the default PWM freq. but then I hear the fan vibrate soooo that's not going to work..

Wondering if any1 has anymore ideas and sorry for the long winded question... :-/ (I'm new to this but am learning lots, if something is really wrong or easily fix, please let me know) Thx! :slight_smile:

You need more supply decoupling, the electrical noise from the motors is interfering with the A/D in the arduino. Connect a 0.1uF capacitor from Vref to GND.

Also connect something like 100uF across the power supply close to your motors or better still one close to each motor. Finally put a 0.1uF capacitor across each motor.

That should improve things.

Thanks for the fast reply! :slight_smile: I tried out what you said and then played around with different capacitor values that i had on hand, and was able to greatly improve the accuracy. Before the temp was bouncing back and forth from 22 C to as low as 6 C..(when fans are on 50% duty) but after some tinkering and your help it now goes from 22 C to 18 sometimes 16... so its much improved but not quite as steady as when the fan's are off :frowning: (nearly constant 22 C) I'm thinking I could create a more stable temp reading by implementing some code to avg or throw out bad temp values...

I'm wondering though if there is anything else I could do.... since this problem doesn't happen with the default PWM freq... would lowering my freq help out?? Any more ideas are greatly appreciated! ;D

OK it looks like we are on the right track the problem is the electrical noise generated by the motors. Basically we need to reduce that noise as much as possible and then stop it from coupling into the analogue system.

You could try a small resistor in series with the analogue input (say 100R) with a 0.01uF capacitor from analogue input to ground. This will reduce fast noise getting into the converter while not affecting the analogue reading of the slowly changing temperature.
You could also look to improve the isolation between your arduino and the motors. The best way would be to have the motors powered by a totally separate power supply (not even grounds connected) and use an opto isolator to control it. You will need a transistor or FET on the motor side because you can't switch a motor with the output from an opto isolator. Failing that more decoupling capacitors and possibly series resistors (or inductors) on both the motor supply and the arduino supply.

Filtering by software is a last resort and in my (not so humble ;)) opinion is unsatisfactory.