{"id":264,"date":"2010-11-10T11:18:40","date_gmt":"2010-11-10T16:18:40","guid":{"rendered":"http:\/\/embedded-lab.com\/blog\/?p=264"},"modified":"2012-07-30T09:29:31","modified_gmt":"2012-07-30T13:29:31","slug":"lab-5-analog-to-digital-conversion-adc","status":"publish","type":"post","link":"https:\/\/embedded-lab.com\/blog\/lab-5-analog-to-digital-conversion-adc\/","title":{"rendered":"Lab 5: Analog-to-digital conversion (ADC)"},"content":{"rendered":"<p><strong>Description<\/strong><\/p>\n<p>Analog-to-digital conversion (ADC) is necessary because, while embedded systems deal with digital values, their surroundings typically involve many analog signals such as, temperature, speed, pressure, the output of a microphone, etc. They all need to be converted into digital data before being processed by the microcontroller. Today, we will see how to read an external analog signal using a PIC16F688 microcontroller, and display the conversion output (a digital number) on a LCD. The input analog signal will be a varying voltage between 0-5V derived using a potentiometer.<\/p>\n<p><strong>Required Theory<\/strong><\/p>\n<p>The PIC16F688 microcontroller has a built-in 10-bit ADC with eight input channels. The eight channels are available at RA0, RA1, RA2, RA4, RC0, RC1, RC2, and RC3. They have alternate labels, AN0-AN7, for this function, and are multiplexed into a single Sample and Hold circuit. The\u00a0output of the Sample and Hold is\u00a0connected to the input of the A\/D converter. The 10-bit conversion result is stored\u00a0\u00a0into the ADC result registers ADRESH (A\/D Result Higher byte) and ADRESL (A\/D Result Lower byte). Each of these registers is 8-bit. The functionality of the A\/D module is controlled by three registers: ANSEL, ADCON0, and ADCON1. The details of these control registers are discussed in <a href=\"http:\/\/embedded-lab.com\/blog\/?p=379\" target=\"_blank\"><em><strong>ADC channels in PIC16F688<\/strong><\/em><\/a>.<br \/>\n<!--more--><br \/>\n<strong>Circuit Diagram<\/strong><\/p>\n<p>The test circuit to demonstrate the 10-bit A\/D conversion using PIC16F688 is shown below. The test input voltage for ADC is derived from a 5K potentiometer connected across the +5V power supply, and is connected to RA2\/AN2 pin of PIC16F688. The supply voltage (+5V) is chosen as the reference voltage for A\/D conversion. Therefore, the 10-bit ADC will convert any analog voltage between 0-5V to a digital number ranging from 0-1023. The number will be displayed on the LCD.<\/p>\n<p>This circuit diagram is not much different from the one for our previous lab (<a href=\"http:\/\/embedded-lab.com\/blog\/?p=203\" target=\"_blank\"><em><strong>Lab 4: Interfacing a character LCD<\/strong><\/em><\/a>), except it has a 5K potentiometer for generating test analog voltage for ADC operation.<\/p>\n<div id=\"attachment_891\" style=\"width: 560px\" class=\"wp-caption aligncenter\"><a rel=\"attachment wp-att-891\" href=\"http:\/\/embedded-lab.com\/blog\/?attachment_id=891\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-891\" class=\"size-medium wp-image-891 \" title=\"Ciruit_ADC_PIC16F688\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2010\/11\/Ciruit_ADC_PIC16F688-550x438.jpg\" alt=\"\" width=\"550\" height=\"438\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2010\/11\/Ciruit_ADC_PIC16F688-550x438.jpg 550w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2010\/11\/Ciruit_ADC_PIC16F688.jpg 805w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/a><p id=\"caption-attachment-891\" class=\"wp-caption-text\">Circuit diagram<\/p><\/div>\n<div id=\"attachment_268\" style=\"width: 560px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2010\/10\/SetUp2.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-268\" class=\"size-full wp-image-268 \" title=\"SetUp2\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2010\/10\/SetUp2.jpg\" alt=\"\" width=\"550\" height=\"411\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2010\/10\/SetUp2.jpg 550w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2010\/10\/SetUp2-401x300.jpg 401w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/a><p id=\"caption-attachment-268\" class=\"wp-caption-text\">Circuit setup on breadboard<\/p><\/div>\n<p style=\"text-align: center;\">\n<div id=\"attachment_872\" style=\"width: 560px\" class=\"wp-caption aligncenter\"><a rel=\"attachment wp-att-872\" href=\"http:\/\/embedded-lab.com\/blog\/?attachment_id=872\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-872\" class=\"size-medium wp-image-872 \" title=\"Img_PIC16F688_ADCTest\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2010\/11\/Img_PIC16F688_ADCTest-550x400.jpg\" alt=\"\" width=\"550\" height=\"400\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2010\/11\/Img_PIC16F688_ADCTest-550x400.jpg 550w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2010\/11\/Img_PIC16F688_ADCTest.jpg 600w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/a><p id=\"caption-attachment-872\" class=\"wp-caption-text\">Circuit setup using the PIC16F688 breadboard module<\/p><\/div>\n<p style=\"text-align: center;\">\n<p><strong>Software<\/strong><\/p>\n<p>The programming involves configuring ANSEL, ADCON0, and ADCON1 registers. Since RA2\/AN2 is used as analog input, the corresponding ANSEL bit must be set. In ADCON0 register, set CHS1 and clear CHS0 and CHS2, so that the AN2 channel will be connected to the internal Sample and Hold circuit. Clearing the VCFG bit in ADCON0 will select the supply voltage (+5V) as the reference voltage for A\/D conversion. The ADCON1 register is used to select the clock source for A\/D conversion. However, the MikroC Pro for PIC has got a built-in library function named ADC_Read() that, by default, uses the internal RC clock for ADC operation. So you don&#8217;t need to initialize the ADCON1 register. The complete program is given below.<\/p>\n<pre><span style=\"color: #003366;\">\/*<\/span><\/pre>\n<pre><span style=\"color: #003366;\"> Lab 5: Analog-to-digital converter<\/span><\/pre>\n<pre><span style=\"color: #003366;\"> Internal Oscillator @ 4MHz, MCLR Enabled, PWRT Enabled, WDT OFF<\/span><\/pre>\n<pre><span style=\"color: #003366;\"> Copyright @ Rajendra Bhatt<\/span><\/pre>\n<pre><span style=\"color: #003366;\"> October 10, 2010<\/span><\/pre>\n<pre><span style=\"color: #003366;\">*\/<\/span><\/pre>\n<pre><span style=\"color: #003366;\">\/\/ LCD module connections<\/span><\/pre>\n<pre><span style=\"color: #003366;\"> sbit LCD_RS at RC4_bit;<\/span><\/pre>\n<pre><span style=\"color: #003366;\"> sbit LCD_EN at RC5_bit;<\/span><\/pre>\n<pre><span style=\"color: #003366;\"> sbit LCD_D4 at RC0_bit;<\/span><\/pre>\n<pre><span style=\"color: #003366;\"> sbit LCD_D5 at RC1_bit;<\/span><\/pre>\n<pre><span style=\"color: #003366;\"> sbit LCD_D6 at RC2_bit;<\/span><\/pre>\n<pre><span style=\"color: #003366;\"> sbit LCD_D7 at RC3_bit;<\/span><\/pre>\n<pre><span style=\"color: #003366;\"> sbit LCD_RS_Direction at TRISC4_bit;<\/span><\/pre>\n<pre><span style=\"color: #003366;\"> sbit LCD_EN_Direction at TRISC5_bit;<\/span><\/pre>\n<pre><span style=\"color: #003366;\"> sbit LCD_D4_Direction at TRISC0_bit;<\/span><\/pre>\n<pre><span style=\"color: #003366;\"> sbit LCD_D5_Direction at TRISC1_bit;<\/span><\/pre>\n<pre><span style=\"color: #003366;\"> sbit LCD_D6_Direction at TRISC2_bit;<\/span><\/pre>\n<pre><span style=\"color: #003366;\"> sbit LCD_D7_Direction at TRISC3_bit;<\/span><\/pre>\n<pre><span style=\"color: #003366;\">\/\/ End LCD module connections<\/span><\/pre>\n<pre><span style=\"color: #003366;\">\/\/ Define Messages<\/span><\/pre>\n<pre><span style=\"color: #003366;\"> char message1[] = \"ADC Value= \";<\/span><\/pre>\n<pre><span style=\"color: #003366;\"> char *temp = \"0000\";<\/span><\/pre>\n<pre><span style=\"color: #003366;\"> unsigned int ADC_Value;<\/span><\/pre>\n<pre><span style=\"color: #003366;\"> void main() {<\/span><\/pre>\n<pre><span style=\"color: #003366;\">  ANSEL = 0b00000100; \/\/ RA2\/AN2 is analog input<\/span><\/pre>\n<pre><span style=\"color: #003366;\">  ADCON0 = 0b00001000; \/\/ Analog channel select @ AN2<\/span><\/pre>\n<pre><span style=\"color: #003366;\">  CMCON0 = 0x07 ; \/\/ Disbale comparators<\/span><\/pre>\n<pre><span style=\"color: #003366;\">  TRISC = 0b00000000; \/\/ PORTC All Outputs<\/span><\/pre>\n<pre><span style=\"color: #003366;\">  TRISA = 0b00001100; \/\/ PORTA All Outputs, Except RA3 and RA2<\/span><\/pre>\n<pre><span style=\"color: #003366;\">  Lcd_Init(); \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\/\/ Initialize LCD<\/span><\/pre>\n<div>\n<p><span style=\"color: #003366;\"><span style=\"color: #003366;\"> <\/span><\/span><\/p>\n<pre><span style=\"color: #003366;\">  Lcd_Cmd(_LCD_CLEAR); \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \/\/ CLEAR display<\/span><\/pre>\n<pre><span style=\"color: #003366;\">  Lcd_Cmd(_LCD_CURSOR_OFF); \u00a0 \u00a0 \u00a0 \u00a0\/\/ Cursor off<\/span><\/pre>\n<pre><span style=\"color: #003366;\">  Lcd_Out(1,1,message1); \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \/\/ Write message1 in 1st row<\/span><\/pre>\n<\/div>\n<pre><span style=\"color: #003366;\">  do {<\/span><\/pre>\n<pre><span style=\"color: #003366;\">   adc_value = ADC_Read(2);<\/span><\/pre>\n<pre><span style=\"color: #003366;\">   temp[0] = adc_value\/1000 + 48; \/\/ Add 48 to get the ASCII character value<\/span><\/pre>\n<pre><span style=\"color: #003366;\">   temp[1] = (adc_value\/100)%10 + 48;<\/span><\/pre>\n<pre><span style=\"color: #003366;\">   temp[2] = (adc_value\/10)%10 + 48;<\/span><\/pre>\n<pre><span style=\"color: #003366;\">   temp[3] = adc_value%10 + 48;<\/span><\/pre>\n<pre><span style=\"color: #003366;\">   Lcd_Out(1,11,temp);<\/span><\/pre>\n<pre><span style=\"color: #003366;\">   Delay_ms(2000);<\/span><\/pre>\n<pre><span style=\"color: #003366;\">  } while(1);<\/span><\/pre>\n<pre><span style=\"color: #003366;\"> }<\/span><\/pre>\n<div style=\"text-align: right;\"><span style=\"color: #003366;\"><a href=\"http:\/\/embedded-lab.com\/uploads\/HexFiles\/PIC16F688\/Lab5_ADC.zip\" target=\"_blank\">Download HEX file<\/a><\/span><\/div>\n<div style=\"text-align: right;\"><span style=\"color: #003366;\"><br \/>\n<\/span><\/div>\n<div id=\"attachment_873\" style=\"width: 560px\" class=\"wp-caption aligncenter\"><a rel=\"attachment wp-att-873\" href=\"http:\/\/embedded-lab.com\/blog\/?attachment_id=873\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-873\" class=\"size-medium wp-image-873 \" title=\"Img_PIC16F688_ADCTest_PGM\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2010\/11\/Img_PIC16F688_ADCTest_PGM-550x399.jpg\" alt=\"\" width=\"550\" height=\"399\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2010\/11\/Img_PIC16F688_ADCTest_PGM-550x399.jpg 550w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2010\/11\/Img_PIC16F688_ADCTest_PGM.jpg 600w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/a><p id=\"caption-attachment-873\" class=\"wp-caption-text\">Loading the HEX file with my handy iCP01 PIC programmer.<\/p><\/div>\n<p style=\"text-align: left;\"><strong>Output<\/strong><\/p>\n<div>Vary the potentiometer and you will see the 10-bit conversion result also vary proportionally from 0- 1023.<\/div>\n<div><a rel=\"attachment wp-att-265\" href=\"http:\/\/embedded-lab.com\/blog\/?attachment_id=265\"><\/a><\/div>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-265 aligncenter\" title=\"Output1\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2010\/10\/Output11.jpg\" alt=\"\" width=\"550\" height=\"379\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2010\/10\/Output11.jpg 550w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2010\/10\/Output11-435x300.jpg 435w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-874 aligncenter\" title=\"Img_PIC16F688_ADCTest_OP1\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2010\/11\/Img_PIC16F688_ADCTest_OP1-550x407.jpg\" alt=\"\" width=\"550\" height=\"407\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2010\/11\/Img_PIC16F688_ADCTest_OP1-550x407.jpg 550w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2010\/11\/Img_PIC16F688_ADCTest_OP1.jpg 600w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-879 aligncenter\" title=\"Img_PIC16F688_ADCTest_OP2\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2010\/11\/Img_PIC16F688_ADCTest_OP2-550x416.jpg\" alt=\"\" width=\"550\" height=\"416\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2010\/11\/Img_PIC16F688_ADCTest_OP2-550x416.jpg 550w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2010\/11\/Img_PIC16F688_ADCTest_OP2.jpg 600w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Description Analog-to-digital conversion (ADC) is necessary because, while embedded systems deal with digital values, their surroundings typically involve many analog signals such as, temperature, speed, pressure, the output of a microphone, etc. They all need to be converted into digital data before being processed by the microcontroller. Today, we will see how to read an external analog signal using a PIC16F688 microcontroller, and display the conversion output (a digital number) on a LCD. The input analog signal will be a varying voltage between 0-5V derived using a potentiometer. Required Theory The PIC16F688 microcontroller has a built-in 10-bit ADC with eight<\/p>\n","protected":false},"author":2,"featured_media":265,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[32,29,38],"tags":[44,45,20],"class_list":["post-264","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-embedded-labs","category-embedded-lessons","category-pic-tutorials","tag-adc","tag-lcd","tag-pic16f688"],"_links":{"self":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/264","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/comments?post=264"}],"version-history":[{"count":34,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/264\/revisions"}],"predecessor-version":[{"id":5834,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/264\/revisions\/5834"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/media\/265"}],"wp:attachment":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/media?parent=264"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/categories?post=264"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/tags?post=264"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}