{{tag>riot esp esp32 can adc}} ====== Utiliser le pilote ADC de RIOt avec l'ESP32 ====== RIOT propose une abstraction simple pour utiliser les convertisseurs analogiques numériques (CAN ou ADC) intégrés dans la plupart des MCU: le pilote ADC (periph/adc). Cette interface de périphérique est construite autour du concept de lignes (ADC LINES). Pour pouvoir lire (échantillonner) une valeur, il faut au préalable initialiser **la bonne ligne ADC**, pour cela on précise le numéro de ligne que l'on souhaite utiliser: #include "periph/adc.h" //Pour l'ESP32 la GPIO33 correspond à la ligne ADC 11 #define ADC_GPIO33 ADC_LINE(11) ... if(adc_init(ADC_GPIO33) < 0 ) { printf("Echec initalisation de l'entree ADC n° %u \n\r", ADC_GPIO33); } else { printf("Ligne n° %u active\n\r", ADC_GPIO33); } Pour garantir au maximum la portabilité, il n'y a pas de relation directe entre les GPIOs et les lignes ADC, c'est la principale difficulté à l'utilisation de cette interface. Pour déterminer quel GPIO correspond à quelle ligne, il faut consulter directement le code source. Les GPIO liées aux convertisseurs analogiques numériques pour les cartes de type ESP32-DEVKIT, NodeMCU-ESP32 et leurs clones sont déclarées dans le fichier **RIOT-OS/boards/esp32-wroom-32/include/periph_conf.h** #ifndef ADC_GPIOS #define ADC_GPIOS { GPIO0 , GPIO2 , GPIO4 , GPIO12, GPIO13, GPIO14, \ GPIO15, GPIO25, GPIO26, GPIO27, GPIO32, GPIO33, \ GPIO34, GPIO35, GPIO36, GPIO39 } #endif Le fichier utilise cette déclaration pour initialiser le tableau des lignes ADC disponibles dans le fichier **RIOT-OS/boards/common/esp32/include/periph_conf_common.h**: static const gpio_t adc_channels[] = ADC_GPIOS; ... #define ADC_NUMOF ARRAY_SIZE(adc_channels) Pour initialiser la bonne ligne, il faut déterminer l'index de la GPIO utilisée par le montage dans le tableau adc_channels[] qui correspond à la constante préprocesseur **ADC_GPIOS**: Par exemple si le montage utilise la GPIO12, cette GPIO est le 4ième élément du tableau, son index est 3 ===== Exemple ===== ==== Montage ==== On branche un potentiomètre sur le GPIO33 du d'une carte de type ESP32-DEVKIT. On cherche ici à afficher régulièrement sa valeur sur le port série. Note: Note that the call to adc_init is needed for the reads to work. I remeber that the ESP8266 had a 1.0 V reference, maybe this is also the case here? ==== Code ==== Déclarer l'utilisation de la fonctionnalité periph_adc dans le Makefile # a minimal application Makefile APPLICATION = hello_adc BOARD ?= esp32-wroom-32 PORT ?= /dev/ttyUSB0 RIOTBASE ?= $(CURDIR)/../RIOT-OS FEATURES_REQUIRED += periph_timer FEATURES_REQUIRED += periph_adc # Pour une application simple n'utilisant pas les IPCs # le module core_msg peut être désactivé pour optimiser # l'occupation mémoire. # DISABLE_MODULE += core_msg USEMODULE += xtimer # Le module suivant est chargé seulement pour la cible ESP32 ifeq ($BOARD, es32-wroom-32) USEMODULE += esp_log_startup endif include $(RIOTBASE)/Makefile.include #include #include "xtimer.h" #include "periph/adc.h" #define RES ADC_RES_10BIT #define ADC_GPIO33 ADC_LINE(11) int main(void) { int sample = 0; printf("%u lignes detectees. \n\r", ADC_NUMOF); //initialisation de l'entrée ADC if(adc_init(ADC_GPIO33) < 0 ) { printf("Echec initalisation de l'entree ADC n° %u \n\r", ADC_GPIO33); } else { printf("Ligne n° %u active\n\r", ADC_GPIO33); } while(1) { //lecture du CAN sample = adc_sample(ADC_GPIO33, RES); if (sample < 0) { printf("Resolution %u invalide pour la ligne %u \n\r", RES, ADC_GPIO33); } else { printf("ADC LINE (%u): %i\n\r", ADC_GPIO33, sample); } xtimer_sleep(2); } return 0; } Une fois le code compilé et flashé, on pourra lire sur le port série via un programme comme **minicom**. ===== Références ===== * https://doc.riot-os.org/group__drivers__periph__adc.html * https://forum.riot-os.org/t/reading-adc-inputs-on-a-bluepill-board/3090 * https://forum.riot-os.org/t/adc-example-for-esp32/2713