Issue - sampling all of adc channels (10 bits)

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

Hi

I have tried to use a single channel (ADC0) at higest speed (10 bit) based on free running mode at every 1ms, it works without any problem. Then I decided to sample all of the adc channels at every 1ms and stumbled on problems as I varied the pot on channel 0, suddenly most of channels copy the value from cahnnel 0. I double-checked my board for any sign of error and tested on every channel. They are not connected together at all. I assume ATMEGA32 cannot sample 8 channels at 10 bits and at the higest sampling rate. Unless I have ocerlooked something.


ISR(TIMER1_OVF_vect) 
{
  	PORTB ^= (1 << RED_LED); // Toggle the LED 
  	TCNT1  = RELOAD; // Reload timer with precalculated value 
	PORTB ^= (1 << GREEN_LED); // Toggle the LED

	ADMUX=ADC_VREF_TYPE | 0;
	ADCSRA |= (1<<ADSC);
	while(!(ADCSRA & 0x10)); // wait for conversion done, ADIF flag active
	ADCResult=ADCW;
	ADCSample[0]=ADCResult;

	ADMUX=ADC_VREF_TYPE | 1;
	ADCSRA |= (1<<ADSC);
	while(!(ADCSRA & 0x10)); // wait for conversion done, ADIF flag active
	ADCResult=ADCW;
	ADCSample[1]=ADCResult;

	ADMUX=ADC_VREF_TYPE | 2;
	ADCSRA |= (1<<ADSC);
	while(!(ADCSRA & 0x10)); // wait for conversion done, ADIF flag active
	ADCResult=ADCW;
	ADCSample[2]=ADCResult;

	ADMUX=ADC_VREF_TYPE | 3;
	ADCSRA |= (1<<ADSC);
	while(!(ADCSRA & 0x10)); // wait for conversion done, ADIF flag active
	ADCResult=ADCW;
	ADCSample[3]=ADCResult;

	ADMUX=ADC_VREF_TYPE | 4;
	ADCSRA |= (1<<ADSC);
	while(!(ADCSRA & 0x10)); // wait for conversion done, ADIF flag active
	ADCResult=ADCW;
	ADCSample[4]=ADCResult;

	ADMUX=ADC_VREF_TYPE | 5;
	ADCSRA |= (1<<ADSC);
	while(!(ADCSRA & 0x10)); // wait for conversion done, ADIF flag active
	ADCResult=ADCW;
	ADCSample[5]=ADCResult;

	ADMUX=ADC_VREF_TYPE | 6;
	ADCSRA |= (1<<ADSC);
	while(!(ADCSRA & 0x10)); // wait for conversion done, ADIF flag active
	ADCResult=ADCW;
	ADCSample[6]=ADCResult;

	ADMUX=ADC_VREF_TYPE | 7;
	ADCSRA |= (1<<ADSC);
	while(!(ADCSRA & 0x10)); // wait for conversion done, ADIF flag active
	ADCResult=ADCW;
	ADCSample[7]=ADCResult;

	PORTB ^= (1 << GREEN_LED); // Toggle the LED

} 

void ADCInitalization(void)
{
	ACSR = (1 << ACD);	// Disable Analog Comparator & Reduce power consumption

	SFIOR = (0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);	// Timer/Counter1 Overflow

	ADMUX=ADC_VREF_TYPE | (1 << ADLAR) | ADCSample[0];

	ADCSRA = (1<<ADEN)   |          	 			// ADC enable 
        	 (1<<ADSC)   |               			// start conversion 
			 (0 << ADIF) |							// ADC Complete Flag
			 (1 << ADIE) |							// ADC Interrupt Enable
        	 0<<ADPS2 | 0<<ADPS1 | 0<<ADPS0;   		// Prescale = 1 	
}

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

IIRC you need to throw away the first conversion after changing channel, as that first conversion will be crap. The data sheet has more on this.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

Quote:

while(!(ADCSRA & 0x10)); // wait for conversion done, ADIF flag active

Where are you clearing that flag?
Quote:

(1 << ADIE) | // ADC Interrupt Enable

Where is your ISR?

What speed is your Mega32 clock?

There are some posts on "overclocking" the ADC that have some numbers. But if you are clocking at some MHz then don't expect good results. Under those conditions the input signal must have excellent drive.

But there is no need to go to those extremes for what you describe. You want to do 8 conversions each millisecond, or 8ksps. That is within reach of the ADC running >>within<< specs.

I normally run a 57kHz ADC clock. 13 ADC cycles per conversion gives 225us; add a bit for ISR servicing and latency gives 250us or 4ksps.

Twice the clock and you have your 8ksps and still well within spec. 4x the clock and a slight overclocking, but overkill on the samples IMO--does your app really "close the loop" every 1ms? I'd doubt it.

Do a simple round-robin interrupt-driven ADC "channel scan", parking the raw values for each channel into your sample array as you are doing. "Set it and forget it"--whenever you want values, the latest conversion result is right there. (Make sure you do atomic access if using all 8 bits.)

So, you have coding problems as first noted and then IMO system design/concept problems.

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

theusch wrote:
Quote:

while(!(ADCSRA & 0x10)); // wait for conversion done, ADIF flag active

Where are you clearing that flag?
Quote:

(1 << ADIE) | // ADC Interrupt Enable

Where is your ISR?

What speed is your Mega32 clock?

There are some posts on "overclocking" the ADC that have some numbers. But if you are clocking at some MHz then don't expect good results. Under those conditions the input signal must have excellent drive.

But there is no need to go to those extremes for what you describe. You want to do 8 conversions each millisecond, or 8ksps. That is within reach of the ADC running >>within<< specs.

I normally run a 57kHz ADC clock. 13 ADC cycles per conversion gives 225us; add a bit for ISR servicing and latency gives 250us or 4ksps.

Twice the clock and you have your 8ksps and still well within spec. 4x the clock and a slight overclocking, but overkill on the samples IMO--does your app really "close the loop" every 1ms? I'd doubt it.

Do a simple round-robin interrupt-driven ADC "channel scan", parking the raw values for each channel into your sample array as you are doing. "Set it and forget it"--whenever you want values, the latest conversion result is right there. (Make sure you do atomic access if using all 8 bits.)

So, you have coding problems as first noted and then IMO system design/concept problems.

Sorry, it should be (0<<ADIE). I am currently using an internal 8MHz clock at the moment. Basically I sample all of adc channels at every 1ms. I am hoping that can be done quick as possible then I can introduce my adc calculation and control system.

Again I would like to have 10 bit of each adc channel

Can you please give me an example of round robin interrupt drive ADC?

MM

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

ISR(ADC_vect)
{
	ADCResult=ADCH;
//	PORTB ^= (1 << GREEN_LED); // Toggle the LED
//	ADCSRA |= (1<<ADSC);

	switch(channelADC)
	{
		case 0:
		PORTB ^= (1 << GREEN_LED); // Toggle the LED
		ADCSample[0]=ADCResult;
		channelADC++;
		break;

		case 1:
		ADCSample[1]=ADCResult;
		channelADC++;
		break;

		case 2:
		ADCSample[2]=ADCResult;
		channelADC++;
		break;

		case 3:
		ADCSample[3]=ADCResult;
		channelADC++;
		break;

		case 4:
		ADCSample[4]=ADCResult;
		channelADC++;
		break;

		case 5:
		ADCSample[5]=ADCResult;
		channelADC++;
		break;

		case 6:
		ADCSample[6]=ADCResult;
		channelADC++;
		break;

		case 7:
		ADCSample[7]=ADCResult;
		channelADC=RESET;
		PORTB ^= (1 << GREEN_LED); // Toggle the LED
		break;
	}

	ADMUX = ADCSample[channelADC]; 		// ADC Sample Circular Routine
	ADCSRA |= (1<<ADSC);				// Start ADC Sample
}

I have written it early and I assume it is sort of round robin interrupt driven ADC scan?

MM

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

Quote:

I have written it early and I assume it is sort of round robin interrupt driven ADC scan?

Well, I'd try to streamline that ISR as much as practical--remember that you are going to run it every ~100-200us. And GCC isn't known for skinny ISRs.

Do a Forum search for "round robin lee" all words.

CodeVision Wizard will make one for you.

Quote:

I am hoping that can be done quick as possible

Do you realize from my previous post that doing the round-robin >>is<< nearly "quick as possible". Yes, hard polling is faster but then you are tying up nearly all of your processing time. Or running wildly out of spec and getting virtually meaningless results--what is the use of an app closing the loop every ms using data values good to only a few bits?

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

Do not put "wait for XXX" operations inside ISRs, ever! Since every rule needs an exception or two, I could relent and add the clause, "unless the maximum possible wait time is roughly the same as the handful of microseconds that returning from and then reentering the ISR would take".

If you want to run the ADC over a set of channels in free-running mode, just be aware of the pipelined nature of the operation of the analog sampling operation, relative to the setting in the ADMux register and the "conversion complete" interrupt.

From too-lazy-to-recheck-the-spec memory, by the time you enter your ISR, the A/D converter has already sampled and begun to convert the analog signal selected by ADMUX. Presuming that you want to sample in a round-robin fashion at the maximum rate, the just-completed conversion result should be for the channel previous to the one that ADMUX points to now. So, in the ISR, you should do someting like

    int8_t muxTemp = ADMUX;
    int8_t convertedChannel = muxTemp - 1;
    if (convertedChannel < 0) {
        convertedChannel = channelQty - 1;
    }
    results[ convertedChannel ] = ADCW;
    if (++muxTemp >= channelQty) {
        conversionCycles++;
        muxTemp = 0;
    }
    ADMUX = muxTemp;

Then be aware that it takes a couple conversions for this pipelined monitoring process to initialize.

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

Levenkay wrote:
Do not put "wait for XXX" operations inside ISRs, ever! Since every rule needs an exception or two, I could relent and add the clause, "unless the maximum possible wait time is roughly the same as the handful of microseconds that returning from and then reentering the ISR would take".

If you want to run the ADC over a set of channels in free-running mode, just be aware of the pipelined nature of the operation of the analog sampling operation, relative to the setting in the ADMux register and the "conversion complete" interrupt.

From too-lazy-to-recheck-the-spec memory, by the time you enter your ISR, the A/D converter has already sampled and begun to convert the analog signal selected by ADMUX. Presuming that you want to sample in a round-robin fashion at the maximum rate, the just-completed conversion result should be for the channel previous to the one that ADMUX points to now. So, in the ISR, you should do someting like

    int8_t muxTemp = ADMUX;
    int8_t convertedChannel = muxTemp - 1;
    if (convertedChannel < 0) {
        convertedChannel = channelQty - 1;
    }
    results[ convertedChannel ] = ADCW;
    if (++muxTemp >= channelQty) {
        conversionCycles++;
        muxTemp = 0;
    }
    ADMUX = muxTemp;

Then be aware that it takes a couple conversions for this pipelined monitoring process to initialize.

I am intrigued with your code, I have noticed you did not include ADCSRA |= (1<<ADSC), is that because the ADC sample is completed and interrupt is generated then change the ADC channel by adding value to ADMUX up to 8 channels?

MM

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

maverickmax wrote:
Levenkay wrote:
So, in the ISR, you should do someting like
    int8_t muxTemp = ADMUX;
    int8_t convertedChannel = muxTemp - 1;
    if (convertedChannel < 0) {
        convertedChannel = channelQty - 1;
    }
    results[ convertedChannel ] = ADCW;
    if (++muxTemp >= channelQty) {
        conversionCycles++;
        muxTemp = 0;
    }
    ADMUX = muxTemp;

Then be aware that it takes a couple conversions for this pipelined monitoring process to initialize.

I am intrigued with your code, I have noticed you did not include ADCSRA |= (1<<ADSC), is that because the ADC sample is completed and interrupt is generated then change the ADC channel by adding value to ADMUX up to 8 channels?

MM

Yes; I didn't show the initialization, but the intent is to start the ADC in free-running mode, so you don't need to keep restarting it, you just change ADMUX to keep cycling through the channels you want to take samples from.

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

Since I took your advice, I have implemented a round robin ADC interrupt driven based on free running mode. I could not get any reading from all of ADC channels.


void ADCInitalization(void)
{
	ACSR = (1 << ACD);	// Disable Analog Comparator & Reduce power consumption

	SFIOR = (0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);	// Timer/Counter1 Overflow

	ADMUX=ADC_VREF_TYPE | (1 << ADLAR) | 0;

	ADCSRA = (1<<ADEN)   |          	 			// ADC enable 
        	 (1<<ADSC)   |               			// start conversion 
			 (0<<ADATE)	 |
			 (0 << ADIF) |							// ADC Complete Flag
			 (1 << ADIE) |							// ADC Interrupt Enable
        	 (0<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);   		// 128 prescalar 	
}


ISR(ADC_vect) 
{
	PORTB ^= (1 << GREEN_LED);
	if(dumbSample==1)
	{
		// Discard first dummy ADC data
		dumbSample=0;
	}
	else
	{
		ADMUX = ADCChannel | ADC_VREF_TYPE;
		ADCResult=ADCW;  
		ADCChannel++;
		ADCSample[ADCChannel]=ADCResult;
		if(ADCChannel==7){ADCChannel=0;}
	}
		PORTB ^= (1 << GREEN_LED);
}

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

I forget to enable ADATE in order to activate the free running mode. I stll couldnot get 8 samples from all of ADC channels. However if I run on single changle, it will work.


ISR(ADC_vect) 
{
	if(dumbSample==1)
	{
		// Discard first dummy ADC data
		dumbSample=0;
	}
	else
	{
		ADMUX = ADCChannel | ADC_VREF_TYPE;
		ADCResult=ADCW;  
		ADCSample[ADCChannel]=ADCResult;
;
		if(ADCChannel==7)
		{
			ADCChannel=0;
			PORTB ^= (1 << GREEN_LED);
		}
		ADCChannel++;

	}
}


void ADCInitalization(void)
{
	ACSR = (1<<ACD);	// Disable Analog Comparator & Reduce power consumption

	SFIOR = (0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);	// Timer/Counter1 Overflow

	ADMUX= ADC_VREF_TYPE | (0 << ADLAR) | 0;

	ADCSRA = (1<<ADEN)   |          	 			// ADC enable 
        	 (1<<ADSC)   |               			// start conversion 
			 (1<<ADATE)	 |
			 (0 << ADIF) |							// ADC Complete Flag
			 (1 << ADIE) |							// ADC Interrupt Enable
        	 (0
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

At least your prescaler bits are wrong, all zeros means /2. /128 is all ones.

There's also a bug in how you increment the channel number in the ISR which means channel 0 will not be sampled. I suggest you change it to something like

ADCChannel = (ADCChannel + 1) & 7;
if (ADCChannel == 0)
{
    PORTB ^= (1 >> GREEN_LED);
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why use ADATE if using multiple channels? Why not just:

1) set ADMUX
2) trigger conversion (ADSC)
3) either wait or use interrupt
4) collect result when ready
5) go to (1)

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

anders_m wrote:
At least your prescaler bits are wrong, all zeros means /2. /128 is all ones.

There's also a bug in how you increment the channel number in the ISR which means channel 0 will not be sampled. I suggest you change it to something like

ADCChannel = (ADCChannel + 1) & 7;
if (ADCChannel == 0)
{
    PORTB ^= (1 >> GREEN_LED);
}

Thank you for pointing my silly errors however I still cannot sample all of adc channels because I changed my pot on channel 0 while the rest are not connected to anything and yet I get the reading on every channel on my debug! Why?

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

connect your other channels to ground, and see what you get.

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

What code are you actually using?

Are you still using free-running? Why in the world would you want to do that? [apologies to Levenkay]

If you run continuous round-robin conversions there is really no need to do the explicit discard of the first conversion, as you will soon get a new "better" value anyway.

If you are still running with a way overclocked ADC you will indeed get channel "bleeedover", especially with low signal drive and no cap on the input pin(s).

Unconnected pins can read any value.

[Gee, it sounds like I've said this all before]

In the general case, the high bits of ADMUX have the reference selection and other options, and shouldn't be ignored.

Didja look at any of the "round robin lee" hits on prior discussions?

It really >>is<< this easy and compact:

// ADC interrupt service routine
// with auto input scanning
interrupt [ADC_INT] void adc_isr(void)
{
register static unsigned char input_index=0;

// Read the AD conversion result
   adc_raw[input_index]=ADCW;
// Select next ADC input
   if (++input_index >= ADC_CHANNELS)
      {
      input_index=0;
      }

   ADMUX=(FIRST_ADC_INPUT|ADC_VREF_TYPE)+input_index;

// Start the AD conversion
   ADCSRA |= (1 << ADSC);
} 

... and at an ADC clock of ~200kHz you get 10ksps+ to meet your goals and still run the ADC within spec.

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

theusch wrote:
What code are you actually using?

Are you still using free-running? Why in the world would you want to do that? [apologies to Levenkay]

If you run continuous round-robin conversions there is really no need to do the explicit discard of the first conversion, as you will soon get a new "better" value anyway.

If you are still running with a way overclocked ADC you will indeed get channel "bleeedover", especially with low signal drive and no cap on the input pin(s).

Unconnected pins can read any value.

[Gee, it sounds like I've said this all before]

In the general case, the high bits of ADMUX have the reference selection and other options, and shouldn't be ignored.

Didja look at any of the "round robin lee" hits on prior discussions?

It really >>is<< this easy and compact:

// ADC interrupt service routine
// with auto input scanning
interrupt [ADC_INT] void adc_isr(void)
{
register static unsigned char input_index=0;

// Read the AD conversion result
   adc_raw[input_index]=ADCW;
// Select next ADC input
   if (++input_index >= ADC_CHANNELS)
      {
      input_index=0;
      }

   ADMUX=(FIRST_ADC_INPUT|ADC_VREF_TYPE)+input_index;

// Start the AD conversion
   ADCSRA |= (1 << ADSC);
} 

... and at an ADC clock of ~200kHz you get 10ksps+ to meet your goals and still run the ADC within spec.

Lee

Dear sir

Let me start again, you advised me to use single conversion instead of free running mode so I am going to follow your advice but I need to know the reason.

Secondly I am currently using AVRStudio and WINAVR.

I am going to adjust the code which you just gave me now.

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

Quote:

Let me start again, you advised me to use single conversion instead of free running mode so I am going to follow your advice but I need to know the reason.

Do you understand that "if you are free-running and you change the mux in the ADC ISR the next result will be from the previous channel"?

Levenkay apparently likes to do free-running and take that into account. I prefer to do the single-conversion. Sometimes Im doing a little more in the ISR such as "quick trip checking".

With the free-running you will get more conversions per second. (but for your stated requirements you only need 8ksps) Lessee--at 200kHz ADC clock each conversion takes 65us, resulting in 15ksps.

If you use the single-conversion method, then the ISR servicing time until the next conversion is started comes into play. Let's say that is 5us--40 cycles at 8MHz--and now we are at 70us per conversion, or 14ksps. If it is 10us, then 13ksps.

Now, if you have long interrupt latencies 'cause you are doing a lot of stuff in other ISRs then the sample rate would drop. Just don't do that.

In either case, this mechanism takes less than 10% of your AVR. With your original polling-ADC you were taking nearly all of your AVR at rated ADC clock rate and resorted to overclocking which won't get good results.

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.

Last Edited: Thu. Mar 4, 2010 - 03:44 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have done what you advised me to do but I still get the same problem.

I have connected channel 1 to 7 to 0V while channel 0 is connected to POT, according to my debug, the adc 0 - 643 ADC 1 - 568 and rest of channel are zero. I am a bit puzzled with this.


ISR(ADC_vect) 
{
	static unsigned char input_index=0;

	if(dumbSample==1)
	{
		// Discard first dummy ADC data
		dumbSample=0;
	}
	else
	{
	
		// Read the AD conversion result 
 		ADCSample[input_index]=ADCW; 

		// Select next ADC input 
   		if (++input_index >= 8) 
      	{ 
      		input_index=0; 
					PORTB ^= (1 << GREEN_LED);
      	} 

   		ADMUX=( 0 |ADC_VREF_TYPE)+input_index; 

	}

	// Start the AD conversion 
   		ADCSRA |= (1 << ADSC);
}
Last Edited: Thu. Mar 4, 2010 - 03:46 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
Quote:

Let me start again, you advised me to use single conversion instead of free running mode so I am going to follow your advice but I need to know the reason.

Do you understand that "if you are free-running and you change the mux in the ADC ISR the next result will be from the previous channel"?

I was not fully aware of this but now I understand.

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

Quote:

I have done what you advised me to do but I still get the same problem

What problem, specifically, and with what code?

What is your ADC clock? And

Quote:

Unconnected pins can read any value.

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

theusch wrote:
Quote:

I have done what you advised me to do but I still get the same problem

What problem, specifically, and with what code?

What is your ADC clock? And

Quote:

Unconnected pins can read any value.

I have connected every adc channel to pot and change the prescale from 2 to 4. I have the reading from all adc channels are improving but I have noticed one of my channel is generating 712 and my voltage reading in 2.5V so I expect it should be 512 roughly. Is summat do with accuracy?

It seemed that prescale 2 for adc clock cause problem in sampling. If it is true, why did datasheet never mention it? Unless I have overlooked something. Can someone remind me the calculation of ADC clock?

MM

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

Don't just guess at the prescaler. Based on your F_CPU it should be picked to bring the ADC clock into the 50kHz..200kHz range (as the datasheet says).

If, for example you clocked the AVR at 8MHz then one would need to use a /64 prescaler to give a clock of 125kHz (it's the only one in the 50 .. 200 range).

By a strange quirk of fate it's therefore sometimes an idea to actually run the AVR slower. Say you used a 6.4MHz clock speed then a /128 prescaler would give you 200kHz which is as fast as the ADC can be clocked to follow datasheet guidance for 10 bit sampling.

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

Quote:

Can someone remind me the calculation of ADC clock?

How often in this thread have the issue of ADC clock rate been brought up?

You have several times quoted my entire response, but apparently don't read it--in my first response I asked for your AVR's clock speed--no reply. How can we spoon-feed you a prescaler number without knowing that?

Quote:

If it is true, why did datasheet never mention it? Unless I have overlooked something. Can someone remind me the calculation of ADC clock?


Exactly what part of the datasheet are you looking at? Perhaps start with the Analog-to-Digital Converter chapter. And then the Prescaler section...
Quote:
By default, the successive approximation circuitry requires an input clock frequency between 50 kHz and 200 kHz to get maximum resolution

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

theusch wrote:
Quote:

Can someone remind me the calculation of ADC clock?

How often in this thread have the issue of ADC clock rate been brought up?

You have several times quoted my entire response, but apparently don't read it--in my first response I asked for your AVR's clock speed--no reply. How can we spoon-feed you a prescaler number without knowing that?

Quote:

If it is true, why did datasheet never mention it? Unless I have overlooked something. Can someone remind me the calculation of ADC clock?


Exactly what part of the datasheet are you looking at? Perhaps start with the Analog-to-Digital Converter chapter. And then the Prescaler section...
Quote:
By default, the successive approximation circuitry requires an input clock frequency between 50 kHz and 200 kHz to get maximum resolution

Look I have seen somewhere that you can exceed ADC clock without any difficulties but I have ran number of problems and I acknowledged my errors and I am going to pay more attention in the datasheet. Sorry for frustrating you as well as myself.

I admit that I am disappointed to find out that AVR chip can only sample at max 5us. In fact, I am hoping to sample at 1us, 1.33us and 1.66us for three phase signals

MM

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

...and you still have not given us your AVR's clock rate.

If you want to do real work with analysis of 3-phase signals, then use an Analog Devices ADE7xxx chip where all the information is gathered for you to energy-billing precision.

The Xmega has a faster ADC, and DMA, and twin ADCs on larger models.

Quote:

I admit that I am disappointed to find out that AVR chip can only sample at max 5us.

5us? No, 65us at the highest recommended clock rate.

I'm out.

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

My current ADC Clock is 125kHz which is within 50kHz and 200kH (Prescaler - 64). Thank you for letting me know about ADE7xxx chip. Can you please share the infromation about 65us clock rate?

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

200kHz is the maximum ADC clock rate, not the maximum sample rate. The conversion takes more than one ADC clock.

Regards,
Steve A.

The Board helps those that help themselves.

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

clawson wrote:
If, for example you clocked the AVR at 8MHz then one would need to use a /64 prescaler to give a clock of 125kHz (it's the only one in the 50 .. 200 range).
At 8MHz a /128 prescaler gives 62.5kHz which works fine ... but you already knew that.