Un NXT à commande vocale !

, par  Sylvain Cacheux

Le kit de base NXT comporte un microphone. On peut s’en servir comme télécommande. Voici comment.

La commande vocale s’insinue partout. Les derniers GPS, les téléphones portables incluent maintenant des processeurs suffisamment puissants, voire même des puces dédiées, leur permettant de proposer cette fonctionnalité.

Le NXT ne la propose pas de base, comblons donc cette lacune !

Ben oui mais comment qu’c’est-y don’ possible, cré fieux !??

Effectivement, les plus avertis d’entre vous auront vite remarqué que le NXT ne contient pas un Intel Quad Core ni 2 Gb de RAM et se demandent donc une architecture si modeste peut quand même faire reconnaitre la voix !

Forcément, y’a un truc.

Mon idée n’est pas de reconnaitre la voix en tant que telle, mais un ordre.

Whouah, quelle différence sibylline !

Ok, je développe.

Évidemment, le NXT n’est pas capable de reconnaitre des mots, et encore moins des phrases. En revanche, il sait capter du bruit via son micro.

Ce micro n’indique au NXT que l’intensité sonore qu’il détecte, avec un niveau variant de 0 (rien) à 100 (saturation du micro). Le NXT possède aussi des timers. Je commence à voir votre oeil qui s’illumine !

Voilà : il suffit de mesurer pendant combien de temps un niveau sonore est détecté !

On utilise un timer qu’on déclenche lorsque le niveau sonore détecté par le NXT dépasse un certain seuil (qu’on calibre auparavant sur le niveau sonore ambiant). C’est la détection de l’ordre (T0).

C’est bien, on a détecté un ordre. Mais lequel ?

En fait, le timer s’arrête lorsque le niveau sonore baisse, c’est à dire la fin de l’ordre (T1).

Du coup, il suffit de comparer T1-T0 (=ordre) à une table.

Exemple :
- Si 0 < ordre < 500 ms, alors effectuer telle action
- Si 500 ms < ordre < 1 s, alors effectuer telle autre action
- Si 1s < ordre < 1,5 s, alors effectuer encore telle autre action.
- etc.

Voici, ci-dessous, un programme en RobotC (à copier/coller directement dans RobotC, qui remettra en forme) qui met en pratique cette théorie. Dans ce programme, vous verrez qu’en fonction de la longueur de votre ordre, un numéro s’affiche sur l’écran.

A vous de modifier cela pour faire faire à votre NXT ce que vous voulez !

Un bémol cependant : il faut évidement garder le niveau sonore à un certain niveau pour que le NXT continue de mesurer la durée de l’ordre. C’est pour cela que j’ai ajouter une petite pause dans la boucle. Elle évite de couper la mesure entre 2 mots. C’est une petite bidouille qui peut être améliorée, je vous laisse tester !

A bientôt pour de nouvelles aventures !

#pragma config(Sensor, S1,     soundSensor,         sensorSoundDB)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

/*--------------------------------------------------------------------------------------------------------*\
|*                                                                                                        *|
|*                                        - commandes vocales -                                           *|
|*                                            ROBOTC on NXT                                               *|
|*                                                                                                        *|
|*  This program runs tasks depending on sound delay, which can be assimilated to vocal commands.         *|
|*                                                                                                        *|
|*                                        ROBOT CONFIGURATION                                             *|
|*    NOTES:                                                                                              *|
|*    1)  The 1 second delay is needed to avoid obtaining inaccurate initial readings.                    *|
|*                                                                                                        *|
|*    MOTORS & SENSORS:                                                                                   *|
|*    [I/O Port]              [Name]              [Type]              [Description]                       *|
|*    Port B                  motorB              NXT                 Right motor                         *|
|*    Port C                  motorC              NXT                 Left motor                          *|
|*    Port 1                  soundSensor         Sound Sensor        Sound Db Right                      *|
\*-------------------------------------------------------------------------------------------------------*/

int NiveauReference, DureeSon;


task main()
{
 NiveauReference = 0;
 DureeSon = 0;

 wait1Msec(1000);       // A one-second wait is required to cleanly initialize the Sound Sensor.
 eraseDisplay();

 //initializing ambiant sound level
 NiveauReference = SensorValue[soundSensor];
 nxtDisplayTextLine(0, "niveau actuel :");
 nxtDisplayTextLine(1, "%2i", NiveauReference);
 wait1Msec(3000);
 eraseDisplay();

 while(true)            // Infinite loop
 {
           ClearTimer(T1); // reseting timer and showing the current sound level
           nxtDisplayTextLine(0, "niveau son :");
           nxtDisplayTextLine(1, "%2i", SensorValue[soundSensor]);

           // checking if the sound level detects words
           while (SensorValue[soundSensor] > (NiveauReference + 10))
           {
              DureeSon = time1[T1]; // incrementing the variable according to timer to have the sound delay eared by the NXT
              nxtDisplayTextLine(2, "Ecoute depuis"); // indicating from how long the NXT "ears" words (orders)
              nxtDisplayTextLine(3, "   %2i ms", DureeSon);
              wait1Msec(250); // pause to avoid breaking measure word after word, can be adjusted.
              /* this pause is a kind of pb as if you are between 2 words at the end of pause, the loop ends...
                 another way of programing could be the following :
                 loop:
                 {
                 check sound level,
                 if sound level > reference + 10 then initiate timer
                 wait 500 ms (or a little less, for next measuring processing time)
                 measure timer :
                   if the sound level is under reference +10, then order 1 and end loop
                   else
                     wait another 500 ms (so we have a 1 second delay/order)
                     if the sound level is under reference +10, then order 2 and end loop
                     else
                              wait 1000 ms (so we have a 2 seconds delay/order)
                              if the sound level is under reference +10, then order 3 and end loop
                              else
                                      wait another 1000 ms (so we have a 3 seconds delay/order)
                                      if the sound level is under reference +10, then order 4 and end loop
                                      else
                                              wait another 1000 ms (so we have a 4 seconds delay/order)
                                              if the sound level is under reference +10, then order 5 and end loop
                                              else
                                                      wait another ? ms (so we have a more than 4 seconds delay/order)
                                                      if the sound level is under reference +10, then order 6 and end loop
                 }
              */
           }

           // checking if an "order" have been "eared"
           if (DureeSon > 0)
           {
             // defining orders depending on the order's delay
             if ((DureeSon >    0) & (DureeSon <  500)) DureeSon = 1;
      if ((DureeSon >  500) & (DureeSon < 1000)) DureeSon = 2;
             if ((DureeSon > 1000) & (DureeSon < 2000)) DureeSon = 3;
             if ((DureeSon > 2000) & (DureeSon < 3000)) DureeSon = 4;
             if ((DureeSon > 3000) & (DureeSon < 4000)) DureeSon = 5;
             if  (DureeSon > 4000)                      DureeSon = 6;

      switch (DureeSon)
      {
        case 1:
          nxtDisplayTextLine(3, "Ordre 1");
          wait1Msec(2000);
          break;
        case 2:
          nxtDisplayTextLine(3, "Ordre 2");
          wait1Msec(2000);
          break;
        case 3:
          nxtDisplayTextLine(3, "Ordre 3");
          wait1Msec(2000);
          break;
        case 4:
          nxtDisplayTextLine(3, "Ordre 4");
          wait1Msec(2000);
          break;
        case 5:
          nxtDisplayTextLine(3, "Ordre 5");
          wait1Msec(2000);
          break;
        case 6:
          nxtDisplayTextLine(3, "Ordre 6");
          wait1Msec(2000);
          break;
        case 0:
          nxtDisplayTextLine(3, "Ratage...");
          wait1Msec(2000);
          break;
        default:
      }
      // reinitializing the "order"
      DureeSon = 0;
      eraseDisplay();
    }
 }
}

Navigation

AgendaTous les événements

décembre 2024 :

Rien pour ce mois

novembre 2024 | janvier 2025

Brèves Toutes les brèves