ADC drift when driving PWM

Gentlemen, I have a stunning problem with PWM out influencing the ADC in.

I have two sensors connected to AD0 and AD1 on a 2009. I debug the values through serial.print. The values are stable and as expected so far.

Now, I use PWM out (analogWrite...) to drive PWM 9 and 10. There is no load on the PWM outs other than one TTL-gate on each. VSS is very constant at 4.82V +/- 2mV. As soon as I set my PWM value lower than 240, the ADs start to drift significantly at +/- 50% !! There is no difference in using AREF external or internal :-/

Anyone an idea ??

The problem does not occur if I let the PWM frequency at standard. If I set the PWM frequency to 32kHz

int PreScalerValue=0x07; // PWM base frequecy = 32kHz TCCR1B &= ~PreScalerValue; PreScalerValue=1; TCCR1B |= PreScalerValue;

than the values start drifting....crazy.

Is Aref drifting? Measure the voltage on the Vref pin to see if it moves.

It is directly connected to VCC, drifts minimal +/- 2mV, but no difference to where PWM is turned off. I also physically disconnected the PWM outs from anything else to avoid EMV....just bent them away from the difference.

I am not 100% sure yet, but I wrote a very short piece of sample code to get closer to the issue. My original code is about 9k. It runs at 91-92Hz(loops per second). The short demo code is way faster and I delay() it. The ADC drift is minimal, even w PMW turned on.

I think the devil is going to be in the details here. First, I don't know what you mean by "standard" PWM frequency. If you change the frequency out from under the analogWrite() function you're also effectively changing the duty cycle.

Tell us more about your sensors. Do they have a very high output impedance? Above 10k or so and you stand to see a fair amount of noise that can be coupled into the A/D pins from external/internal switching.

-- Check out our new shield:

This is how you change the FREQUENCY:

int PreScalerValue=0x07; // PWM base frequecy = 32kHz TCCR1B &= ~PreScalerValue; PreScalerValue=1; TCCR1B |= PreScalerValue;

By decreasing the prescaler value, the frequency increases. Standard frequency is at 500Hz for pins 9 and 10.

analogWrite(...) changes the pulsewidth, correct.

It can't be anything with the sensors, as everything works at standard PWM frequency or without using the PWM outs also at 32kHz. There is definitely some noise which I am eliminating effectively by using a savitzky-golay filter. What happens is: - I do not turn any PWM on, value of AD is about 500, no issue. - I turn on PWM (500Hz, analogWrite(Pin,value) ), still no problem, no matter which value I write to the PWM. - I switch PWM frequency to 32kHz, but don't do any analogWrite(Pin,value), still no issue. - I do analogWrite(Pin,value) at 32kHz, AD value rises to 720 and drifts heavily. - If I write values between 245 and 255 to the PWM, no issue. - If I use the short code, no issue, neither at 32kHz nor at 500Hz

I have two sensors connected to AD0 and AD1

Just a shot in the dark here but try connecting the two sensors to another two channels besides AD0 and AD1. Looking at the datasheet it looks PWM shares?? the Analog comparator which uses AD) and AD1 as it's inputs. Maybe there's some kind of switching noise at the higher frequency PWM.

You could also try putting a 100nF cap across the Vref pin to GND.

If I use the short code, no issue, neither at 32kHz nor at 500Hz

This one is interesting...I wonder if "long" code also implies large data structures that might be exceeding your available RAM and you're getting stack overflow issues.

Any large arrays in your code?

-- Check out our new shield:

nope, just about 25 floats and 10 ints.

also funny: start up the arduino and have let say a motor at the pwms. there is a big difference whether you use a serial.print(..) at setup() or not. The pwms "fire" unpredictable during the first seconds if there is a serial.print(..). If no serial.print(..) it is pretty sure the do not "fire". But...not the issue of this thread. :-)