Aquila Reloaded – Chapitre 6 : Capteur ambiant de basses

Bonjour à tous,

Je continue le développement de ma carte Aquila Reloaded. On va voir maintenant comment faire pour capter des basses avec le micro intégré.

AOP : Amplificateur opérationnel

Comme je l’ai dit dans le premier chapitre, l’objectif du projet est aussi de réutiliser un maximum de composants déjà présents sur le circuit original. Or, la partie « gestion microphone » du circuit électronique dispose d’un composant « LM358 ». Il s’agit d’un AOP (Amplificateur opérationnel).

Un AOP dispose de deux entrées : l’une est nommée « inverseuse » (), l’autre « non inverseuse » (+). Il dispose également de deux broches d’alimentation (VCC+ et VCC-), et d’une sortie (S). Sans rentrer dans les détails techniques, il permet d’effectuer une amplification différentielle. Il est représenté très souvent sur les schémas avec la notation américaine : un triangle à 3 broches + 2 broches facultatives pour l’alimentation. Si vous voulez plus de détails techniques, le site de sonelec-musique est parfait. La page Wikipedia recense également pas mal d’infos.

Deux applications concrètes sont possibles pour l’AOP, ce sont les cas d’usage les plus courants et ils vont nous servir pour l’Aquila.

Mode Amplificateur non-inverseur (régime linéaire)

Voici le schéma suivant :

Deux résistances R1 et R2 permettent d’ajuster le gain de l’amplificateur. La formule de calcul du gain est (R2 / R1) + 1. Simple non ?

Pour info, la résistance R2 située entre l’entrée inverseuse et la sortie est appelée « résistance de contre-réaction ».

Vous l’aurez compris, on va utiliser ce schéma pour amplifier notre microphone ! On voit ça après 😉

Mode comparateur (régime saturé)

Voici le schéma suivant :

Dans ce schéma, la résistance de contre-réaction disparait. Ce qui a pour effet de générer un gain infini (saturé). Et comme l’AOP ne délivrera jamais une tension de sortie supérieure à celle de son alimentation, on obtient un comparateur. Dans ce câblage, l’AOP va réagir comme tel :

  • Si la tension à la borne (+) du comparateur est supérieure à la tension à la borne (), alors la sortie S sera égale à VCC+ (Donc un peu moins de 5V)
  • Si la tension à la borne (+) du comparateur est inférieure à la tension à la borne (), alors la sortie S sera égale à VCC- (Donc 0V)

C’est simple ! Et cela peut être pratique avec notre Arduino, on va voir comment un peu plus tard.

Cas concret : capteur de basses

Amplification du microphone

Vous l’aurez compris, on va utiliser l’AOP à notre disposition pour amplifier notre microphone. Pour cela, nous allons appliquer le premier schéma, en captant le son de notre microphone.

Comme c’est un micro de type « Electret », il est nécessaire de l’amplifier et de filtrer la partie « continue » du signal 5V, pour ne récupérer que le son, c’est le rôle du condensateur C1 et des deux résistances R3 et R4.

Un potentiomètre R2 sera positionné en tant que résistance de contre-réaction, et permettra d’ajuster le gain de l’amplificateur. La sortie de l’AOP est connectée à une entrée analogique de l’Arduino

Isolation des basses

L’objectif du micro est de capter les basses, et de déclencher un mouvement synchronisé à la musique. Il est donc nécessaire de construire un filtre passe-bas afin d’éliminer les mediums et les aigus. Il existe deux méthodes pour construire notre passe-bas :

  • La première méthode consiste à effectuer une filtration logicielle, avec transformée de fourrier et autres calculs gourmands en CPU. J’ai testé, ca fonctionne, mais ça charge le CPU de l’Arduino et ralenti les autres fonctionnalités dont nous allons avoir besoin sur l’Aquila (moteurs PAP, DMX, …). Bref, à oublier !
  • La seconde méthode consiste à effectuer une filtration matérielle, avec une résistance et un condensateur (montage type RC). C’est la méthode que nous allons privilégier.

Ci-dessous, par rapport au schéma précédent, j’ai rajouté un filtre passe-bas matériel composé d’une résistance R5 et d’un condensateur C2. Si vous voulez plus de détails sur comment réaliser un filtre passe-bas ou passe-haut, je vous renvoie sur sonelec-musique.

Capteur de basses par impulsion

Notre LM358 est en fait un « double AOP » : deux AOP cohabitent dans le même boitier. Pour l’instant nous n’avons utilisé qu’un seul des AOP. On peut utiliser le second pour créer un comparateur audio.

Voici le schéma complété :

Les résistances R6 et R7 sont câblées en pont-diviseur de tension ; j’aurai pu les remplacer par un potentiomètre. Elles donnent une valeur de référence au comparateur. Ainsi, si le signal audio (basses uniquement) dépasse la valeur du comparateur, la sortie S est égale à 5V, donc vaut 1. Si la valeur est en dessous, la sortie S est égale à 0V, donc vaut 0.

Sur l’Arduino, j’ai choisi de câbler ce signal à une entrée de type « interrupt() ».

Partie logicielle

D’un point de vue logiciel, je ne vais pas trop rentrer dans le détail, mais je peux choisir de travailler le signal :

  • Soit en mode analogique, en comparant la valeur de A0 à une valeur de référence
  • Soit en mode numérique, en réagissant lorsque le trigger passe de 0 à 1.

Comment détecter les basses en analogique ?

C’est simple : la fonction « analogRead() » retourne une valeur entre 0 et 1023, qui correspond à la tension appliquée, entre 0 et 5V.

NB: Pour convertir cette valeur en tension : U = Aread * (5 / 1023)

Pour détecter les basses, première astuce : comme le micro est filtré par un passe-bas, la valeur en analogique sera faible et augmentera brutalement dès la réception du « coup de basse ». On va donc définir un seuil. Voici un exemple de code qui allume la diode interne.

int seuil;

void setup() {
  seuil = 700;
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  if(analogRead(0) > seuil) {
    digitalWrite(LED_BUILTIN, HIGH);
  }
  else {
    digitalWrite(LED_BUILTIN, LOW);
  }
}

C’est rudimentaire mais ca fonctionne ! Cependant, le seuil est statique, il serait mieux qu’il soit dynamique, en effectuant un échantillonnage et en mesurant l’écart entre la valeur moyenne sur les dernières secondes, et la valeur maximale. Pour l’instant je n’ai trouvé aucun code satisfaisant capable de répondre à ce besoin, et je n’ai pas eu le temps de développer mon propre code. Je ferai un EDIT sur cette page quand j’aurai développé un truc pas trop mal.

Comment détecter les basses en numérique ?

On va utiliser l’interrupt de l’Arduino afin de déclencher des événements. Pour voir comment fonctionne les interrupt(), vous pouvez consulter la fin du chapitre 4.

Pour résumer, l’interrupt s’enclenchera dès réception d’un « coup de basse », on va définir le code suivant, qui allumera brièvement la LED interne (pour l’exemple) :

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(3, INPUT);
  attachInterrupt(digitalPinToInterrupt(3), bassLed, RISING);
}

void bassLed() { 
 digitalWrite(LED_BUILTIN, HIGH);
 delay(5);
 digitalWrite(LED_BUILTIN, LOW);
}
void loop() {
 // Do what you want
}

Remarque sur les tensions analogiques de référence

Par défaut, la tension d’un Arduino est de 5V, et ce sera la valeur de référence pour toutes les broches analogiques. Toutefois, il est possible de prendre une autre tension de référence, inférieure à 5V. Dans ce cas, l’étalonnage entre 0 et 1023 sera différent (et plus précis). Pour cela, il faut appliquer la tension désirée à la broche « AREF » de l’Arduino, puis utiliser la fonction analogReference(EXTERNAL). Pour plus de détail, vous pouvez consulter cette page.

Remarque sur les micros « tout fait pour Arduino » vendus sur Internet

Pour les avoir testés, cela fonctionne mais le rendu n’est pas génial. Très souvent, les modules ne disposent pas de filtre, ce ne sont que de simples comparateurs avec seuil. Cela peut fonctionner pour certains usages (détecteur de bruit par exemple), mais pas pour un usage comme l’Aquila.

Voila, vous savez maintenant comment utiliser un microphone avec l’Arduino ! La suite au prochain épisode 😉

2 commentaires :

  1. Hello,

    Super ce projet ! tout est détaillé c’est génial ! Je travaille également sur un projet de rampe led adressables en ce moment avec détection de son, effets etc. Par contre il me semble qu’avec les microcontrôleurs atmega, on ne peut pas utiliser de delay durant les fonctions interruptions car les delay utilisent déjà les interruptions…As-tu testé ton code ? Je peux me tromper…
    En tout cas merci de partager ce projet et bonne continuation !

  2. Hello,
    Il est fortement déconseillé d’utiliser les delays à cause du DMX ou du contrôle des moteurs PAP, car la lecture et contrôle est faite à chaque tour de la fonction loop()
    J’ai une version de code fonctionnelle en « beta », qui fonctionne déjà très bien quand le scan est asservi en DMX.
    Je peux vous l’envoyer si vous voulez 🙂

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *