Problems /w Multichannel ADC Sampling on Atmega644

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

Hello everyone,

I have an issue with the Atmega644 and the ADC. I am trying to sample the first four ADC channels which are connected to 20k pots. Each pot is setup as a voltage divider and will output a voltage between ground and 5 volts. The ADC is set to use AREF as the reference voltage, and 5 volts is supplied. I have also tried using AVCC.

My problem is that when I sample the ADC channels I am getting inconsistent results. For example, when I reading the first channel, ADC0, both the first and second pots result in a change in the first sampled value from the ADC. I am using single ended mode, so this should not be the case?

I have provided a copy of the code I am using. The file adccode.c is cut down to include only the relevant ADC code. The file crossover_code.c is the full code for the MCU. I am compiling using GCC-AVR with -Os. Also attached is a copy of the MCU schematic with only the relevant connections included for the ADC and pots.

Attachment(s): 

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

This is because there is only one sample-and-hold capacitor in the AVR, so if the source impedance is too high the previous reading will affect the current one.
One "solution" is to add a small capacitor to the ADC input, this acts as a reservoir, and has the same effect as lowering the source impedance. Not a good idea with fast changing analog inputs, but great for reading pots.

Four legs good, two legs bad, three legs stable.

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

You could also try strapping another 20k fixed resistor across each pot in parallel.

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

Ahh... that makes sense...

I even read that in the data sheet :oops:

I'll try using some capacitors first, since the pots are only sampled when a set button is pressed. I have some 10k pots as well.

I'll let you know what happens and post back!

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

Well I've verified the ADC is reading the right data, but when I try and use it strange things are happening elsewhere, so I have other problems as well it seems.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
ISR(ADC_vect)
{	
	adc[readingADCchan]=ADCH;
	
	if (++readingADCchan >= 4)
	{
		readingADCchan=0;
		readingADCstatus=0;
	}
	else
	{
		//ADMUX=0x20+readingADCchan;
		ADCSRA |= (1<<ADSC);
	}
}

You either gotta post the exact code that you are talking about, or talk about the exact code that you are posting. Yeah, the fragment above will indeed read the same channel over and over again 'cause ADMUX is never changed.

John's advise ain't necessarily bad and I'd also recommend it in most cases. But at moderate impedances like a 20k pot at different levels you should be able to read one channel after another with the low prescaler without seeing any "crosstalk", especailly tossing the low two bits as you are doing.

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

Yes, I apologize, ADMUX *is* getting changed. I had been debugging the code and had ADMUX set constant for testing.

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

Well, there you go, I admit I didn't actually bother to read the code!

Four legs good, two legs bad, three legs stable.