ADC
Function
ANALOG MEETS DIGITAL
Regardless if you are an
analog or digital person, sometimes you have to get from one domain to the
next. We'll use VBA to create one of the simplest ADC functions possible
-
ADC_Function.xlsm.
But even this simple implementation will throw some light onto ADC concepts such as LSBs,
resolution, output counts and speed. (For other topics see the
VBA page.)
The ADC operation can be defined by a few parameters.
N Bits -
Defines how many binary bits represent the analog voltage.
Vmin -
The minimum analog voltage to be converted to digital output.
Vmax - The maximum analog voltage to be converted to digital
output.
How does an ADC work? It essentially divides
the analog range (Vmin to Vmax) into 2^N levels. For each level, there's a corresponding digital value from 0 to 2^N-1.
The ADC takes the input voltage, finds the closest discrete analog level and
assigns the corresponding digital count to the ADC output.
Between any
two levels, the voltage difference is V_LSB = (Vmax-Vmin)/2^N. For a N = 3 bit converter
whose input range is 0 to 4V, the converter looks like this.
Levels |
8 |
2^N |
|
V LSB |
0.5 |
(Vmax-Vmin)/2^N |
You can't measure, or resolve, any voltage
smaller than the V_LSB = 0.5V. If you need more resolution, increase the
number of bits.
THE ADC CODE
The VBA code for the ADC is fairly
simple: step thru all possible codes to find the closest discrete level to the input voltage,
and then assign
the corresponding digital value to the ADC's output.
Function ADCout(Vin, N, Vmin, Vmax)
' calculate ADC digital output given analog input voltage
Dim LSB, Vlevel, VthreshHI, VthreshLO As Double
Dim Count, CountMax As Integer
' find V_LSB and maximin digital output
LSB = (Vmax - Vmin) / (2 ^ N)
CountMax = (2 ^ N) - 1
ADCout = 0
' run sequentially through all possible ADC counts
For Count = 0 To CountMax
' calc the analog level for this
count
Vlevel = Vmin + Count * LSB
' calc the thresholds above and below
the level
VthreshHI = Vlevel + 1 / 2 * LSB
VthreshLO = Vlevel - 1 / 2 * LSB
' if the input voltage is in the range,
' assign the Count to the ADC output
If Vin > VthreshLO And Vin <= VthreshHI Then ADCout = Count
Next Count
' final check - for inputs below or above the analog range.
If Vin <= Vmin Then ADCout = 0
If Vin >= Vmin + 1 / 2 * LSB + CountMax * LSB Then ADCout = CountMax
End Function |
To see the VBA code hit ALT-F11 and double
click on the Modules > Module1 in the VBA Project window.
The code runs sequenctially through every possible ADC
count For Count = 0 To CountMax.
For each count, the corresponding discrete level is calculated
Vlevel = Vmin + Count * LSB
Next, the thresholds VthreshHI and
VthreshLO are found, which define a voltage range 1/2 LSB above and 1/2 LSB below
Vlevel.
VthreshHI = Vlevel +
1 / 2 * LSB
VthreshLO = Vlevel - 1 / 2 * LSB
For last step, the code checks if Vin
falls between the thresholds. If yes, then the current count is
assigned to the ADC output., If not, then move on to the next count.
After all the Counts have been run
through, there's a final check if Vin fell outside the min or max
discrete levels. If so, the ADC output gets assigned a 0 or CountMax.
Yes, you might say, this is an overly simplified strategy to
convert voltages to codes. Correct! There are faster ways, but
they all improve on the understanding of this basic scheme.
3-BIT LSB, LEVELS AND THRESHOLDS
For the initial run, we'll check out an N = 3 bit
converter with Vmin=0V and Vmax=4V. This converter divides the range into
2^3 = 8
discrete levels with an V_LSB=0.5V. The code will run through every count, 0
to 7. Here's a table of Counts and Vlevel along with the HI and LO thresholds
for each level.
Count |
Vlevel |
VthreshHI |
VthreshLO |
0 |
0.0 |
0.25 |
-0.25V |
1 |
0.5 |
0.75 |
0.25 |
2 |
1.0 |
1.25 |
0.75 |
3 |
1.5 |
1.75 |
1.25 |
4 |
2.0 |
2.25 |
1.75 |
5 |
2.5 |
2.75 |
2.25 |
6 |
3.0 |
3.25 |
2.75 |
7 |
3.5 |
3.75 |
3.25 |
Its all straight forward except for two
special cases, 0 and 7. For count=0, the LO threshold is less than Vmin=0V.
But that's okay because the final check in the code assigns count=0 to all
Vin < Vmin. For count=7, the HI threshold of 3.75V doesn't quite reach Vmax=4V.
That's okay too because the final check assigns Count=7 for Vin>3.75V.
ADC IN ACTION
Let's test our ADC in the Excel sheet named "ADC
Ramp" by applying a ramp input
using the Triangle Wave generator.
Column Vin calls the Tri_Wave( ) function which calculates the waveform
based on the the traiangle parameters and the time
column. The triangle wave ramps from 0V to 4V for 10 us and then down again. The next
column shows ADC output calculated by the VBA function ADCout( ).
The last column the voltage level corresponding to the digital count is shown in the
last column called by VADVout( ). This last function simply calculates the
analog level versus count using
VADCout
= Vmin + Counts * LSB.
The table below shows the results for the
initial time segment.
time |
Vin |
ADCout (counts) |
VADCout (V) |
0.0000 |
0.00 |
0 |
0.00 |
0.0001 |
0.04 |
0 |
0.00 |
0.0002 |
0.08 |
0 |
0.00 |
0.0003 |
0.12 |
0 |
0.00 |
0.0004 |
0.16 |
0 |
0.00 |
0.0005 |
0.20 |
0 |
0.00 |
0.0006 |
0.24 |
0 |
0.00 |
0.0007 |
0.28 |
1 |
0.50 |
0.0008 |
0.32 |
1 |
0.50 |
0.0009 |
0.36 |
1 |
0.50 |
0.0010 |
0.40 |
1 |
0.50 |
0.0011 |
0.44 |
1 |
0.50 |
In the Excel file, the first plot shows the
triangle wave's rising edge ramping
through the ADC's analog range of 0 to 4V. The second plot shows the output
(ADCout) of the ADC ranging from 0 to 7. Returning to the first graph,
the discrete voltage level for each count (VADCout) is plotted right on top of the
ramp. Hey this thing actually works! Check out how the ADCout changes at the
thresholds calculated in the first table above.
INCREASING RESOLUTION
You have to admit it, the 3 bit ADC does a
poor job of capturing the ramp input. Try increasing the resolution to 4 or
5 bits. What does the captured triangle look like now? Nice! The higher the
resolution, the smaller the LSBs and the smoother the ramp becomes. This
could be important if that ramp represents a changing temperature, EKG
signal, video brightness or music signal that you are measuring or storing.
Try increasing the bits to 8 or 10 which gives you 256 or 1024 discrete
levels.
Sometimes a mismatch between the amplitude of your signal and
the ADC range leads to poor resolution. Suppose your ramp is from V1=0V to
V2=1V and you have an 8-bit ADC with an input range of Vmin=0V to Vmax=10V.
How does your digitized ramp appear now? Even with 8-bits resolution, the
ramp looks like crapola. Now imagine that you placed a 10x amplifier before
the ADC to boost your signal from 1V to the 10V full scale. Change V2 to 10V and
check if the ramp looks better than before.
TOO SLOW
If a small LSB is important, why not increase
the resolution to 16 bits (65536 levels) and beyond? Depending on your PC
speed, the higher resolution calculations may take some time to compute.
Why? For 16-bits (65536 levels) and 100 time points, the function will loop
through the code a total of 100*65636 = 6,563,600 times! That's because this
algorithm is a bit simple minded. It runs through every possible count from
0 to CountMax, regardless of Vin. Similarly, an actual ADC implemented in
hardware fights the same challenge, the more bits you have, the slower the
conversion.
So the challenge becomes, how can you speed
up the conversion process? One way is through the Successive Approximation
algorithm which dramatically speeds up the process. What is the strategy of
this method?
TRY IT!
- Copy the Excel sheet
to a new one. Instead of a triangle wave, apply a sine wave to the
input. You can also check out the sine wave code in the topic
Sine Wave Generator.
Back to Topics
|