You can assign from one to thirteen pins to be used as analog inputs. These pins are named AN0 through AN12. The set that you use as analog inputs must start with AN0 and must be contiguous, i.e. if you use AN0 and AN3 as analog inputs, you can't use AN1 and AN2 for a different purpose. A statement such as setup_adc_ports(AN0_TO_AN3) selects the range of pins to be used as analog inputs.
The input voltage range is 0 to 5V. Voltages outside this range can damage the PIC. The 0 to 5V range is converted by the PIC's ADC to an 8 or 10 bit positive integer, i.e. to a value 0-255 or 0-1023. A statement such as #DEVICE ADC=10 selects 8-bit or 10-bit ADC resolution.
There is really only one ADC in the PIC, and a bunch of analog switches to connect any one of the thirteen input pins to it. After a change of selected pin, e.g. with set_adc_channel(3) to select input pin AN3, a 10uS delay is recommended so that the ADC can lock in and digitize the new value, before you read it with read_ADC(). You can read_adc() with no delay if you haven't recently changed selected input pin.
In the demo program AnalogInput.c a 10-bit ADC conversion is done, with the low order 8 bits displayed on port D and the high 2 bits displayed on pins C0 and C1.
Reading a trimpot
A simple source for a 0-5V analog level is a potentiometer (a.k.a. trimpot). One use is as an easily adjustable variable value to control operation ofyour program, or some gain factors; the kind of thing you might have otherwise done by querying the user in a text window. Here, just turn the pot.
Reading a phototransistor
A typical circuit for reading light intensity with a phototransistor is shown at right. Greater light level causes a lower voltage at pin AN0, and a lower value read by the PIC's ADC.
Amplification and level shifting
The above circuit used a sensor without amplification, and the output voltage range was intrinsically limited to 0-5V by the supply rails of the circuit. If you wish to use an opamp or instrumentation amp to produce the voltage to be digitized, you will need to limit it to the 0-5V range, and possibly also to level-shift it so that both polarities of sensing are readable. There are many ways to accomplish these things.
The best way is to use a level of 2.5V as your "null" level. If you use a rail-to-rail opamp with supply rails of 0 and 5V, its output is naturally limited to the PIC's analog input range. One convenient way to produce the 2.5V without consuming power in a voltage divider is to use a rail splitter which provides a reference voltage exactly half way between the supply rails.
Above is an amplified phototransistor circuit, which provides 100-fold gain (1M/10K) and a high-pass filter with a time constant of 1mS (10Kohm * 100pF). Thus it responds sensitively to a rapid change in light level, probably caused by a strobed LED or IRED, while ignoring overall (DC) light level.
Strobing an LED or IRED briefly (e.g. 100uS) and infrequently (e.g. every 5 mS) allows you to use 10x the rated steady current, and get 10x more light, without overheating the LED. It also allows you to use a phototransistor circuit that responds only to changes, and your PIC software can compare the light level just before and during the flash. All of these allow greatly improved sensitivity.
The chip is a high-speed rail-to-rail opamp such as LM6132, with supply rails of 0 and 5V. Its non-inverting input is held at 2.5V by the voltage divider, and therefore this is the quiescent level of the inverting input as well -- and of the output. The ADC in 10-bit mode reads about 512.
Perhaps the voltage divider produces not exactly 2.5V, or the ADC maps 2.5V not to exactly half scale? The connection from the 2.5V reference point to analog input AN1 allows the PIC to determine the ADC result corresponding to quiescence.
tip - high gain high speed opamp circuits are often unstable, as you can observe with an oscilloscope (and only with an oscilloscope). Try to eliminate oscillations with a small capacitor (e.g. 10pF) across the feedback resistor (1M here). Always use a supply decoupling capacitor (e.g. 0.1uF) across the supply rails, right near the chip.
Instrumentation amps are often used with full- or half- strain gauge bridges (four or two strain gauge elements). A half-bridge is shown above. The gain of the instrumentation amp is set by a gain resistor according a to a formula in the datasheet, typically gain = 50K/Rgain.
For easy interfacing to a PIC's 0-5V analog input range, use a rail-to-rail instrumentation amp such as AD623. The instrumentation amp subtracts its two inputs, multiplies the difference by the gain, and adds on the reference voltage. Here we've used a reference voltage of zero, but we could have made it 2.5V by using a voltage divider. With a reference voltage of zero, which is preferable, how can we read deflections of the strain gauge bridge of both polarities? The 10K nulling trimpot allows us to set the quiescent output of the instrumentation amp to 2.5V. Alternately, you could use a rail splitter which is simply an IC that outputs the average of its two input rails, which in this case will be 0V and 5V. This method wastes far less current but cannot be trimmed to the ideal 2.5V in the case that your supply doesn't produce exactly 5V.
Often strain gauges need an amplification factor of 500 or even 1000. At these high gains, noise from nearby digital devices (such as a PIC) can cause erratic operation of the amplifier. Use supply decoupling capacitors (typically 0.1uF) near the chip, from both supply rails to Vref (ground here). If it is acceptable to low-pass the signal, use an appropriate capacitor between the inverting and non-inverting inputs of the instrumentation amp (e.g. for a 1mS low pass, C=0.1uF here, because 0.1uF * 10Kohm = 1mS). You can also use an RC low pass between the output of the instrumentation amp and the PIC input. In many cases you may need to use a standalone strain gauge amplifier board with its own power supply (see [xxx])