Mega64 ADC bouncing. Is it Atmel or me?

Go To Last Post
14 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello all,

I made a Mega64 board running at 8MHz and I am using the internal ADC to read the voltage on pin ADC1 only. The voltage on pin ADC1 is between 2-5 volts always. Here is my problem. I quickly made the UART spit out the conversion every 400mSec so I can watch the result. What I am seeing is a stable 2.523 on the pin of the ADC. This voltage is heavily conditioned from an amp circuit so it is dead solid. I'm watching the ADC and it is bouncing between 480 - 487. Your thinking VCC right? I have the ADC reference pin connected to VCC, so any drift is canceled out. So my question is....does this seem to be an acceptable drift, or is there a problem? I was hoping to have more stability, but perhaps this is just the way it is.

Thanks guys. Have a good rest of the week.

Tom

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

What I am seeing is a stable 2.523 on the pin of the ADC. This voltage is heavily conditioned from an amp circuit so it is dead solid.

Good--that would be the first thing.

Quote:

Your thinking VCC right? I have the ADC reference pin connected to VCC, so any drift is canceled out.

Drift, perhaps, but not jitter/ripple.

Are you actually using "0 0 AREF, Internal Vref turned off." or "0 1 AVCC with external capacitor at AREF pin."? Is AVcc filtered from Vcc? Is there any ground bounce? Check that--with rock-solid signal and rock-solid AVcc and rock_solid Vref and rock-solid ground, you should expect rock-solid ADC counts on repeated conversions. (yeah, sure, it could be on the "edge" of a count and read one higher or one lower, but not several counts as you are seeing.)

What speed is your ADC clock? Try slowing it down a notch or two. Same results?

I've got many AVR apps, and a couple '64 apps, that do round-robin conversions on 6-8 channels without seeing bouncing on solid signals. Now, the real-world, especially the signal, isn't as rock-solid as desired. My normal course of events is to gather a new ADC result from each channel every 10ms, add up 50 samples, and average and close the control loop every half second. This seems to virtually eliminate things like mains and power supply ripple.

But you still want to know what it is. No, it isn't inherent in the AVR ADC with good drive on the input signal from an op amp.

Keep us posted.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks Lee. I will check into the correct REF registers on initialization. I am clocking full balls to the wall at the highest speed and I will definitely try slowing it down. Nice idea's to try! Thanks for the help. I'll be in touch.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I will check into the correct REF registers on initialization.

Neither choice is "correct" or "incorrect"; just trying to get an idea of the setup.

Certainly before worrying about a few LSB of bobble you'd need to get your ADC clock under 200kHz.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just flesh out a bit of what Lee is refering to... This concept that many people have of ADC results tracking with movement of Aref is not so good. In a DC sense, yes to the first order things will scale with Aref. BUUUUTTTT There is a pretty bad frequency response. Noise on Aref above 10kHz or so is going to get right through.

Go electric!
Happy electric car owner / builder

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I slowed down the ADC clock to 250KHz and I get the same results. :cry:
I guess the next thing to do is look into the voltages. The board is powered from a wall wart and I can see a 4mV fluctuation between 4.991 to 4.995 volts. AVCC is filtered from VCC through a ferrite bead. Perhaps I'll try some more cap on the AVCC pin. If that fails, I'll try averaging the result like what Lee did.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I slowed down the ADC clock to 250KHz and I get the same results.

Still outside the recommended range.

Which AREF setup are you using?

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I tried even slower down to 62.5 kHz, same results. Lee, my AREF setup is the AREF pin, filtered from VCC through a ferrite bead.

// ADC initialization
// ADC Clock frequency: 62.5 kHz
// ADC Voltage Reference: AREF pin
ADMUX=0x00;
ADCSRA=0x87;
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

From Vcc or AVcc?

All ground pins hooked up?

>>No<< ripple on Gnd or Vcc or AVcc or Aref? Lessee-- +/- 4 counts on 5V is 5mV/count so like 50mV P-P would explain your symptoms.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Lee...you nailed it. I have EXACTLY 50mV of ripple on the AREF pin. AREF is connected to AVCC directly. AVCC is through a ferrite bead. The same ripple is on VCC so it is a power supply issue. Probably the lead length of the wall wart if I were to guess. Not much I can do but average it out, which works well I wanted to add.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you want to check if the bouncing is from AREF then you can do it like that:

feed your ADC input with about 10% of AREF, stable voltage, with 10k and 10uF//100nF to your ADC input.
(Should give a stable adc_input)
now do a lot of samples and calculate/estimate the moise in LSB.

Do the same with an input of 90% ARef.
(With the same stable input circuit)
now do the same to calculate/estimate noise in LSB.

If the noise is about the same, then it comes from ADC and input.
If it rises, then it comes from the ARef.

Why:
If the input is noisy then it should be the same voltage noise independent of DC voltage. So the noise in LSB is the same with low input voltage as with high input voltage.
If your ARef is noisy then it will have less influence with low input voltage than with high input voltage.
ADC_Value = 1024 * V_In / (ARef + Ref_noise)

Klaus
********************************
Look at: www.megausb.de (German)
********************************

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Not much I can do but average it out, which works well I wanted to add.

If you take enough samples like my 50 and you are not sampling in sync with the mains then it seems to cancel nicely. If you ARE in sync with the mains then it should still be steady but may be in the trough or the peak.

But I'm sure that you can filter better, especially if the ripple is mains frequency. Did you apply the series inductor as shown in the datasheets? Can't you apply a filter targeted at the mains frequency?

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I probably could add some filtering, but the averaging is working out very very well. I am getting great numbers and the system is performing flawlessly. I think I'll just do this in software. This is what we call "bailing out the hardware guys".

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"Software pills for hardware ills."

In a "slow" system as I described where I close the loop every (say) 500ms, with "slow" signals such as temperature sensors, current monitoring, and the like, I usually do the simple average and then no matter what "software filter" I apply the result is still "A/D counts". But remember that the /50 is always rounding down. One could just as easily use the total. This can turn your 10-bit ADC into 10+ bits.

My typical setup with multiple A/D channels:

Continuous round-robin conversions on the needed channels, with an ADC-complete ISR grabbing the value, storing it in an array, selecting the next channel, starting the next conversion.

Then every 10ms (say) in the main loop, I grab the results of the latest conversion for each channel and add to the accumulated total for that channel.

Then every 500ms (say) the accumulated totals are averaged for the value to be used for the app, and the accumulator cleared.

This works fine for slow signals. But it doesn't always fit, so it needs to be adjusted based on the nature of the signal being measured. Monitoring the raw power for power-loss detection, for example, cannot afford the full 500ms so it might be examined at each 10ms period.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.