{{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