Electronic Design with Excel


  Topics | VBA Basics | Back to eCircuit Center


ADC Function



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.xls. 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.

N Bits 3
Vmin 0
Vmax 4
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 VBA code for the ADC is fairly simple: find the closest discrete level to the input voltage and 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 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.



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.



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.



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.



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. We'll take a look at this in another topic.



  1. Copy the Excel sheet to a new one. Instead of a triangle wave, apply a sine wave to the input. You can check out the sine wave code in the topic Sine Wave Generator.


Back to Topics



  2008   eCircuit Center