{"id":4802,"date":"2012-05-31T23:47:51","date_gmt":"2012-06-01T03:47:51","guid":{"rendered":"http:\/\/embedded-lab.com\/blog\/?p=4802"},"modified":"2012-11-06T13:42:52","modified_gmt":"2012-11-06T18:42:52","slug":"chipkit-tutorial-3-analog-to-digital-conversion","status":"publish","type":"post","link":"https:\/\/embedded-lab.com\/blog\/chipkit-tutorial-3-analog-to-digital-conversion\/","title":{"rendered":"chipKIT Tutorial 3: Analog-to-digital conversion"},"content":{"rendered":"<p>We live in an analog world where most physical variables are analog signals. However, a microcontroller can only process data that is available in digital format. It is precisely for this reason that the analog-to-digital conversion (ADC) is so important in embedded systems that interact with an analog environment. In this tutorial, we will discuss about the ADC capabilities of chipKIT UNO32 board and illustrate how to read an analog input signal from its ADC channels.<\/p>\n<div id=\"attachment_4808\" style=\"width: 580px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/T4_Title.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-4808\" class=\"size-full wp-image-4808\" title=\"T4_Title\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/T4_Title.jpg\" alt=\"\" width=\"570\" height=\"395\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/T4_Title.jpg 570w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/T4_Title-550x381.jpg 550w\" sizes=\"auto, (max-width: 570px) 100vw, 570px\" \/><\/a><p id=\"caption-attachment-4808\" class=\"wp-caption-text\">Analog-to-digital conversion<\/p><\/div>\n<p><!--more--><\/p>\n<p><strong>Theory<\/strong><\/p>\n<p>Many embedded applications deal with physical variables such as motion, temperature, pressure, relative humidity, light intensity, and sound. A microcontroller cannot directly handle these entities because i) they are non-electrical signals, and, ii) they are analog quantities, which means they have a continuous set of values over a given range, in contrast to the discrete values of digital signals. To enable the microcontroller to process these quantities, they must be somehow represented into digital signals. The first step in this process is to convert the physical signals into electrical signals, which requires the use of a transducer.<\/p>\n<p>A\u00a0transducer is an electro-mechanical system that converts physical signals into electrical signals or vice-versa. A simplest example of a transducer is a light dependent resistor or LDR, which can be used to measure the intensity of ambient light. An LDR is a special resistor whose resistance varies with intensity of light falling on its surface. The resistance of an LDR decreases as the light intensity goes up. The pictures below show the measurements of an LDR&#8217;s resistance under two different intensities of light falling on it.<\/p>\n<div id=\"attachment_4815\" style=\"width: 580px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/LDRRES3.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-4815\" class=\"size-full wp-image-4815\" title=\"LDRRES3\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/LDRRES3.jpg\" alt=\"\" width=\"570\" height=\"415\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/LDRRES3.jpg 570w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/LDRRES3-550x400.jpg 550w\" sizes=\"auto, (max-width: 570px) 100vw, 570px\" \/><\/a><p id=\"caption-attachment-4815\" class=\"wp-caption-text\">LDR resistance is lower (1.31 K?) at higher light intensity<\/p><\/div>\n<div id=\"attachment_4805\" style=\"width: 580px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/LDRRES2.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-4805\" class=\"size-full wp-image-4805\" title=\"LDRRES2\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/LDRRES2.jpg\" alt=\"\" width=\"570\" height=\"424\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/LDRRES2.jpg 570w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/LDRRES2-550x409.jpg 550w\" sizes=\"auto, (max-width: 570px) 100vw, 570px\" \/><\/a><p id=\"caption-attachment-4805\" class=\"wp-caption-text\">LDR resistance goes up (6.30 K?) when the light falling on it is blocked<\/p><\/div>\n<p>An LDR in series with a fixed value resistor can be used to construct a mechanism for converting the light intensity into an electrical voltage. This will be discussed in more detail later. Another example of transducer is an electric motor, which converts an electrical voltage into motion.<\/p>\n<p>Now the physical signal has been converted into an electrical signal but it is not yet ready for computer processing because of its analog nature. The next step, therefore, requires an analog-to-digital conversion (ADC) system that takes a continuously varying voltage input and returns a binary digital representation suitable for use by the microcontroller.<\/p>\n<p>These days many microcontrollers are equipped with analog-to-digital conversion systems. The PIC32MX320F128H microcontoller on the chipKIT UNO32 board has got a built-in ADC with 16 ADC input channels. Out of these only 12 are\u00a0accessible on Uno32 board\u00a0through the header pins A0 through A11. The resolution of the ADC is 10-bit, which means 1024 (2<sup>10<\/sup>) discrete binary representations (0 to 1023) can be made for a given range of an analog signal. The acceptable range of ADC is set through the reference voltage (VREF). The default set reference voltage for the PIC32MX320F128H microcontoller on the chipKIT UNO32 board is its supply voltage (Vcc = 3.3 V). This is also the maximum value of the analog voltage that can be applied to any ADC channel on the chipKIT UNO32 board. Suppose, if the range of the ADC is set to 0-3.3V (VREF=3.3 V), the ADC resolution can also be expressed in terms of voltage as 3.3\/1024 ? 3.2 millivolts. This is the smallest change in the analog input voltage that is detectable by the on-chip analog-to-digital (A\/D) converter. So, anything between 0 and 3.2 mV will be represented by decimal 0, between 3.2 mV and 6.4 mV by decimal 1, between 6.4 mV and 9.6 mV by decimal 2, &#8230;, and finally, between 3.2968 V and 3.3 V by 1023. You can see that with this arrangement, the maximum error in the digital representation of an analog voltage could be 3.2 mV. This is also known as <strong>quantization error<\/strong>.<\/p>\n<p>Sometimes the range of the analog input voltage is too small compared to 3.3V and varies only a little bit. For example, the air temperature inside a room does not vary a lot. In such a case you can enhance the resolution of the A\/D converter (thus reducing the quantization error) to track the temperature more accurately. Suppose if you know the output voltage from the temperature sensing transducer cannot go beyond 1V, then setting VREF = 1V results in an improved resolution of 1\/1024 ? 1 mV. The A\/D converter is now capable of detecting much smaller changes in the input signal. An external ADC reference voltage can be supplied to the microcontroller on the chipKIT UNO32 board through its AREF pin, which is labeled as A on connector J5. The maximum voltage that can be applied to this pin is 3.3V.<\/p>\n<p><strong>Circuit setup<\/strong><\/p>\n<p>In this tutorial, a 2.2K resistor is connected in series with an LDR to construct a voltage-dividing network, as shown below. The voltage across the resistor is measured through the ADC channel A0 of the Uno32 board. When light falls on the LDR, its resistance decreases, and consequently the voltage across the 2.2K resistor goes up. If the light is blocked from falling onto the LDR, the opposite happens. Therefore, the 10-bit ADC output is proportional to the intensity of light falling on the LDR. The board is connected to the PC and the ADC output will be sent over the serial port and displayed on the <a href=\"http:\/\/embedded-lab.com\/blog\/?p=4783\">serial monitor window<\/a>.<\/p>\n<div id=\"attachment_4827\" style=\"width: 582px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/T4_Circuit.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-4827\" class=\"size-full wp-image-4827\" title=\"T4_Circuit\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/T4_Circuit.jpg\" alt=\"\" width=\"572\" height=\"510\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/T4_Circuit.jpg 572w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/T4_Circuit-550x490.jpg 550w\" sizes=\"auto, (max-width: 572px) 100vw, 572px\" \/><\/a><p id=\"caption-attachment-4827\" class=\"wp-caption-text\">Sensing the analog world<\/p><\/div>\n<div id=\"attachment_4807\" style=\"width: 580px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/T4_Setup.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-4807\" class=\"size-full wp-image-4807\" title=\"T4_Setup\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/T4_Setup.jpg\" alt=\"\" width=\"570\" height=\"413\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/T4_Setup.jpg 570w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/T4_Setup-550x398.jpg 550w\" sizes=\"auto, (max-width: 570px) 100vw, 570px\" \/><\/a><p id=\"caption-attachment-4807\" class=\"wp-caption-text\">LDR circuit setup on a breadboard<\/p><\/div>\n<p><strong>Writing sketch<\/strong><\/p>\n<p>Since the ADC outputs are sent over the serial line, the serial port and the baud rate must be initialized in the setup function. The <strong>analogRead()<\/strong> function is used to read an analog input signal from the analog pin specified inside the parenthesis.\u00a0By default, the supply voltage of 3.3V is used as the reference voltage for A\/D conversion, which means input voltages between 0 and 3.3 volts are mapped into integer values between 0 and 1023. In order to use an external reference voltage applied to the A pin, use\u00a0<strong>analogReference(External)<\/strong> function in your sketch. Here&#8217;s the complete chipKIT sketch to read the input value at A0 ADC channel and print the ADC output to the serial monitor.<\/p>\n\n<div class=\"wp_syntax\"><table><tr><td class=\"code\"><pre class=\"c\" style=\"font-family:monospace;\"><span style=\"color: #808080; font-style: italic;\">\/*\n  Tutorial 4:  Analog to digital conversion\n  Description: Reads an analog signal input to A0 pin and send the\n               10-bit ADC output to PC to display on the serial monitor.\n  Board: chipKIT UNO32\n *\/<\/span>\n&nbsp;\n<span style=\"color: #993333;\">int<\/span> ADC_OUTPUT<span style=\"color: #339933;\">;<\/span>\n<span style=\"color: #993333;\">void<\/span> setup<span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #009900;\">&#123;<\/span>\n  Serial.<span style=\"color: #202020;\">begin<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #0000dd;\">9600<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n<span style=\"color: #009900;\">&#125;<\/span>\n&nbsp;\n<span style=\"color: #993333;\">void<\/span> loop<span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #009900;\">&#123;<\/span>\n  ADC_OUTPUT <span style=\"color: #339933;\">=<\/span> analogRead<span style=\"color: #009900;\">&#40;<\/span>A0<span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n  Serial.<span style=\"color: #202020;\">print<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #ff0000;\">&quot;LDR sensor output = &quot;<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n  Serial.<span style=\"color: #202020;\">println<\/span><span style=\"color: #009900;\">&#40;<\/span>ADC_OUTPUT<span style=\"color: #339933;\">,<\/span> DEC<span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n  delay<span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #0000dd;\">1000<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n<span style=\"color: #009900;\">&#125;<\/span><\/pre><\/td><\/tr><\/table><\/div>\n\n<p><strong><a href=\"http:\/\/www.embedded-lab.com\/uploads\/chipKIT\/T4_ADC.zip\">Download the sketch file<\/a><\/strong><\/p>\n<p><strong>Output<\/strong><\/p>\n<p>Upload the above sketch into the Uno32 board and open the serial terminal window from MPIDE. The ADC samples (integer ADC outputs) are printed on the window at 1 sec interval. You can watch how these numbers change with the changing intensity of the light falling on the LDR. If you put a finger over the LDR and block the light falling on it, the ADC output will be dropped abruptly.<\/p>\n<div id=\"attachment_4806\" style=\"width: 580px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/T4_SendingData.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-4806\" class=\"size-full wp-image-4806\" title=\"T4_SendingData\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/T4_SendingData.jpg\" alt=\"\" width=\"570\" height=\"405\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/T4_SendingData.jpg 570w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/T4_SendingData-550x390.jpg 550w\" sizes=\"auto, (max-width: 570px) 100vw, 570px\" \/><\/a><p id=\"caption-attachment-4806\" class=\"wp-caption-text\">chipKIT Uno32 board sends ADC output to PC through serial interface<\/p><\/div>\n<div id=\"attachment_4803\" style=\"width: 570px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/ADC_OP.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-4803\" class=\"size-full wp-image-4803\" title=\"ADC_OP\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/ADC_OP.jpg\" alt=\"\" width=\"560\" height=\"441\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/ADC_OP.jpg 560w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/ADC_OP-550x433.jpg 550w\" sizes=\"auto, (max-width: 560px) 100vw, 560px\" \/><\/a><p id=\"caption-attachment-4803\" class=\"wp-caption-text\">ADC output displayed on serial monitor<\/p><\/div>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We live in an analog world where most physical variables are analog signals. However, a microcontroller can only process data that is available in digital format. It is precisely for this reason that the analog-to-digital conversion (ADC) is so important in embedded systems that interact with an analog environment. In this tutorial, we will discuss about the ADC capabilities of chipKIT UNO32 board and illustrate how to read an analog input signal from its ADC channels.<\/p>\n","protected":false},"author":1,"featured_media":4803,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[401],"tags":[44,402,399,428],"class_list":["post-4802","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-chipkit","tag-adc","tag-chipkit-uno32","tag-ldr","tag-photoresistor"],"_links":{"self":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/4802","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\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/comments?post=4802"}],"version-history":[{"count":23,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/4802\/revisions"}],"predecessor-version":[{"id":8019,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/4802\/revisions\/8019"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/media\/4803"}],"wp:attachment":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/media?parent=4802"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/categories?post=4802"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/tags?post=4802"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}