Implementation of enhancing ADC resolution by oversampling

From MCS Wiki
Revision as of 12:52, 28 March 2013 by Admin (Talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Contents

Description

Atmel’s AVR controller offers an Analog to Digital Converter with 10-bit resolution. In most cases 10-bit resolution is sufficient, but in some cases higher accuracy is desired. Special signal processing techniques can be used to improve the resolution of the measurement. By using a method called ‘Oversampling and Decimation’ higher resolution might be achieved, without using an external ADC. This Application Note explains the method, and which conditions need to be fulfilled to make this method work properly.

The ADCs reference voltage and the ADCs resolution define the ADC step size. The ADC’s reference voltage, VREF, may be selected to AVCC, an internal 2.56V / 1.1V reference, or a reference voltage at the AREF pin. A lower VREF provides a higher voltage precision but minimizes the dynamic range of the input signal. If the 2.56V VREF is selected, this will give the user ~2.5mV accuracy on the conversion result, and the highest input voltage that is measured is 2.56V. Alternatively one could consider using the ADC input channels with gain stage. This will give the user the possibility of measuring an analog signal with better voltage precision, at the expense of the ADCs dynamic range. If it is not acceptable to trade dynamic range for better voltage resolution, one could choose to trade oversampling of the signal for improved resolution. This method is however limited by the characteristic of the ADC: Using oversampling and decimation will only lower the ADCs quantization error, it does not compensate for the ADCs integral non-linearity.


Table: Resolution option


Enhadc table1.jpg


This method is based on Nyquist theorem that provide in Atmel AVR site

Sensor

One of the most popular applications of the ADXL202E is tilt measurement. An accelerometer uses the force of gravity as an input vector to determine orientation of an object in space. An accelerometer is most sensitive to tilt when its sensitive axis is perpendicular to the force of gravity, i.e., parallel to the earth’s surface. At this orientation its sensitivity to changes in tilt is highest. When the accelerometer is oriented on axis to gravity, i.e., near its +1 g or –1 g reading, the change in output acceleration per degree of tilt is negligible. When the accelerometer is perpendicular to gravity, its output will change nearly 17.5 mg per degree of tilt, but at 45° degrees it is changing only at 12.2 mg per Degree and resolution declines. The following table illustrates the changes in the X and Y axes as the device is tilted ± 90° through gravity.


Table: How the X and Y axes respond to changes in tilt


Enhadc table2.jpg

Test Schematic

Schematic

Example - 13bit

$regfile = "m16def.dat"
$crystal = 8000000
 
'$lib "mcsbyte.lbx"                                          ' for smaller code
 
 
Config Lcdbus = 4
Config Lcdpin = Pin , Db4 = Portb.3 , Db5 = Portb.2 , Db6 = Portb.1 , Db7 = Portb.0 , E = Portb.4 , Rs = Portb.5
Config Lcd = 16 * 2
 
 
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Stop Adc
Dim X As Word , Y As Word , C(2) As Single , N As Word , Sumx As Long , Sumy As Long
Dim Sy As String * 18 , Sx As String * 18 , Vx As String * 14 , Vy As String * 14
Cursor Off
Cls
 
Start Adc
Do
Sumy = 0
Sumx = 0
For N = 1 To 64
Y = Getadc(0)
'Power Adcnoise
X = Getadc(1)
'Power Adcnoise
Sumy = Sumy + Y
Sumx = Sumx + X
Next A
 
'Sy = Bin(sumy)
'Sx = Bin(sumx)
'Vy = Right(sy , 3)
'Vx = Right(sx , 3)
'C(1) = Val(vy)
'C(2) = Val(vx)
C(1) = Sumy / 8
C(2) = Sumx / 8
C(1) = C(1) - 3584
C(2) = C(2) - 3584
C(1) = C(1) * 0.175
C(2) = C(2) * 0.175
 
Locate 1 , 1
Lcd "X=" ; Fusing(c(2) , "#.##")
'Lcd Sy
Locate 2 , 1
Lcd "Y=" ; Fusing(c(1) , "#.##")
'Lcd Sx
Loop
 
 End                                                        'end program

Example - 14bit

$regfile = "m16def.dat"
$crystal = 8000000
 
'$lib "mcsbyte.lbx"                                          ' for smaller code
 
 
Config Lcdbus = 4
Config Lcdpin = Pin , Db4 = Portb.3 , Db5 = Portb.2 , Db6 = Portb.1 , Db7 = Portb.0 , E = Portb.4 , Rs = Portb.5
Config Lcd = 16 * 2
 
 
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Stop Adc
Dim X As Word , Y As Word , C(2) As Single , N As Word , Sumx As Long , Sumy As Long
Dim Sy As String * 18 , Sx As String * 18 , Vx As String * 14 , Vy As String * 14
Cursor Off
Cls
 
Start Adc
Do
Sumy = 0
Sumx = 0
For N = 1 To 256
X = Getadc(0)
'Power Adcnoise
Y = Getadc(1)
'Power Adcnoise
Sumy = Sumy + Y
Sumx = Sumx + X
Next A
 
'Sy = Bin(sumy)
'Sx = Bin(sumx)
'Vy = Right(sy , 4)
'Vx = Right(sx , 4)
'C(1) = Val(vy)
'C(2) = Val(vx)
C(1) = Sumx / 16.0
C(2) = Sumy / 16.0
C(1) = C(1) - 7169
C(2) = C(2) - 7169
C(1) = C(1) * 0.0880
'C(1) = C(1) + 14                                            'callibration value
C(2) = C(2) * 0.0880
'C(2) = C(2) - 14                                            'callibration value
Locate 1 , 1
Lcd "X=" ; Fusing(c(1) , "#.##")
'Lcd Sy
Locate 2 , 1
Lcd "Y=" ; Fusing(c(2) , "#.##")
'Lcd Sx
Loop
 
 End                                                        'end program

Example - 15bit

$regfile = "m16def.dat"
$crystal = 8000000
 
'$lib "mcsbyte.lbx"                                          ' for smaller code
 
 
Config Lcdbus = 4
Config Lcdpin = Pin , Db4 = Portb.3 , Db5 = Portb.2 , Db6 = Portb.1 , Db7 = Portb.0 , E = Portb.4 , Rs = Portb.5
Config Lcd = 16 * 2
 
 
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Stop Adc
Dim X As Word , Y As Word , C(2) As Single , N As Word , Sumx As Long , Sumy As Long
Dim Sy As String * 22 , Sx As String * 22 , Vx As String * 22 , Vy As String * 22
Cursor Off
Cls
 
Start Adc
Do
Sumy = 0
Sumx = 0
For N = 1 To 1024
X = Getadc(0)
'Power Adcnoise
Y = Getadc(1)
'Power Adcnoise
Sumy = Sumy + Y
Sumx = Sumx + X
Next A
 
'Sy = Bin(sumy)
'Sx = Bin(sumx)
'Vy = Right(sy , 5)
'Vx = Right(sx , 5)
'C(1) = Val(vy)
'C(2) = Val(vx)
C(1) = Sumx / 32.0
C(2) = Sumy / 32.0
C(1) = C(1) - 14339
C(2) = C(2) - 14339
C(1) = C(1) * 0.0440
C(1) = C(1) + 14                                            'callibration value
C(2) = C(2) * 0.0440
C(2) = C(2) - 14                                            'callibration value
Locate 1 , 1
Lcd "X=" ; Fusing(c(1) , "#.###")
'Lcd Sy
Locate 2 , 1
Lcd "Y=" ; Fusing(c(2) , "#.###")
'Lcd Sx
Loop
 
 End                                                        'end program

Author

Written by: Mohammad Jafar Dalvand, University of Tehran, Iran

Email Address: Dalvand@ut.ac.ir

Personal tools
Namespaces
Variants
Actions
Navigation
Language