Oversampling ATmega16

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

Hello !

As you know the ATmega16 have ADC with10 bits resolution and i need convert an analog voltage but very precisely.
So i want to do the converttion with 13 bits ressolution.

Someone know how build the program for an Oversampling ??

Thank

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

Use an external ADC.

Leon Heller G1HSM

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

You have to oversample by a factor of 4 for each bit of improvement. So, 13 bits with a 10 bit ADC could, theoretically, be achieved oversampling at a rate 4*4*4 = 64 times for each output sample. You would then average 64 10-bit samples to get your 13 bit value.

Thus, if you need data at 1KHz sample rate, you would have to sample at 64KHz.

Be aware that over-sampling only improves resolution. It does NOT improve accuracy. That is limited by the reference.

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

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

What are you measuring? If its just sitting there wiggling in one spot, like a dc voltage, then adding extra samples works. If its moving, that trick doesnt work so good. adding 2 samps gives 11 bits, 4 samps 12 bits, 8 samps 13 bits.

Imagecraft compiler user

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

In fact i need to convert a analog voltage who move between 0 and 10 V.

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

I tested it with several AVRs, it's not possible.
Even on the sum of 1024 samples you get no additional bit resolution.
The reason was, the ADC has to less noise.
It's characteristic was almost an ideal staircase.

E.g. I wanted to measure 3000V and thus I add 64 samples and divide by 22.
The samples are made every 20ms/64 to get 50Hz suppression, so the display was very stable.
But the display shows only 0V, 3V, 6V, 9V and so on.

Peter

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

With the new ATMEL website the only way I could find this was with the ATMEL advanced search. Good thing I already knew it was there since there is no way to browse all the application notes any longer. I could not find the oversampling appnote with any mega documents links.

AVR121: Enhancing ADC resolution by oversampling
http://www.atmel.com/dyn/resourc...
http://www.atmel.com/dyn/resourc...

Also see:
AVR120: Characterization and Calibration of the ADC on an AVR
http://www.atmel.com/dyn/resourc...

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

Quote:
I tested it with several AVRs, it's not possible.

what about dithering? Oversampling is not magic, and it really works, but at the cost of bandwidth. That implicates further consequences, like antialiasing filters for higher frequencies. So, in theory, you are able to measure any signal with any resolution as long as your signal is within measured bandwidth.

Quote:
analog voltage who move between 0 and 10 V

The move is not a problem. The problem is how fast it moves..

No RSTDISBL, no fun!

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

danni, I had no idea it was so clean, I thought the trick to add noise like in AVR121 appnote (already linked by Mike B) was just for reference, but it really is needed.

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

Brutte wrote:
what about dithering? Oversampling is not magic, and it really works, but at the cost of bandwidth.

But it can not be done only in software.

You need additional hardware.
A sawtooth generator and a summation amplifier to shift the ADC staircase around one bit during the conversions.

So its easier, the additional hardware was an external ADC of the wanted resolution.

Peter

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

danni wrote:

E.g. I wanted to measure 3000V and thus I add 64 samples and divide by 22.

Peter

64 samples would imply that you are going to add 3 bits of effective resolution. 4^3. You should add 64 samples and then shift right by 3 (divide by 8 ). This will increase your effective resolution to 13 bits on a 10 bit adc.

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

Quote:
This will increase your effective resolution to 13 bits on a 10 bit adc.
Not if the input does not meet specifications. There MUST be sufficient noise at sufficient frequencies in order for this technique to work. For the example given, the noise must be on the order of +/- 1.5V. If the noise is significantly less than this, then multiple readings will get you nowhere, you will simply get the same value each reading.

Regards,
Steve A.

The Board helps those that help themselves.

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

Or if there is > 1/2 bit noise on the adc reference. Almost never a problem. Toggle some I/O during the conversion if it is. Try it and see what happens. I was primarily trying to point out that dividing by 22 is not ideal for oversampling

Koshchi wrote:
Quote:
This will increase your effective resolution to 13 bits on a 10 bit adc.
Not if the input does not meet specifications. There MUST be sufficient noise at sufficient frequencies in order for this technique to work. For the example given, the noise must be on the order of +/- 1.5V. If the noise is significantly less than this, then multiple readings will get you nowhere, you will simply get the same value each reading.

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

That's a clever idea.... modulate the aref by 1 lsb.

Imagecraft compiler user

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

Hint to Dani and others - when you compute the average, DO NOT throw away the fractional part of the answer!

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

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

I've found this thread because I was trying to analyze the following code

int
AD (void)
{
	int sum=0;
	uint8_t i=0;

	/* The AD conversion should not be done during change of the PWM signals. 
	 * The time consumed by this routine is ca. ( 25 + 8 * 13 ) * 8 µs = 1.032 ms 
	 * (or 250µs longer, if the pwm change is hit; this can only happen once in an update cycle).
	 * So it could be called 3 times during one update cycle, leaving ca. 1 ms for calculations.
	*/

// here, you should deactivate all other interrupts except ADC_ready
// to avoid noise on the measurement results and to make sure that 
// wake up from sleep is only due to ADC_ready
	
	ADCSRA |= _BV(ADSC);		/* start AD conversion */ 
	sleep_mode();				/* the first conversion result is discarded */
	
	sum=0;
	
	for (i=0; i<=7; i++)
	{
		while (TCNT1 > 0x7FFF-1000);
		while (TCNT1 < 1000);
		while ( (TCNT1 > OCR1A-1000) && (TCNT1 < OCR1A+1000) ); // wait until pwm change has passed
		// one AD conversion needs 832 clock cycles
		// by this 2000 clock cycles (=250µs, 6,25%) are not used for conversion in one update cycle (4 ms)
		ADCSRA |= _BV(ADSC);	/* start AD conversion */ 
		sleep_mode();			/* wait until conversion is complete */
		sum = sum + ADC; 		/* result is a 13 bit value (max 0x1FFF) */
	}
	
// here, you should activate again all other interrupts, which were deactivated above	
	
	return sum;
}

According to the comments this is a 13 bit value ADC which yes, if you see the for loop runs 8 times by 1024 is 8192, the maximum possible value of the variable sum out of this routine.

But all the other postings here talk about 64 required samples to end up with the 13 bit resolution. This would require 832 cpu cycles ( which is even mentioned in one of the comments on above code). But the routine makes only 8 samples.

There is also a

EMPTY_INTERRUPT(ADC_vect)

Which I think is needed to get out of the sleep mode.

Is this really a 13 bit emulation ? or I am missing a number 8 somewhere that multiplied by the 104 would end up on the 832 cycles required ?

Thanks a million in advance for any help guidance on this.

Jose

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

Quote:
According to the comments this is a 13 bit value ADC which yes, if you see the for loop runs 8 times by 1024 is 8192, the maximum possible value of the variable sum out of this routine.
Just because you have a 13 bit number doesn't mean that you have created an ADC with 13 bit resolution.
Quote:
This would require 832 cpu cycles
No, this is the time for one ADC conversion. For 64 samples that would mean 53248 cycles.

Regards,
Steve A.

The Board helps those that help themselves.

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

Steve,

Thanks for your response , but first of all, I did not write the routine and much less I am saying it is a 13 bit resolution. I am trying to understand the code as well as understanding the subject of this thread. At first glance the code seems to be much better than just making one ADC reading; for me it looks like an 8 sample averaging provided the signal bandwidth allows for that ie the signal does not change during the total time required to run the 8 measurements.

On the 832 cycles, OK, my bad it is 13 ADC cycles or 13X64 CPU cycles (this is a 8MHZ internal clock with a 125 KHZ ADC clock).

Thanks,

Jose.