tutoriel – réaliser un interphone audio avec ESP32 et Arduino IDE

Traducteur

Porter la fonction audio sur les objets domestiques

J’avais consacré plusieurs articles pour expliquer   la mise en œuvre du streaming audio, avec la plateforme ESP32-Lyrat et  l’atelier logiciel ESP-ADF. Avec à la clé la restitution d’un son tout à fait correct, que la diffusion s’effectue soit en Bluetooth soit en Wifi.

Mais à partir du moment où j’ai voulu greffer des fonctions audio sur mes objets domestiques, sur base ESP8266/ESP32, je me suis rendu compte que l’atelier de développement Arduino offrait une bien meilleure souplesse que l’atelier Espressif ESP-ADF. La fonction audio s’intégre alors bien dans l’architecture choisie pour mes objets domestiques. Elle complète le pilotage avec MQTT depuis domoticz.

Chaque objet domestique pourra restituer ou capturer un flux audio via WiFi/Internet, avec mon serveur central ou d’autres objets.

Mises à jour

2020-04-01  Ajout détecteur IR ; détails sur le brochage

2020-04-12 Mise à jour et ajouts suite à intégration : échanges réseau via FTP, synchrnoisation MQTT avec le serveur Domoticz, alternative audio utilisant le DAC interne ESP32, intégration du détecteur IR en boitier étanche, LED bleue pour faciliter l’enregistrement, mise en boîtier …

2020-04-15 Description du lien WAN avec le client FTP et le lien MQTT Domoticz.

Réaliser un interphone

L’interphone est  capable de traiter les flux audio montants et descendants :

  • restituer un flux audio sur un haut-parleur
  • capturer un flux audio à partir d’un microphone.

Plutôt que de m’orienter sur une architecture VoIP full duplex et temps réel, je mise sur des échanges à l’alternat, le séquencement pouvant être réalisé sous MQTT. Ce qui amène à échanger via le réseau en mode fichier, avec un recours possible à une mémoire SDCARD attachée à l’objet.

Voici les mécanismes dont j’ai besoin pour l’interphone et qui pourront être utiles à d’autres objets domestiques :

  • restituer un flux audio (WAV ou MP3) sur un haut-parleur intégré à l’objet domestique. Le flux peut être généré depuis le réseau, en mode HTTP, ou depuis une SDCARD
  • enregistrer  un flux audio (fichier WAV) depuis un microphone intégré à l’objet domestique sur une SDCARD. Le fichier pourra être rappatrié ensuite via le réseau
  •  séquencer les fonctions audio, avec des capacités de détection et d’interaction vocale avec les visiteurs
  • échanger avec le serveur Domoticz ( centre de pilotage pour les objets domestiques philoc) par le biais de messages MQTT.

Plateforme matérielle

Concevoir des objets domestiques à bas coût, c’est une de mes priorités. C’est pourquoi  j’indique une estimation de  prix pour les composants  choisis, avec deux bornes, suivant que le délai d’approvisionnement soit court ou long.

Le coeur microcontrôleur ESP32

L’ESP32 est mieux armé que l’ESP8266 dès lors qu’il s’agit de traiter de flux audio en temps réel. Plus rapide, et doté de plus de mémoire et d’entrées-sorties, il dispose en outre d’un double coeur, très utile à gérer en parallèle les fonctions réseau et les fonctions de conversion de signaux locales.

J’utilise une carte de développement de type ESP32-DEVKITC, mais il y en a plusieurs types, suivant le vendeur et la version :

  • La version d’origine Espressif, ESP32-DEVKITC-V4 est chère et difficile à approvisionner en circuit court
  • J’opte pour une carte AzDelivery ESP32-DEVKITC-NODEMCU. Ses particularités au niveau du brochage sont expliquées dans les spécifications que j’invite à consulter : quelques broches sont réservées à la Flash, certaines  GPIO sont sans pull-up, le marquage est parfois équivoque…
  • pour ce qui concerne les schémas, je n’ai pu trouver que les schémas de l’ESP32 DEVKITC de source Espressif, il y a un risque qu’ils ne soient pas entièrement identiques aux schémas de la carte que j’utilise.

Carte de développement ESP32 DEVKITC :
Lien vers la spécification du modèle utilisé (Azdelivery)
Lien vers un document utile au brochage (pinout) des cartes
Lien vers les schémas de la carte ESP32 DEVKITC (source Espressif
Un autre lien vers des schémas ESP32S, pour évaluer les divergences
esp32 DevKitC V4 : 4€ / 9€

Le stockage de fichiers en local avec une SDCARD

J’utilise une SDCARD pilotée par l’ESP32 avec le bus SPI. Elle est enfichée dans un support de conversion au format SD. Quelques pistes utiles :

  • la taille du support SD aide à ce que  les fils du cordon de liaison soient soudés (j’ai eu des problèmes avec un shield d’extension SDCARD qui consommait terriblement)
  • une SDCARD dispose de deux modes de connexion, avec le mode SD et le mode SPI, c’est ce dernier qui m’intéresse.
  • L’alimentation 3.3V (plage 2.7V-3.6V) est prise sur les broches de l’ESP32. Le cordon de liaison ne dépasse pas 10 cm. J’évalue le courant à fournir à une valeur typique de 200 mA sous 3.3V.

Une image du brochage utilisé :

Lien vers les spécifications Kingston SDCIT-32Gos
Carte SDCARD 32 Gos : 2€ / 9€

Restitution audio

Pour la restitution audio, j’ai testé deux options :

Option 1 : amplificateur modo I2S avec  DAC intégré : MAX98357A
  • un amplificateur 3W – classe D et  raccordé à la carte ESP32 par un lien I2S. Je peux lui connecter directement un haut-parleur 2W – 8/4 Ohm.

Un circuit gère une voie (MONO), sachant qu’il est possible de dupliquer le circuit pour fonctionner en  mode STEREO. Il peut être alimenté sous 3.3V ou 5V. Quelques points à retenir

  • la consommation du circuit I = P/U = 1A typique
  • la capacité de fonctionner en MONO ou STEREO
  • le besoin de régler le gain au niveau numérique, « avant » l’I2S.
  • la gestion des hauts-parleurs par pulses haute-fréquence (PWM) qui ne permettrait pas de se coupler à un amplificateur externe.

J’obtiens une restitution sonore de qualité médiocre avec le type de haut-parleur bas coût que j’ai choisi, dès lors que je demande un niveau sonore assez élevé pour être entendu en extérieur et à travers le boîtier étanche.

Lien vers les spécifications du circuit MAX98357A
MAX98357A : 3€ / 8€
Option recommandée : récupération au rebut d'une enceinte de TV cathodique Philips 90s, disposant d'un haut-parleur de qualité
Option 2 : amplificateur stereo avec entrée analogique : PAM8403

Ce circuit, quand on l’utilise en mode stéréo, demande à être couplé aux deux sorties analogique de l’ESP32, elles-mêmes pilotées par les DAC internes de l’ESP32.

Même dans le cas d’une utilisation en mode MONO, voici deux conseils :

  •    réserver le GPIO25 pour le canal droit, et le GPIO26 pour le canal gauche.  Dans le cas de l’interphone, j’utilise uniquement la voie de droite, mais dès lors que l’option I2S-DAC interne est activée sur une voie, j’ai constaté que je ne pouvais plus libérer la sortie GPIO26 pour un autre usage, jusqu’au prochain reset hardware. Toutes les fonctions de désactivation logicielles essayées ont été inefficaces
  • dans la mesure où l’ESP  dispose de deux ports I2S (I2S_NUM_0/1), et que seul le port I2S_NUM_0 est capable de piloter les DAC internes, je recommande de piloter le microphone I2S avec le port I2S I2S_NUM_1. Les changements d’affectation  de ressources par logiciel, entre les phases d’enregistrement et de restitution sonores n’ont pas été couronnées de succès, et le recours à un cloisonnement matériel porte ses fruits.

Les points à retenir pour le domaine du matériel sont les suivants :

  • on dispose d’une molette de réglage de niveau fort utile dans le cas de l’ interphone, mais qui serait mal adaptée à un concept d’enceinte active, où seul le réglage de gain par logiciel est possible
  • le son restitué par le haut-parleur bas-coût choisi est puissant, mais avec du bruit de codage, certainement du fait du pilotage des sorties DAC de l’ESP32 en mode 8 bits
  • une broche MUTN, pilotée par une GPIO de l’ESP32, permet de couper l’ampli, et donc de s’affranchir du niveau de bruit résiduel, notamment en phase d’enregistrement
  • le circuit demande une alimentation sous 5V.
PAM8403 : 3€ / 6€
Option recommandée : HP Velleman MLS3 2W/8Ohm/diamètre 66 mm : 2€ / 9€

Enregistrement audio

J’utilise un circuit microphone INMP441. Il dispose d’une capacité ADC intégrée, avec une sortie I2S pour la connexion à la carte ESP32.

Sur le plan logiciel, deux points à noter :

  • pour fonctionner avec le port I2S_NUM_1 de l’ESP32, comme évoqué précédemment, et éviter d’interférer avec les circuits de restitution sonores, j’ai été conduit à patcher les fichiers de la librairie
  • le circuit fonctionne apparemment avec un échantillonnage imposé sous 32 bits, ce qui conduit à une configuration surprenante de la librairie logicielle, où on rappatrie pour chaque échantillon de temps 8 octets (deux voies 32 bits) pour finalement n’en stocker que 2 dans le fichier .WAV cible
  • Parmi les 8 octets remontés à chaque temps d’échantillonage, les 4 de la voie de gauche sont à 0.

Je prends en compte :

  • le besoin d’amplifier le niveau d’enregistrement  au niveau numérique, « après » l’I2S
  • la broche d’entrée L/R, pour la sélection du canal DROIT/GAUCHE, et reliée au 3.3V  (canal DROIT)
  • l’alimentation à fournir, 3.3V.
Lien vers les spécifications du circuit INMP441
INMP441 : 2€ / 8€

Détection de présence

J’ai besoin d’une détection de présence pour séquencer les opérations audio. J’utiise un circuit HC-SR501, alimenté sous 5V, disposant d’une sortie signal compatible 3.3V.

Ce circuit s’est révélé difficile à intégrer dans le boîtier étanche de l’interphone, dans la mesure où la vitre en plexiglas bloque la détection infrarouge. Voici le montage retenu en mode traversant, avec maintien et report étanche par collage externe du dôme optique :

Alimentation

Je suis face au problème suivant :

  • un besoin en puissance de l’ordre de 5W, qui excède peut-être les capacités d’alimentation par l’USB
  • des circuits audio demandant du 3.3V  ou du 5V
  • une carte SDCARD qui a besoin d’une alimentation 3.3V
  • une carte ESP32 dont je dois étudier le circuit d’alimentation.

A noter que pour que mon montage fonctionne, j’ai  dû alimenter la SDCARD depuis la sortie 3.3V de la carte ESP32. Sinon la fonction d’ initialisation renvoyait un code d’erreur.

J’invite à vous méfier de la fragilité et de l’inconstance des alimentations pour breadboards, limitées à un courant de 200 mA, et détruites au delà.

Après avoir étudié les schémas des cartes ESP32 dont je disposais, j’ai noté que le convertisseur DC/DC qui fournit le 3.3V aux circuits de la carte et aux circuits raccordés via la broche 3.3 est soit un AMS1117, soit un NCP1117. La sortance en courant n’est pas la même pour ces deux circuits, avec un typique de 1100 mA/1500 mA, qui colle à l’estimation suivante : 200 mA carte ESP32 + 200 mA SDCARD + 700 mA circuits audio.

  • J’alimente donc mes circuits externes au niveau d’un répartiteur raccordé sur la broche 3.3V de la carte ESP32
  • J’alimente la carte ESP32 par un bloc alimentation externe 7.2W / 5V raccordé à la broche 5V de la carte ESP32
  • je vérifie que mon lien USB avec l’atelier Arduino est opérationnel.

  • je peux économiser le coût de mon objet en puisant dans mon rebut le bloc d’alimentation d’un vieux téléphone ou d’une autre boîte électronique.
  • il me reste à étudier  les reports de brochage et le moyen de me passer de l’alimentation USB.
Lien vers les spécifications d'un convertisseur DC/DC AMS117
Lien vers les spécifications d'un convertisseur DC/DC NCP117
Blox alimentation externe universel DC 3.V/5V réglable : rebut / 10€

Mon alimentation DC 3.3V externe permet de fournir 500 / 800  mA, c’est au delà des capacités de l’USB seule …

esp32 DevKitC V4 : 4€ / 9€

Brochage carte ESP32 DEVKITC

  • je dois encore lever le doute sur l’utilisation de la broche GND-NC en tant que participation à l’alimentation de la SDCARD, qui dispose de deux broches SDC-GND.
  • l’option choisie est d’utiliser la sortie DAC audio de l’ESP32, et le circuit PAM8403.

Intégration dans un boîtier étanche

J’opte ici pour un cablage pin à pin par cordon femelle-femelle , qui donne une fiabilité de connexion correcte, et offre beaucoup de flexibilité lors des mises à jour.

J’ai recours à des borniers de répartition intermédiaires pour le brochage des alimentations et des masses. Au final, je choisis l’alimentation 5V via le connecteur micro usb de la carte ESP32, qui « tient » le besoin, et permet d’avoir recours à un accumulateur externe, ce qui facilite  les essais de couverture WiFi.

L’isolation des circuits avec du scotch d’électricien est efficace, la couleur rouge de ce que j’avais sous la main est juste un peu provocante.

Prototype logiciel

Librairies Arduino pour l’audio

  • ma librairie coup de coeur, c’est ESP8266Audio, pour laquelle earlephilower a effectué un travail de structuration formidable. Avec un seul bémol, le fait de ne prendre en compte que la restitution des flux audio. Sinon j’apprécie la modularité pour choisir la source (HTTP / SDCARD), le type de codage (MP3 / WAV), et le mode de restitution (DAC interne ou externe via I2S)
  • pour l’enregistrement, à partir d’un microphone I2S, j’ utilise la librairie ESP32_SoundRecorder de MhageGH. Elle  permet d’enregister en mode mono sur une durée paramétrable
  • ces deux librairies s’appuient sur le driver I2s.h disponible avec le SDK Espressif, repris et intégré au niveau de l’arborescence de l’outil Arduino dès lors que l’on configure la capacité à développer sous ESP32.
Répertoire Github pour la librairie ESP8266Audio
Répertoire Github pour la librairie ESP32SoundRecorder

Installation de la variante EPS32 sur Arduino IDE :
- Ouvrir l'atelier Arduino
- Aller dans l'onglet Fichier/Préférences
- Dans "URL de gestionnaire de cartes supplémentaires" renseigner :
https://dl.espressif.com/dl/package_esp32_index.json
- Sous la RacineArduino, apparait alors le répertoire ./packages/esp32

Accès au répertoire drivers ESP32, dont i2s.h sous la RacineArduino : ./packages/esp32/hardware/esp32/1.0.4/tools/sdk/include/driver/driver

Client FTP pour ESP32

Dans la mesure où je choisis d’effectuer les échanges de messages vocaux – qu’ils soient de type WAV (sans compression, volumineux) ou MP3 – par FTP, j’ai à choisir de monter sur l’ESP32 un client ou un serveur FTP. C »est l’application interphone qui va déclencher les échanges, que ce soit dans le sens montant ou descendant, avec le serveur. Par ailleurs je ne veux pas rendre l’interphone adressable depuis le web. Je choisis donc de mettre en oeuvre un client FTP sur l’ESP32.

C’est l’exercice que j’ai l’impression d’avoir le moins bien résolu. L’offre sur github n’est déjà pas aussi fournie que je l’espérais. Je pars d’un besoin pourtant simple :

  • ouvrir et fermer une connexion FTP avec le serveur central
  • naviguer dans les répertoires serveur, manipuler les fichiers
  • ouvrir et fermer un fichier en écriture ou en lecture
  • disposer de fonctions d’écriture et de lecture par blocs, afin d’avoir à éviter le recours à un buffer tampon énorme – de la taille du fichier – lors des échanges entre la SDCARD et le serveur.

En choisissant la librairie ESP32_FTPClient, je dispose des bons moyens pour gérer la connexion et l’accès aux fichiers, ainsi que d’une fonction d’écriture par bloc utilisable pour les uploads. Le besoin de l’application interphone par elle-même est ainsi couvert.

Mais comme j’ai besoin de charger mes messages d’invitation vocale vers la SDCARD depuis le serveur, j’ai recours à une petite application tierce « esp32downftp.ino » qui me permet d’effectuer un download de fichier vocal par ftp, depuis le serveur et vers la SDCARD. Ne trouvant pas de fonction de lecture par blocs dans la libaririe, j’ai splitté la fonction DownloadFile en deux fonctions DownPHG/DowloadFile.  Mon code est laid, mais il fonctionne.

Répertoire Github pour la librairie ESP32_FTPClient

Les membres philoc pourront trouver dans  la bibliothèque  la fonction downftp.ino et les fichiers sources de la librairie ESP32_FTPClient modifiés.

Synchronisation MQTT vers Domoticz

Dans la mesure où je remonte le message d’un visiteur vers une réserve tournante de 10 places sur mon serveur, écoutables avec tout lecteur audio, il m’est utile de disposer d’un compteur des messages reçus sur mon portail Domoticz, et de générer par Domoticz une notifcation mail qui me permet d’être prévenu d’un nouveau message, sur mon smartphone.

Voir la page philoc : MQTT et JSON : la jonction Arduino – ESP8266 – Domoticz

Codes Arduino

Les codes Arduino de mise en oeuvre seront très bientôt placés dans l’espace bibliothèque, en accès libre aux membre de www.philoc.fr.

Quelques difficultés contournées à ce jour, et aussi quelques acquis :

  • l’accès optimisé à la SDCARD, avec un ligne d’appel fort utile intégrant la pin de chip select, le recours au bus SPI, et surtout la mise en oeuvre d’une cadence d’horloge à même de supporter le temps réel
 if (!SD.begin(5, SPI, 16000000)) Serial.println("SD begin failed");
  • le mécanisme pour amplifier le signal enregistré au niveau de l’interception du flux I2S
short conv 
conv = communicationData[8 * i + 3] << 8 | communicationData[8 * i + 2];
conv = (short)(conv * 16) ;
communicationData[8 * i + 3] = (conv >> 8) & 0xFF;
communicationData[8 * i + 2] = conv & 0xFF;      
communicationData[8 * i + 3] = (conv >> 8) & 0xFF;
  • l’adaptation des paramètres DMA pour une meilleure fluidité sur le temps réel, notamment en réception
.dma_buf_count = 16,
.dma_buf_len = 60