{"id":112,"date":"2017-10-13T01:04:53","date_gmt":"2017-10-13T01:04:53","guid":{"rendered":"http:\/\/marcjuneau.ca\/?p=112"},"modified":"2017-10-13T01:06:03","modified_gmt":"2017-10-13T01:06:03","slug":"avr-adc-avec-un-arduino-uno","status":"publish","type":"post","link":"https:\/\/marcjuneau.ca\/?p=112","title":{"rendered":"AVR ADC avec un Arduino UNO"},"content":{"rendered":"<p>Cet article explique comment utiliser le convertisseur analogique \u00e0 num\u00e9rique (ADC) pr\u00e9sent sur le Atmega328p du Arduino UNO.<\/p>\n<p>Dans cet article, nous utiliserons une boucle pour la lecture d&rsquo;un canal. Je ferai un autre article qui expliquera comment faire cette lecture en interruption, ce qui est recommand\u00e9 afin de lib\u00e9rer le programme principal.<\/p>\n<p><strong>\u00c9tape 1 : Initialisation du ADC<\/strong><\/p>\n<p>Dans l&rsquo;initialisation, nous devons configurer le registre ADCSRA.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-115\" src=\"http:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_2.jpg\" alt=\"Screenshot_2\" width=\"1311\" height=\"220\" srcset=\"https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_2.jpg 1311w, https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_2-300x50.jpg 300w, https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_2-768x129.jpg 768w, https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_2-1024x172.jpg 1024w, https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_2-1200x201.jpg 1200w\" sizes=\"auto, (max-width: 1311px) 100vw, 1311px\" \/><\/p>\n<p>Le bit ADEN active le ADC alors que les bits ADPS0-ADPS3 s\u00e9lectionnent la division de l&rsquo;horloge du syst\u00e8me qui \u00e9tablira la vitesse de l&rsquo;horloge du ADC.\u00a0Ce qui est important, c&rsquo;est que l&rsquo;horloge de l&rsquo;ADC ne d\u00e9passe pas\u00a0200KHz lorsque les 10 bits de r\u00e9solution sont n\u00e9cessaires. Puisque nous avons une horloge de 16MHz sur le Arduino UNO, nous devons diviser par 80 ou plus. Selon la table 24-5 du datasheet, nous devrons donc utiliser le facteur de division 128.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-118\" src=\"http:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_3.jpg\" alt=\"Screenshot_3\" width=\"1327\" height=\"526\" srcset=\"https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_3.jpg 1327w, https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_3-300x119.jpg 300w, https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_3-768x304.jpg 768w, https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_3-1024x406.jpg 1024w, https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_3-1200x476.jpg 1200w\" sizes=\"auto, (max-width: 1327px) 100vw, 1327px\" \/><\/p>\n<p>Nous devons \u00e9galement configurer le registre ADMUX qui s\u00e9lectionne la tension de r\u00e9f\u00e9rence utilis\u00e9e par l&rsquo;ADC.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-122\" src=\"http:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_3.png\" alt=\"Screenshot_3\" width=\"991\" height=\"149\" srcset=\"https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_3.png 991w, https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_3-300x45.png 300w, https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_3-768x115.png 768w\" sizes=\"auto, (max-width: 991px) 100vw, 991px\" \/><\/p>\n<p>Puisque la broche AREF du Arduino UNO n&rsquo;est pas reli\u00e9e, nous allons utiliser AVcc comme r\u00e9f\u00e9rence. La table 24-3 montre que le bit REFS0 doit \u00eatre activ\u00e9.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-123\" src=\"http:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_2.png\" alt=\"Screenshot_2\" width=\"1133\" height=\"277\" srcset=\"https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_2.png 1133w, https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_2-300x73.png 300w, https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_2-768x188.png 768w, https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_2-1024x250.png 1024w\" sizes=\"auto, (max-width: 1133px) 100vw, 1133px\" \/><\/p>\n<p>Voici \u00e0 quoi le code de la fonction adcInit devrait ressembler :<\/p>\n<pre>void adcInit()\r\n{\r\n ADCSRA = (1&lt;&lt;ADEN) | (1&lt;&lt;ADPS2) | (1&lt;&lt;ADPS1) |(1&lt;&lt;ADPS0) ;\r\n ADMUX =  (1&lt;&lt;REFS0);\r\n}<\/pre>\n<p><strong>\u00c9tape 2\u00a0:\u00a0S\u00e9lection du canal<\/strong><\/p>\n<p>Le Atmega328P utilis\u00e9 par le Arduino UNO poss\u00e8de 6 canaux sur son ADC. Lorsqu&rsquo;il n&rsquo;y a qu&rsquo;un canal utilis\u00e9, vous devez s\u00e9lectionner le canal une seule fois. Sinon, vous devez s\u00e9lectionner le bon canal avant chaque conversion. La s\u00e9lection du canal s&rsquo;effectue via le registre ADMUX avec les bits MUX3 \u00e0 MUX0.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-120\" src=\"http:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_4.png\" alt=\"Screenshot_4\" width=\"1131\" height=\"842\" srcset=\"https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_4.png 1131w, https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_4-300x223.png 300w, https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_4-768x572.png 768w, https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_4-1024x762.png 1024w\" sizes=\"auto, (max-width: 1131px) 100vw, 1131px\" \/><\/p>\n<p>Voici \u00e0 quoi la fonction adcSetCh devrait ressembler :<\/p>\n<pre>void adcSetCh(uint8_t ch)\r\n{\r\n ADMUX &amp;= 0xF0; \r\n ADMUX |= (ch &amp; 0x0F);\r\n}<\/pre>\n<p><strong>\u00c9tape 3\u00a0: Lecture de l&rsquo;ADC dans une boucle<\/strong><\/p>\n<p>Il faut maintenant d\u00e9marrer l&rsquo;ADC. Cette op\u00e9ration s&rsquo;effectue \u00e0 l&rsquo;aide du bit ADSC du registre ADCSRA. Lorsque ce bit est mis \u00e0 1, une conversion d\u00e9marre. Le bit retourne \u00e0 z\u00e9ro lorsque la conversion est termin\u00e9e.<\/p>\n<p>Voici \u00e0 quoi le code de la fonction adcRead devrait ressembler :<\/p>\n<pre>uint16_t adcRead(uint8_t ch)\r\n{\r\n ADCSRA |= (1&lt;&lt;ADSC);\r\n while (ADCSRA &amp; (1&lt;&lt;ADSC)); \r\n return ADCW;\r\n}<\/pre>\n<p><strong>Exemple d&rsquo;utilisation de l&rsquo;ADC<\/strong><\/p>\n<p>Dans cet exemple, un potentiom\u00e8tre est reli\u00e9 au canal 0 de l&rsquo;ADC selon l&rsquo;image suivante.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-124\" src=\"http:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/20171012_1943171-1024x768.jpg\" alt=\"20171012_194317[1]\" width=\"531\" height=\"398\" srcset=\"https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/20171012_1943171-1024x768.jpg 1024w, https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/20171012_1943171-300x225.jpg 300w, https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/20171012_1943171-768x576.jpg 768w, https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/20171012_1943171-1200x900.jpg 1200w\" sizes=\"auto, (max-width: 531px) 100vw, 531px\" \/><\/p>\n<p>Le code fait la lecture de la broche aux 100ms puis il affiche le r\u00e9sultat sur le port s\u00e9rie.<\/p>\n<pre>#define F_CPU 16000000UL\r\n#include &lt;avr\/io.h&gt;\r\n#include &lt;util\/delay.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include \"usart.h\"\r\n#include \"adc.h\"\r\n\r\nuint16_t adcVal = 0;\r\n\r\nint main(void)\r\n{\r\n  char strVal[6] = {0};\r\n  usartInit(19200);\r\n  adcInit();\r\n  while (1) \r\n  {\r\n    adcVal = adcRead(0);\r\n    itoa(adcVal,strVal,10);\r\n    usartSendStr(strVal);\r\n    usartSendStr(\"\\n\\r\");\r\n    _delay_ms(100);\r\n  }\r\n}<\/pre>\n<p>Et voici le r\u00e9sultat observ\u00e9, en variant de 0V \u00e0 5V le potentiom\u00e8tre.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-125\" src=\"http:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_5.png\" alt=\"Screenshot_5\" width=\"697\" height=\"416\" srcset=\"https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_5.png 697w, https:\/\/marcjuneau.ca\/wp-content\/uploads\/2017\/10\/Screenshot_5-300x179.png 300w\" sizes=\"auto, (max-width: 697px) 100vw, 697px\" \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Cet article explique comment utiliser le convertisseur analogique \u00e0 num\u00e9rique (ADC) pr\u00e9sent sur le Atmega328p du Arduino UNO. Dans cet article, nous utiliserons une boucle pour la lecture d&rsquo;un canal. Je ferai un autre article qui expliquera comment faire cette lecture en interruption, ce qui est recommand\u00e9 afin de lib\u00e9rer<span class=\"more-link\"><a href=\"https:\/\/marcjuneau.ca\/?p=112\">Continue Reading<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,11,2],"tags":[],"class_list":["entry","author-mjuneau","post-112","post","type-post","status-publish","format-standard","category-arduino","category-avrstudio","category-cc"],"_links":{"self":[{"href":"https:\/\/marcjuneau.ca\/index.php?rest_route=\/wp\/v2\/posts\/112","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/marcjuneau.ca\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/marcjuneau.ca\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/marcjuneau.ca\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/marcjuneau.ca\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=112"}],"version-history":[{"count":5,"href":"https:\/\/marcjuneau.ca\/index.php?rest_route=\/wp\/v2\/posts\/112\/revisions"}],"predecessor-version":[{"id":126,"href":"https:\/\/marcjuneau.ca\/index.php?rest_route=\/wp\/v2\/posts\/112\/revisions\/126"}],"wp:attachment":[{"href":"https:\/\/marcjuneau.ca\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=112"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/marcjuneau.ca\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=112"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/marcjuneau.ca\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=112"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}