{"id":1829,"date":"2024-06-28T05:52:47","date_gmt":"2024-06-28T05:52:47","guid":{"rendered":"https:\/\/iotthinghub.com\/?p=1829"},"modified":"2024-08-11T17:11:45","modified_gmt":"2024-08-11T17:11:45","slug":"adc-analog-to-digital-converter","status":"publish","type":"post","link":"https:\/\/iotthinghub.com\/?p=1829","title":{"rendered":"ADC (Analog to Digital Converter)"},"content":{"rendered":"\n<p class=\"has-text-color has-link-color wp-elements-1 wp-block-paragraph\" style=\"color:#5c5c5c\">Most of the real world sensor output is analog type. We can read the analog output with the ADC pin provided in Atmel family. In ATnega32 there are 8 ADC channel with 10bit resolution. That means each of the ADC channel can divide 0-5V to 0-1023 counting value that can be easily read by the ALU unit. So the resolution in terms of voltage is-<\/p>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-2 wp-block-paragraph\" style=\"color:#252525\">                      <strong>resulation=(5\/1024)\u22485mV&nbsp;<\/strong><\/p>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-3 wp-block-paragraph\" style=\"color:#5c5c5c\">Now what is the adc value of 2.5V? For single ended conversion, the ADC result is<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img decoding=\"async\" width=\"438\" height=\"104\" src=\"https:\/\/iotthinghub.com\/wp-content\/uploads\/2024\/06\/ADC-reference.jpg\" alt=\"\" class=\"wp-image-1832\" style=\"width:215px;height:auto\" srcset=\"https:\/\/iotthinghub.com\/wp-content\/uploads\/2024\/06\/ADC-reference.jpg 438w, https:\/\/iotthinghub.com\/wp-content\/uploads\/2024\/06\/ADC-reference-300x71.jpg 300w\" sizes=\"(max-width: 438px) 100vw, 438px\" \/><\/figure>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-4 wp-block-paragraph\" style=\"color:#5c5c5c\">Where V<sub>in<\/sub>= analog voltage input &amp; V<sub>ref<\/sub>= Voltage reference<\/p>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-5 wp-block-paragraph\" style=\"color:#252525\">So if the sensor value V<sub>in<\/sub>=2.5 and V<sub>ref<\/sub>=5V, than <img decoding=\"async\" width=\"200\" height=\"35\" class=\"wp-image-1833\" style=\"width: 200px;\" src=\"https:\/\/iotthinghub.com\/wp-content\/uploads\/2024\/06\/function-1-3.jpg\" alt=\"\" srcset=\"https:\/\/iotthinghub.com\/wp-content\/uploads\/2024\/06\/function-1-3.jpg 426w, https:\/\/iotthinghub.com\/wp-content\/uploads\/2024\/06\/function-1-3-300x52.jpg 300w\" sizes=\"(max-width: 200px) 100vw, 200px\" \/><\/p>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-6 wp-block-paragraph\" style=\"color:#5c5c5c\">Since in C the counting begin from 0, the value should be ADC value=511. Let\u2019s look at the register available for ADC in ATnega32 and there uses-<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img fetchpriority=\"high\" decoding=\"async\" width=\"590\" height=\"763\" src=\"https:\/\/iotthinghub.com\/wp-content\/uploads\/2024\/06\/ADC.png\" alt=\"\" class=\"wp-image-1838\" style=\"width:824px;height:auto\" srcset=\"https:\/\/iotthinghub.com\/wp-content\/uploads\/2024\/06\/ADC.png 590w, https:\/\/iotthinghub.com\/wp-content\/uploads\/2024\/06\/ADC-232x300.png 232w\" sizes=\"(max-width: 590px) 100vw, 590px\" \/><\/figure>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-7 wp-block-paragraph\" style=\"color:#252525\">To work with ADC we have to do two things<\/p>\n\n\n\n<ol style=\"color:#252525;list-style-type:lower-roman\" class=\"wp-block-list has-text-color has-link-color wp-elements-8\">\n<li>ADC Initialization<\/li>\n\n\n\n<li>ADC result.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"590\" height=\"110\" src=\"https:\/\/iotthinghub.com\/wp-content\/uploads\/2024\/06\/adcc.png\" alt=\"\" class=\"wp-image-1842\" style=\"width:343px;height:auto\" srcset=\"https:\/\/iotthinghub.com\/wp-content\/uploads\/2024\/06\/adcc.png 590w, https:\/\/iotthinghub.com\/wp-content\/uploads\/2024\/06\/adcc-300x56.png 300w\" sizes=\"(max-width: 590px) 100vw, 590px\" \/><\/figure>\n\n\n\n<ol style=\"color:#252525;list-style-type:lower-roman\" class=\"wp-block-list has-text-color has-link-color wp-elements-9\">\n<li>ADC reference selection<\/li>\n\n\n\n<li>ADC clock selection to make the F_ADC=50kHz-200kHz<\/li>\n\n\n\n<li>ADC Enable<\/li>\n<\/ol>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-10 wp-block-paragraph\" style=\"color:#5c5c5c\">Suppose we want to initialize Vref=AVCC(5V) and use a crystal of 16MHz. Now to enable AVCC with external capacitor (100nf) at AREF pin<\/p>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-11 wp-block-paragraph\" style=\"color:#252525\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ADMUX|=(1&lt;&lt;REFS0);<\/p>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-12 wp-block-paragraph\" style=\"color:#5c5c5c\">For F_ADC=(F_CPU\/Prescaler), here we want F_ADC=125kHz, than &gt; Prescaler=(16MHz\/125kHz)=128<\/p>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-13 wp-block-paragraph\" style=\"color:#252525\">ADCSRA|=(1&lt;&lt;ADPS2)|(1&lt;&lt;ADPS1)|(1&lt;&lt;ADPS0);<\/p>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-14 wp-block-paragraph\" style=\"color:#252525\">For ADC Enable&nbsp; :&nbsp;&nbsp; ADCSRA|=(1&lt;&lt;ADEN);<\/p>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-15 wp-block-paragraph\" style=\"color:#5c5c5c\">Let\u2019s use a user-defined function that has no argument and no return function i.e. void adc_init (void). So our C code for ADC initializing is-<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\n  ADMUX|=(1&lt;&lt;REFS0);\/\/AVCC with external capacitor at AREF pin\n  ADCSRA|=(1&lt;&lt;ADPS2)|(1&lt;&lt;ADPS1)|(1&lt;&lt;ADPS0);\n  ADCSRA|=(1&lt;&lt;ADEN);\n<\/pre><\/div>\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"590\" height=\"110\" src=\"https:\/\/iotthinghub.com\/wp-content\/uploads\/2024\/06\/adce.png\" alt=\"\" class=\"wp-image-1850\" style=\"width:327px;height:auto\" srcset=\"https:\/\/iotthinghub.com\/wp-content\/uploads\/2024\/06\/adce.png 590w, https:\/\/iotthinghub.com\/wp-content\/uploads\/2024\/06\/adce-300x56.png 300w\" sizes=\"(max-width: 590px) 100vw, 590px\" \/><\/figure>\n\n\n\n<ol style=\"color:#252525;list-style-type:lower-roman\" class=\"wp-block-list has-text-color has-link-color wp-elements-16\">\n<li>ADC Channel selection<\/li>\n\n\n\n<li>ADC start conversion<\/li>\n\n\n\n<li>wait until conversion finished<\/li>\n\n\n\n<li>Read the ADC value<\/li>\n<\/ol>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-17 wp-block-paragraph\" style=\"color:#5c5c5c\">Let use a user defined function that use an 8 bit argument value (for channel) and 16bit return value (since ADC is 10bit).<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\n uint16_t read_adc(uint8_t ch)\n{\n uint8_t channel;\n channel=0xff&amp;ch;  \/\/ Filter channel\n ADMUX=(ADMUX &amp; 0xc0); \/\/Clear all channel\n ADMUX|=channel;\/\/Analog Channel Selection\n ADCSRA|=(1&lt;&lt;ADSC);\/\/ADC Start Conversion\nwhile(ADCSRA &amp;(1&lt;&lt;ADSC))\n {\n   ;\/\/do nothing until conversion finished\n }\n return (ADCW);\n}\n<\/pre><\/div>\n\n\n<p class=\"has-text-color has-link-color wp-elements-18 wp-block-paragraph\" style=\"color:#5c5c5c\">Note that as soon as we enable the ADSC bit of ADCSRA register, ADC conversion start. This bit is clear when the conversion over. So in the while loop we check the condition of bit set. If it is clear than return it in unsigned 16bit integer.<\/p>\n\n\n\n<p class=\"has-text-color has-link-color has-upper-heading-font-size wp-elements-19 wp-block-paragraph\" style=\"color:#252525\"><strong>ADC with Interrupt<\/strong> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-20 wp-block-paragraph\" style=\"color:#5c5c5c\">ADC can also be read using ADC interrupt. In that case the interrupt trigger as soon as the conversion compete. Let\u2019s display ADC 8bit value in I\/O port of AVR. In that case we use interrupt driven ADC. In that case we make some changes in both ADC initialization and ADC read condition<\/p>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-21 wp-block-paragraph\" style=\"color:#252525\">ADC Initialization<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\n void adc_init(void)\n{\nADMUX |=(1&lt;&lt;REFS0);\t\t\t\t\t\t\t\t\/\/AVCC with external capacitor at AREF pin\nADCSRA |=(1&lt;&lt;ADPS2)|(1&lt;&lt;ADPS1);\t\t\t\t\t\/\/F_ADC=F_CPU\/64\nADCSRA |=(1&lt;&lt;ADEN);\t\t\t\t\t\t\t\t\/\/ADC Enable\nADCSRA |=(1&lt;&lt;ADIE);\t\t\t\t\t\t\t\t\/\/ADC Interrupt Enable\nsei();\t\t\t\t\t\t\t\t\t\t\t\t\/\/Global Interrupt Enable\n}\n<\/pre><\/div>\n\n\n<p class=\"has-text-color has-link-color wp-elements-22 wp-block-paragraph\" style=\"color:#5c5c5c\">Here F_CPU= internal 8MHz. ADC read function using interrupt<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\n void adc_value(uint8_t Ch)\n{\nuint8_t channel;\nchannel=0xff&amp;Ch;\t\t\t\t\t\t\t\t\t\/\/Filter Channel\nADMUX=(ADMUX &amp; 0XC0);\t\t\t\t\t\t\t\t\/\/Clear all channel\t\t\t\t\t\t\nADMUX |=channel;\t\t\t\t\t\t\t\t\t\/\/Analog Channel Selection\nADCSRA |= (1&lt;&lt;ADSC);\t\t\t\t\t\t\t\t\/\/ADC Start Conversion\n}\n<\/pre><\/div>\n\n\n<p class=\"has-text-color has-link-color wp-elements-23 wp-block-paragraph\" style=\"color:#5c5c5c\">The main program as follow-<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\n #include&lt;avr\/io.h&gt;\n #include&lt;util\/delay.h&gt;\n #include&lt;avr\/interrupt.h&gt;\n #include&quot;adc.h&quot;\n uint16_t value;\nint main(void)\n{\n  DDRD=0xFF; \t\t\t\t\t\t\/\/PORTD for output\n  adc_init();\t\t\t\t\t\t\/\/ADC Initilization\n  while(1)\n\t{\n\t  adc_value(0);\t\t\t\t\/\/Read ADC Channel 0\n\t  PORTD=(uint8_t)value;\t\t\/\/PORTD=ADCL\n\t}\n return 0;\n}\nISR(ADC_vect)\n{\n  value=ADCW;\n}\n<\/pre><\/div>\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-7387b849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<div class=\"wp-block-buttons is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-3e41869c wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/iotthinghub.com\/wp-content\/uploads\/2024\/08\/ADC.rar\" style=\"padding-top:var(--wp--preset--spacing--30);padding-right:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--30);padding-left:var(--wp--preset--spacing--40)\">download<\/a><\/div>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"has-text-color has-link-color has-upper-heading-font-size wp-elements-24 wp-block-paragraph\" style=\"color:#252525\"><a href=\"https:\/\/iotthinghub.com\/wp-content\/uploads\/2024\/08\/ADC.rar\">Interrupt Driven.rar<\/a><\/p>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Most of the real world sensor output is analog type. We can read the analog output with the ADC pin provided in Atmel family. In ATnega32 there are 8 ADC channel with 10bit resolution. That means each of the ADC channel can divide 0-5V to 0-1023 counting value that can be easily read by the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17],"tags":[],"class_list":["post-1829","post","type-post","status-publish","format-standard","hentry","category-adc"],"_links":{"self":[{"href":"https:\/\/iotthinghub.com\/index.php?rest_route=\/wp\/v2\/posts\/1829","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/iotthinghub.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/iotthinghub.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/iotthinghub.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/iotthinghub.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1829"}],"version-history":[{"count":17,"href":"https:\/\/iotthinghub.com\/index.php?rest_route=\/wp\/v2\/posts\/1829\/revisions"}],"predecessor-version":[{"id":2621,"href":"https:\/\/iotthinghub.com\/index.php?rest_route=\/wp\/v2\/posts\/1829\/revisions\/2621"}],"wp:attachment":[{"href":"https:\/\/iotthinghub.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1829"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/iotthinghub.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1829"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/iotthinghub.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1829"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}