Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Reconnaissance et synthèse vocales avec Arduino

Composants et fournitures

Arduino Due
× 1
Déploiement du microphone à électret SparkFun
× 1
SparkFun Mono Audio Amp Breakout
× 1
Haut-parleur :0,25 W, 8 ohms
× 1
Planche à pain (générique)
× 1
LED 5 mm :Rouge
× 3
Résistance 330 ohm
× 3
Câbles de raccordement (générique)
× 1

Outils et machines nécessaires

Fer à souder (générique)

Applications et services en ligne

BitVoicer Server 1.0

À propos de ce projet

Dans mon projet précédent, j'ai montré comment contrôler quelques LED à l'aide d'une carte Arduino et d'un serveur BitVoicer. Dans ce projet, je vais rendre les choses un peu plus compliquées. Je vais également synthétiser la parole à l'aide du convertisseur numérique-analogique (DAC) Arduino DUE. Si vous n'avez pas d'Arduino DUE, vous pouvez utiliser d'autres cartes Arduino, mais vous aurez besoin d'un DAC externe et d'un code supplémentaire pour faire fonctionner le DAC (la bibliothèque BVSSpeaker ne vous aidera pas).

Dans la vidéo ci-dessous, vous pouvez voir que je fais également jouer une petite chanson à l'Arduino et faire clignoter les LED comme s'il s'agissait de touches de piano. Désolé pour mes compétences en piano, mais c'est le mieux que je puisse faire :) . Les LED clignotent en fait dans la même séquence et dans la même synchronisation que les vraies touches C, D et E, donc si vous avez un piano autour, vous pouvez suivre les LED et jouer la même chanson. C'est un jingle d'un ancien détaillant (Mappin) qui n'existe même plus.

Les procédures suivantes seront exécutées pour transformer les commandes vocales en activité LED et en parole synthétisée :

  • 1. Les ondes audio seront capturées et amplifiées par la carte Sparkfun Electret Breakout ;
  • 2. Le signal amplifié sera numérisé et mis en mémoire tampon dans l'Arduino à l'aide de son convertisseur analogique-numérique (ADC) ;
  • 3. Les échantillons audio seront diffusés sur BitVoicer Server à l'aide du port série Arduino ;
  • 4. BitVoicer Server traitera le flux audio et reconnaîtra la parole qu'il contient ;
  • 5. La parole reconnue sera mappée sur des commandes prédéfinies qui seront renvoyées à l'Arduino. Si l'une des commandes consiste à synthétiser la parole, BitVoicer Server préparera le flux audio et l'enverra à l'Arduino ;
  • 6. L'Arduino identifiera les commandes et effectuera l'action appropriée. Si un flux audio est reçu, il sera mis en file d'attente dans la classe BVSSpeaker et lu à l'aide du DUE DAC et DMA.
  • 7. L'ampli audio mono SparkFun amplifiera le signal DAC afin qu'il puisse piloter un haut-parleur de 8 ohms.

Liste des matériaux :

  • Arduino DUE :~ 50,00 $
  • Répartition du microphone à électret Sparkfun :7,95 USD
  • Répartition de l'ampli audio mono SparkFun :7,95 USD
  • BitVoicer Server 1.0 :9,90 USD
  • Enceinte 8 Ohm :~ 2,00 $
  • Planche à pain :~10,00 $
  • 3 x LED :~1,00 $
  • 3 résistances de 330 ohms :~ 0,75 USD
  • Câbles de connexion :~0,50 USD

ÉTAPE 1 :Câblage

La première étape consiste à câbler l'Arduino et la maquette avec les composants comme indiqué dans les images ci-dessous. J'ai dû placer un petit caoutchouc sous le haut-parleur car il vibre beaucoup et sans le caoutchouc la qualité de l'audio est considérablement affectée.

Ici, nous avons une petite mais importante différence par rapport à mon projet précédent. La plupart des cartes Arduino fonctionnent à 5V, mais le DUE fonctionne à 3,3V. Parce que j'ai obtenu de meilleurs résultats en exécutant le Sparkfun Electret Breakout à 3,3 V, je vous recommande d'ajouter un cavalier entre la broche 3,3 V et la broche AREF SI vous utilisez des cartes Arduino 5 V. Le DUE utilise déjà une référence analogique de 3,3 V, vous n'avez donc pas besoin de cavalier vers la broche AREF. En fait, la broche AREF du DUE est connectée au microcontrôleur via un pont de résistance. Pour utiliser la broche AREF, la résistance BR1 doit être dessoudée du PCB.

ÉTAPE 2 : Téléchargement du code sur l'Arduino

Vous devez maintenant télécharger le code ci-dessous sur votre Arduino. Pour plus de commodité, le croquis Arduino est également disponible dans la section Pièces jointes au bas de cet article. Avant de télécharger le code, vous devez installer correctement les bibliothèques BitVoicer Server dans l'IDE Arduino (Importation d'une bibliothèque .zip).

Arduino Sketch :BVS_Demo2.ino

Ce croquis comporte sept parties principales :

  • Références de bibliothèque et déclaration de variable :Les quatre premières lignes contiennent des références aux bibliothèques BVSP, BVSMic, BVSSpeaker et DAC. Ces bibliothèques sont fournies par BitSophia et se trouvent dans le dossier d'installation de BitVoicer Server. La bibliothèque DAC est incluse automatiquement lorsque vous ajoutez une référence à la bibliothèque BVSSpeaker. Les autres lignes déclarent les constantes et les variables utilisées tout au long de l'esquisse. La classe BVSP est utilisée pour communiquer avec BitVoicer Server, la classe BVSMic est utilisée pour capturer et stocker des échantillons audio et la classe BVSSpeaker est utilisée pour reproduire l'audio à l'aide du DUE DAC.
  • Fonction de configuration :Cette fonction effectue les actions suivantes :paramétrer les modes des broches et leur état initial; initialise la communication série; et initialise les classes BVSP, BVSMic et BVSSpeaker. Il définit également des « gestionnaires d'événements » (ce sont en fait des pointeurs de fonction) pour les événements frameReceived, modeChanged et streamReceived de la classe BVSP.
  • Fonction de boucle :cette fonction effectue cinq actions importantes :demande des informations sur l'état au serveur (fonction keepAlive()); vérifie si le serveur a envoyé des données et traite les données reçues (fonction receive()); contrôle l'enregistrement et l'envoi de flux audio (fonctions isSREAvailable(), startRecording(), stopRecording() et sendStream()) ; joue les échantillons audio mis en file d'attente dans la classe BVSSpeaker (fonction play()); et appelle la fonction playNextLEDNote() qui contrôle la façon dont les voyants doivent clignoter après la réception de la commande playLEDNotes.
  • Fonction BVSP_frameReceived :Cette fonction est appelée chaque fois que la fonction receive() identifie qu'une trame complète a été reçue. Ici, j'exécute les commandes envoyées depuis BitVoicer Server. Les commandes qui contrôlent les LED contiennent 2 octets. Le premier octet indique la broche et le deuxième octet indique la valeur de la broche. J'utilise la fonction analogWrite() pour définir la valeur appropriée sur la broche. Je vérifie également si la commande playLEDNotes, qui est de type Byte, a bien été reçue. S'il a été reçu, je met playLEDNotes sur true et marquer l'heure actuelle. Ce temps sera utilisé par la fonction playNextLEDNote pour synchroniser les LED avec la chanson.
  • BVSP_modeFonction modifiée :Cette fonction est appelée à chaque fois que la fonction receive() identifie un changement de mode dans le sens sortant (Serveur --> Arduino). WOW!!! Qu'est-ce que c'est?! BitVoicer Server peut envoyer des données encadrées ou des flux audio à l'Arduino. Avant que la communication ne passe d'un mode à un autre, BitVoicer Server envoie un signal. La classe BVSP identifie ce signal et déclenche l'événement modeChanged. Dans la fonction BVSP_modeChanged, si je détecte que la communication passe du mode flux au mode encadré, je sais que l'audio est terminé et je peux donc dire à la classe BVSSpeaker d'arrêter la lecture des échantillons audio.
  • BVSP_streamFonction reçue :Cette fonction est appelée à chaque fois que la fonction receive() identifie que des échantillons audio ont été reçus. Je récupère simplement les échantillons et les mets en file d'attente dans la classe BVSSpeaker afin que la fonction play() puisse les reproduire.
  • fonction playNextLEDNote :Cette fonction ne s'exécute que si la fonction BVSP_frameReceived identifie la commande playLEDNotes. Il contrôle et synchronise les LED avec l'audio envoyé depuis BitVoicer Server. Pour synchroniser les LED avec l'audio et connaître le timing correct, j'ai utilisé Sonic Visualizer. Ce logiciel gratuit m'a permis de voir les ondes audio afin que je puisse facilement dire quand une touche de piano a été enfoncée. Il montre également une ligne de temps et c'est ainsi que j'ai obtenu les millisecondes utilisées dans cette fonction. Cela ressemble à un tour idiot et c'est le cas. Je pense qu'il serait possible d'analyser le flux audio et d'allumer la LED correspondante, mais c'est hors de ma portée.

ÉTAPE 3 : Importation d'objets de solution BitVoicer Server

Vous devez maintenant configurer BitVoicer Server pour qu'il fonctionne avec l'Arduino. BitVoicer Server a quatre objets de solution principaux :emplacements, appareils, données binaires et schémas vocaux.

Les emplacements représentent l'emplacement physique où un périphérique est installé. Dans mon cas, j'ai créé un emplacement appelé Accueil.

Les appareils sont les clients BitVoicer Server. J'ai créé un appareil mixte, je l'ai nommé ArduinoDUE et j'ai entré les paramètres de communication. IMPORTANT :même l'Arduino DUE a une petite quantité de mémoire pour stocker tous les échantillons audio que BitVoicer Server diffusera. Si vous ne limitez pas la bande passante, vous auriez besoin d'une mémoire tampon beaucoup plus grande pour stocker l'audio. J'ai eu des débordements de tampon pour cette raison, j'ai donc dû limiter le débit de données dans les paramètres de communication à 8000 échantillons par seconde.

BinaryData est un type de commande que BitVoicer Server peut envoyer aux appareils clients. Ce sont en fait des tableaux d'octets que vous pouvez lier à des commandes. Lorsque BitVoicer Server reconnaît la parole liée à cette commande, il envoie le tableau d'octets à l'appareil cible. J'ai créé un objet BinaryData pour chaque valeur de broche et les ai nommés ArduinoDUEGreenLedOn, ArduinoDUEGreenLedOff et ainsi de suite. Je me suis retrouvé avec 18 objets BinaryData dans ma solution, je vous suggère donc de télécharger et d'importer les objets depuis le VoiceSchema.sof fichier ci-dessous.

Les schémas vocaux sont l'endroit où tout se réunit. Ils définissent quelles phrases doivent être reconnues et quelles commandes exécuter. Pour chaque phrase, vous pouvez définir autant de commandes que vous le souhaitez et l'ordre dans lequel elles seront exécutées. Vous pouvez également définir des délais entre les commandes. C'est ainsi que j'ai réussi à effectuer la séquence d'actions que vous voyez dans la vidéo.

L'une des phrases de mon schéma vocal est « joue une petite chanson ». Cette phrase contient deux commandes. La première commande envoie un octet qui indique que la commande suivante va être un flux audio. L'Arduino commence alors à « jouer » les LED pendant la transmission de l'audio. L'audio est un petit jingle de piano que j'ai enregistré moi-même et que j'ai défini comme source audio de la deuxième commande. BitVoicer Server ne prend en charge que l'audio PCM mono 8 bits (8000 échantillons par seconde), donc si vous devez convertir un fichier audio dans ce format, je vous recommande l'outil de conversion en ligne suivant :http://audio.online-convert.com/convert -to-wav.

Vous pouvez importer (Importer des objets de solution) tous les objets de solution que j'ai utilisés dans ce projet à partir des fichiers ci-dessous. L'un contient le périphérique DUE et l'autre contient le schéma vocal et ses commandes.

Fichiers d'objet de solution :

  • Device.sof
  • VoiceSchema.sof

ÉTAPE 4 :Conclusion

Voilà! Vous pouvez tout activer et faire les mêmes choses que celles montrées dans la vidéo.

Comme je l'ai fait dans mon projet précédent, j'ai commencé la reconnaissance vocale en activant le périphérique Arduino dans le gestionnaire de serveur BitVoicer. Dès qu'il est activé, l'Arduino identifie un moteur de reconnaissance vocale disponible et commence à diffuser de l'audio vers BitVoicer Server. Cependant, vous voyez maintenant beaucoup plus d'activité dans le voyant Arduino RX pendant que l'audio est diffusé du serveur BitVoicer vers l'Arduino.

Dans mon prochain projet, je serai un peu plus ambitieux. Je vais ajouter la communication WiFi à un Arduino et contrôler deux autres Arduinos tous ensemble par la voix. Je pense à une sorte de jeu entre eux. Les suggestions sont les bienvenues !

Code

  • Esquisse Arduino
Arduino SketchArduino
#include #include #include #include // Définit la broche Arduino qui sera utilisée pour capturer l'audio #define BVSM_AUDIO_INPUT 7// Définit les broches LED#define RED_LED_PIN 6#define YELLOW_LED_PIN 9#define GREEN_LED_PIN 10// Définit les constantes qui seront passées en paramètre à // la fonction BVSP.beginconst unsigned long STATUS_REQUEST_TIMEOUT =3000;const unsigned long STATUS_VAL_REQUEST/; Définit la taille du buffer audio du micro const int MIC_BUFFER_SIZE =64;// Définit la taille du buffer audio du haut-parleurconst int SPEAKER_BUFFER_SIZE =128;// Définit la taille du buffer de réceptionconst int RECEIVE_BUFFER_SIZE =2;// Initialise une nouvelle instance globale de la classe BVSP BVSP bvsp =BVSP();// Initialise une nouvelle instance globale de la classe BVSMic BVSMic bvsm =BVSMic(); // Initialise une nouvelle instance globale de la classe BVSSpeaker BVSSpeaker bvss =BVSSpeaker(); // Crée un tampon qui sera utilisé pour lire les échantillons enregistrés // à partir de t l'octet de classe BVSMic micBuffer[MIC_BUFFER_SIZE];// Crée un tampon qui sera utilisé pour écrire des échantillons audio // dans l'octet de classe BVSSpeaker speakerBuffer[SPEAKER_BUFFER_SIZE];// Crée un tampon qui sera utilisé pour lire les commandes envoyées// du serveur BitVoicer.// Octet 0 =numéro de broche// Octet 1 =valeur de la broche octet receiveBuffer[RECEIVE_BUFFER_SIZE] ;// Ces variables sont utilisées pour contrôler quand jouer// "LED Notes". Ces notes seront jouées avec // la chanson diffusée depuis BitVoicer Server.bool playLEDNotes =false;unsigned int playStartTime =0;void setup() { // Configure les modes de broche pinMode(RED_LED_PIN, OUTPUT); pinMode(YELLOW_LED_PIN, SORTIE); pinMode(GREEN_LED_PIN, SORTIE); // Définit l'état initial de toutes les LED digitalWrite(RED_LED_PIN, LOW); digitalWrite(YELLOW_LED_PIN, LOW); digitalWrite(GREEN_LED_PIN, LOW); // Démarre la communication série à 115200 bps Serial.begin(115200); // Définit le port série Arduino qui sera utilisé pour // la communication, combien de temps il faudra avant qu'une demande d'état // expire et à quelle fréquence les demandes d'état doivent être envoyées à // BitVoicer Server. bvsp.begin(Série, STATUS_REQUEST_TIMEOUT, STATUS_REQUEST_INTERVAL); // Définit la fonction qui gérera l'événement frameReceived // bvsp.frameReceived =BVSP_frameReceived; // Définit la fonction qui gérera l'événement modeChanged // bvsp.modeChanged =BVSP_modeChanged; // Définit la fonction qui gérera l'événement streamReceived // bvsp.streamReceived =BVSP_streamReceived; // Prépare le timer de classe BVSMic bvsm.begin(); // Définit le DAC qui sera utilisé par la classe BVSSpeaker bvss.begin(DAC);}void loop() { // Vérifie si l'intervalle de demande d'état s'est écoulé et // si c'est le cas, envoie une demande d'état au serveur BitVoicer bvsp.keepAlive(); // Vérifie si des données sont disponibles dans le tampon du port série // et traite son contenu selon les spécifications // du protocole BitVoicer Server bvsp.receive(); // Vérifie s'il y a un SRE disponible. S'il y en a un, // commence l'enregistrement. if (bvsp.isSREAvailable()) { // Si la classe BVSMic n'enregistre pas, configure l'entrée // audio et démarre l'enregistrement if (!bvsm.isRecording) { bvsm.setAudioInput(BVSM_AUDIO_INPUT, DEFAULT); bvsm.startRecording(); } // Vérifie si la classe BVSMic a des échantillons disponibles if (bvsm.available) { // S'assure que le mode entrant est STREAM_MODE avant // de transmettre le flux if (bvsp.inboundMode ==FRAMED_MODE) bvsp.setInboundMode(STREAM_MODE); // Lit les échantillons audio de la classe BVSMic int bytesRead =bvsm.read(micBuffer, MIC_BUFFER_SIZE); // Envoie le flux audio à BitVoicer Server bvsp.sendStream(micBuffer, bytesRead); } } else { // Aucun SRE n'est disponible. Si la classe BVSMic enregistre, // l'arrête. if (bvsm.isRecording) bvsm.stopRecording(); } // Lit tous les échantillons audio disponibles dans la classe BVSSpeaker // tampon interne. Ces exemples sont écrits dans le // gestionnaire d'événements BVSP_streamReceived. Si aucun échantillon n'est // disponible dans le tampon interne, rien n'est lu. bvss.play(); // Si playLEDNotes a été défini sur true, // joue les "notes LED" avec la musique. if (playLEDNotes) playNextLEDNote();}// Gère l'événement frameReceived void BVSP_frameReceived(byte dataType, int payloadSize) { // Vérifie si la trame reçue contient des données binaires // 0x07 =Données binaires (tableau d'octets) if (dataType ==DATA_TYPE_BINARY) { // Si 2 octets ont été reçus, traite la commande. if (bvsp.getReceivedBytes(receiveBuffer, RECEIVE_BUFFER_SIZE) ==RECEIVE_BUFFER_SIZE) { analogWrite(receiveBuffer[0], receiveBuffer[1]); } } // Vérifie si la trame reçue contient un type de données d'octet // 0x01 =Type de données d'octet else if (dataType ==DATA_TYPE_BYTE) { // Si la valeur d'octet reçue est 255, définit playLEDNotes // et marque l'heure actuelle. if (bvsp.getReceivedByte() ==255) { playLEDNotes =true; playStartTime =millis(); } }}// Gère l'événement modeChanged void BVSP_modeChanged() { // Si le mode sortant (Serveur --> Périphérique) est passé à // FRAMED_MODE, aucun flux audio n'est censé être reçu. // Indique à la classe BVSSpeaker de terminer la lecture lorsque // son tampon interne devient vide. if (bvsp.outboundMode ==FRAMED_MODE) bvss.finishPlaying();} // Gère l'événement streamReceived void BVSP_streamReceived(int size) { // Obtient le flux reçu de la classe BVSP int bytesRead =bvsp.getReceivedStream(speakerBuffer, SPEAKER_BIZE); // Met en file d'attente le flux reçu pour jouer bvss.enqueue(speakerBuffer, bytesRead);}// Allume la LED appropriée en fonction de l'heure // la commande pour commencer à jouer les notes LED a été reçue.// Les timings utilisés ici sont synchronisés avec the music.void playNextLEDNote(){ // Obtient le temps écoulé entre playStartTime et // l'heure actuelle. non signé longtemps écoulé =millis () - playStartTime; // Éteint toutes les LED allLEDsOff(); // La dernière note a été jouée. // Éteint la dernière LED et arrête de jouer les notes LED. if (elapsed>=11500) { analogWrite(RED_LED_PIN, 0); playLEDNotes =false; } else if (elapsed>=9900) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed>=9370) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed>=8900) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed>=8610) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed>=8230) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed>=7970) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed>=7470) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed>=6760) analogWrite(GREEN_LED_PIN, 255); // E note else if (elapsed>=6350) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed>=5880) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed>=5560) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed>=5180) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed>=4890) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed>=4420) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed>=3810) analogWrite(GREEN_LED_PIN, 255); // E note else if (elapsed>=3420) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed>=2930) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed>=2560) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed>=2200) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed>=1930) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed>=1470) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed>=1000) analogWrite(GREEN_LED_PIN, 255); // E note}// Éteint toutes les LED.void allLEDsOff(){ analogWrite(RED_LED_PIN, 0); analogWrite(YELLOW_LED_PIN, 0); analogWrite(GREEN_LED_PIN, 0);}

Schémas


Processus de fabrication

  1. Système de présence utilisant Arduino et RFID avec Python
  2. Capteur DHT11 avec LED et haut-parleur piézo
  3. Gyroscope amusant avec l'anneau NeoPixel
  4. Arduino Temp. Moniteur et horloge en temps réel avec affichage 3.2
  5. Contrôler un robot Roomba avec Arduino et un appareil Android
  6. Voltmètre DIY avec Arduino et un écran Nokia 5110
  7. Contrôle du servomoteur avec Arduino et MPU6050
  8. module GPS u-blox LEA-6H 02 avec Arduino et Python
  9. Comment lire la température et l'humidité sur Blynk avec DHT11