Analoginput circuit serves any microcontroller
The simple ADC in Figure 1 is perfect for getting analog signals into a purely digital microcontroller. Using just five surfacemount parts, you can assemble it for less than 50 cents (1000), which is approximately half the cost of a singlechipADC approach in the same volume. Moreover, this design takes only one pin from the microcontroller to operate. Although you can purchase many microcontrollers with builtin ADCs, in some circumstances, this solution is impractical. For example, you might have an alldigital microcontroller already designed in. In this design, a USBcompatible, digitalonly microcontroller needed analog input at low cost for a consumer application. The basic analog portion of the circuit in Figure 1 uses clever transistor arrays from Panasonic (www.panasonic.com). Q_{1}/Q_{2} and Q_{3}/Q_{4} are singlepackage, multipletransistor arrays. The Q_{1}/Q_{2} array forms a voltagetocurrent converter. The voltage on Q_{1}'s emitter is a diode drop higher than the voltage on Q_{1}'s base. The V_{BE} drop in Q_{2} returns the original input voltage to the top of R_{1}; R_{1} then converts that voltage to a current.
The Q_{3}/Q_{4} array forms a standard currentmirror circuit. The current flowing in Q_{3}'s collector matches the current forced in Q_{4}'s collector.Q_{4}'s collector has high impedance, so Q_{4} provides a suitable current source. The current from Q_{4} charges C_{1} at a rate that is proportional to the input voltage. The values in Figure 1 allow for a range of conversion times of 3 msec for an input of 4V to 56 msec for an input of 0.1V. The design exploits the fact that most generalpurpose microcontrollers have a bidirectional I/Oport structure. That is, you can program a port pin as either an input or an output. When you set a pin as an input, it has very high input impedance, so it can follow the ramp as C_{1} charges up. When you program a pin as an output, you can set it low, and it discharges C_{1} for the next conversion cycle. This action gives you the basic operation of a singleslope analogtodigitalconversion cycle. The basic operations are as follows:

Set the ADC pin as a low output to discharge C_{1}.

Reset a suitable timercounter in the microcontroller.

Set the ADC pin as an input.

Allow the timer to count until it reads as logic 1 in the microcontroller, or let the timer count to some suitably long value, which suggests that the input is essentially zero.

Stop the timer counter.

Convert to the timer count by some suitable scaling factor to an ADC reading.

Start over for the next conversion.
The conversion from the ramp time to a logic 1 on the microcontroller pin depends on the following factors:

the logic1 switching level of your microcontroller;

the input voltage and, hence, the ramp rate of C_{1};

the value of C_{1}, which sets the ramp rate;

the value of R_{2}, which sets the ramp rate; and

the microcontroller's timer resolution.
You can boil down these variables to the following equation:
where V_{L} is the voltage level of the microcontroller's zerotoone conversion, K is the scaling factor that relates to the voltagetocurrent conversion of the input stage and timer resolution, and dT is the time count of the conversion cycle. Because C_{1}V_{L} is also a constant for a given circuit, you can combine it with K to form a single conversion constant of K_{1}. Hence, you can reduce the equation to K_{1}/dT=V_{IN}.
In this case, the test code was written for Microchip Technology's (www.microchip.com) PIC16F84 microcontroller. This device has a measured V_{L} of 1.28V; the counter has a resolution of 1 µsec. It's probably best to empirically determine the factor K_{1}. Set up the counter resolution as desired, allow the microcontroller to make and display that conversion time or send it through a debugger, and, given that you have an exact V_{IN}, K_{1} is then easy to determine. In this case, K_{1} turned out to be 2V×5700 µsec=11,400.
The constant K_{1} serves to convert the raw timer count to a voltage. To obtain high resolution, you normally use floatingpoint math. If you need to display the value, floatingpoint math might be appropriate, but most applications entail reading a potentiometer or some other system level. In such applications, the output is a barchart display or some control value. Thus, you waste microcontroller resources by using floatingpoint math throughout the conversion process. With careful selection of circuit components, fixedpoint math can usually provide, for example, an 8bit representation (0 to 255) for an input range of 0 to 4V. If you scale the timer/counter by 64, instead of a count of 5700 µsec for an input of 2V, you obtain 89. Then, if you want this 89 to correspond to a halfscale value of 128, the value of K_{1} becomes 11,392. A 16bit unsigned word easily accommodates this value, and you need no floatingpoint math in the conversion. The accuracy of this ADC is approximately 5% with no adjustments. The resolution is a function of the timer resolution and how tight the code makes the conversion loop. The resolution can be many times the absolute accuracy. Moreover, the converter is monotonic.
Is this the best Design Idea in this issue? Vote at www.ednmag.com.
System level design and integration challenges with multiple ADCs on single chip
Understanding the basics of setup and hold time
Product Howto: Digital isolators offer easytouse isolated USB option
Managing noise in the signal chain, Part 2: Noise and distortion in data converters
War of currents: Tesla vs Edison
Simple reversepolarityprotection circuit has no voltage drop
Control an LM317T with a PWM signal
Start with the right op amp when driving SAR ADCs