Fads to Obsessions and Beyond...




Free domain for life, exceptional technical support, website transfer

PIC Analog Digital Conversion (ADC)

The Analog-to-Digital converter (ADC module) on a PIC16F876 is explored by converting an analog voltage from a reference source and displaying the result on a LCD. The use of ADC oversampling to increase resolution of temperature readings on a LM35 sensor is demonstrated.

There are numerous situations in which an analog quantity (voltage and or current) is required to be measured and the PIC (or other) microcontroller use the value in either a calculation, store to datafile, display on LCD etc. For example, in the fruit/vegetable dehydrator project, a LM35 temperature sensor provides a voltage output that is linearly related to temperature (10mV/oC). Analog-to-digital converter (ADC) circuitry is required to perform this function.

Many PIC (and other) microcontrollers have on-board ADC modules that conveniently enable the measurement of analog values and use of the result in the PIC controller firmware/associated circuitry. To explore the capability of the ADC module on a PIC16F876, a 2.5V reference source was established that via a voltage divider/potentiometer enabled a known voltage to be produced, which provided the test input to the PIC ADC.

The PIC16F876 datasheet steps through the process of performing ADC (setting various registers, configuring the ADC module and I/O pins, starting conversion timers, waiting for the result and reading the resultant value from the specified memory register). However, using the CSS C Compiler for PIC microcontrollers makes the use of ADC very easy. The following code snippet is all that is required to read an analog input on PIN A0 and display the result to LCD.

Code Snippet 1:


  #include "PWM_PIC16F876A.h"
  #include "lcd.c"
  
  #define LCD_ENABLE_PIN PIN_B0      
  #define LCD_RS_PIN PIN_B1          

  #device adc=10
  
  void main()
    {
       int i;
       long value, min, max;
       float vMin, vMax;
    
       lcd_init();
    
       //following sets the Vref as input to RA3 (pin 5) on the PIC
       setup_adc_ports(RA0_RA1_ANALOG_RA3_REF);
       setup_adc(ADC_CLOCK_INTERNAL);
       set_adc_channel(0); //0 = AN0 (pin2), 1=AN1 (pin3), etc
    
       lcd_putc("Sampling (volts)");
       do {
          min=0xffff;
          max=0; and 
          for(i=0; i<=10; ++i) {
             delay_ms(100);
             value = Read_ADC();
             if(valuemax) max=value;
          }
          //#device adc=10 or adc=8
          vMin=min*0.00244; // 8bit -> 2.5V/255 = 0.0098v/count       
          vMax=max*0.00244; //10bit -> 2.5V/1024 = 0.00244v/count
          printf(lcd_putc,"Min%1.2f Max%1.2f",vMin,vMax);
       } while (TRUE);
    }   
   				

Note that either 8-bit or 10-bit resolution of the ADC value can be selected, and there is also the ability to set the upper and lower Vref. Depending upon the particular PIC part, there are generally a number of ADC channels available. The positive and negative reference voltage for the ADC module can be Vdd (circuit positive voltage), Vss (circuit ground) or the input voltage at either pins RA2 or RA3 (the reference voltages need to be specified in the setup of the ADC). So this means the following:

    • If the ADC input = Vref (-) then the ADC result will be 0x00
    • If the ADC input = Vref (+) then the ADC result will be 0xFF (8-bit), 0x400 (10-bit)

Therefore, each step of the ADC module on the PIC is equal to (Vref+ minus Vref-)/(bit-mode - 1) where bit-mode is either 256 or 1024 for 8-bit and 10-bit respectively.

The ADC test circuit is the basic minimum required to enable a PIC microcontroller to operate after being programmed with a suitable .hex file. Additionally, a voltage reference (LM336) is provided as a test input to the PIC ADC, with a LCD interfaced to enable demonstration of the digital output of the analog voltage. A schematic diagram is given in the following section.

Power Supply

A typical "wall-wart" power-supply is used (a surplus laptop charger in this case) in conjunction with a voltage regulator (LM7805) to provide the regulated 5V required by the PIC microcontroller.

Circuit Operation

The PIC microcontroller starts upon power-up and runs the pre-programmed (entered via the ISCP) hex code. The hex code, produced via CSS C and is described in the previous Background Section, uses the ADC module of the PIC 16F876 to convert the analog voltage to a digital value that is then displayed on the LCD.

This circuit is simply to test the ability to read a analog voltage and use the value within PIC code. The ADC output is measured (observed) using an multimeter. No other practical use is made of the ADC output.

However, in order to test the utility of "oversampling" as a method for enhancing ADC resolution (via software rather than hardware), the PIC ADC was used to measure temperature with a LM35 temperature sensor. The use of oversampling and testing with the LM35 temperature sensor are reported in the Testing/Experimental Results Section below.

Calibration

No calibration is required. Although, a voltage of 2.5v was measured at pin 2 of the LM336 to check that the voltage reference was working correctly.

Note: Image loading can be slow depending on server load.

  • PIC ADC SchematicPIC ADC Schematic

    Silver Membership registration gives access to full resolution schematic diagrams.

    PIC ADC Schematic - basic potentiometer input

    PIC ADC Schematic - basic potentiometer input

  • PIC ADC SchematicPIC ADC Schematic

    Silver Membership registration gives access to full resolution schematic diagrams.

    PIC ADC Schematic - voltage reference input

    PIC ADC Schematic - voltage reference input

This project did not require a PCB.

The construction was done using prototyping board. See the photographs and schematic diagram sections.

Qty Schematic Part-Reference Value Notes/Datasheet
Resistors
1R110k1/4W, 10% 
1R21k1/4W, 10% 
1R35001/4W, 10% 
1R41001/4W, 10% 
1RV110kpotentiometer 
1RV2500potentiometer 
Capacitors
2C1,C222pFCeramic 
1C30.33uF 
1C40.1uF 
1C6-C101uF 
Integrated Circuits
1U1PIC16F876APIC microcontroller datasheet
1U27805Linear Voltage Regulator  datasheet
1U1MAX232ERS232 Driver/Receiver datasheet
1U2LM358NDual Op-Amp  datasheet
Diodes
1D11N-4004 
1D2LM336-2V52.5V voltage reference datasheet
Miscellaeous
1J1CONN-H55-pin connector for ICSP
1P1CONN9-pin connector for RS232
1SW1SW-SPDT 
1X110MHzCrystal Oscillator
1LCD1 LCD display (16x2 HD44780)  datasheet
Description Downloads
PIC ADC - Bill of Materials Text File Download

The Video Section shows the result of the ADC test code running on a PIC16F876A (see the "Background Section" for an explaination of the coding).

The video shows the DMM response in the foreground as the potentiometer (part of the voltage divider receiving input from the 2.5v voltage reference) is varied changing the analog voltage being input to PIN A0. The PIC ADC converts this voltage and is displayed on the LCD.

The code and circuit used to product the ADC output in the video is described within the other sections on this page.

The "Background Section" also contains an explanation of how to set the PIC parameters in order to use the on-board ADC (Using C Code).

Oversampling to increase Resolution

The AVR article "AVR121: Enhancing ADC resolution by ovesampling" gives the background details about increasing ADC resolution by oversampling, averaging and decimation, and noise reduction by averaging samples (2). The interested reader is directed to this article for the theory of operation, Nyquist theorem and required criteria for applicability, however, using the method is fairly straight-forward.

The following code snippet implements ADC oversampling using CCS C code.

Code Snippet 1: ADC oversampling


int16 overSampling_ReadADC(int8 numExtraBits) {
    int8 numSamples, divisor, i;
    int16 sumSamples = 0, ADCvalue;
    
    numSamples = 1 << (2*numExtraBits);
    divisor = 1 << numExtraBits;
    for (i=0;i> numExtraBits;
    return (sumSamples);
}            

The utility of such "software" ADC oversampling was examined by measuring the temperature of cooling hot water using a LM35 temperature sensor. The collected temperature data does indeed show that "software" ADC oversampling can improve resolution, but this does not alter the inherent accuracy (which for the LM35 is ±0.5oC).


The circuit is the basic minimum required to enable a PIC microcontroller to operate after being programmed with a suitable .hex file. So this circuit was only laid out on a breadboard.

Trouble Shooting

The "Background Section" above provides the necessary introduction to what analog to digital conversion (ADC) is and how to implement on PIC microcontrollers. This information covers the use of the various special function registers (SRF) and how the CSS C Compiler helps with coding the use of ADC on PIC microcontrollers.

ADC Measurement Voltages

The datasheet for the PIC16F876 (and other similar parts) states the following pertinent to ADC:

    • Vref+ minus Vref- , should be a minimum of 2V (with a maximum of Vdd+0.3)
    • Analog input voltage, minimum Vss-0.3V, maximum Vref+0.3V

This means if a voltage of greater than ~5.5V is required to be measured by the PIC ADC, a suitable voltage divider will be required (with recommended impedance of 2.5kohm, maximum of 10kohm - but acquisition time also increases).

A lower voltage reference (all other things being equal) results in greater "effective" resolution for the measured signal (the 8 or 10-bits of the ADC is fixed, but the "bits" are "spread" over a lower range). Therefore, the 2V minimum Vref (or difference between Vref+ and Vref-) sets this lowest "effective" resolution. However, in practice it was found using a 1.25V reference (from a TL431) appeared to work correctly. See temperature measurements made with a LM35 temperature sensor.

This is not however recommended (best to follow datasheet specifications!) and the ADC oversampling (see Testing/Experimental Results Section) technique can be used to enhance resolution instead.


Note: Image loading can be slow depending on server load.

The "Testing/Experimental Results Section" contains a video showing the ADC output from the PIC microcontroller displayed on a LCD, with a DMM also reading the analog test input voltage. The code and circuit used to product the ADC output is described within the other sections on this page.

The code and circuit used to product the ADC output is described within the other sections on this page.

Comments/Questions

No comments yet.

Add Comment/Question

Only Logged-In Members can add comments

"If we could sell our experiences for what they cost us, we'd all be millionaires".

Please donate any amount to help with hosting this web site.

If you subscribe (only $2/annum) you can view the site without advertisements and get emails abouts updates etc.

X

Sorry!

Only logged-in users with correct Membership Level can download.


Membership starts at only $2, so join now!