Différences entre versions de « Senseur IR Decodeur IR »

De MCHobby - Wiki
Sauter à la navigation Sauter à la recherche
 
(4 versions intermédiaires par le même utilisateur non affichées)
Ligne 3 : Ligne 3 :
 
{{ADFImage|IR-appleremote.jpeg|400px}}
 
{{ADFImage|IR-appleremote.jpeg|400px}}
  
For our final project, we will use a remote control to send messages to a microcontroller. For example, this might be useful for a robot that can be directed with an IR remote. It can also be good for projects that you want to control from far away, without wires.
+
Pour notre projet final, nous allons utiliser une commande à distance pour envoyer des messages à un microcontrôleur. Par exemple, cela peut être utile afin de pouvoir piloter un robot à distance. C'est également un technique intéressante pour contrôler un projet à distance, sans avoir besoin de fils.
  
For a remote in this example we'll be using an Apple clicker remote. You can use any kind of remote you wish, or you can steal one of these from an unsuspecting hipster.
+
En guise de télécommande, ce tuto utilise une télécommande Apple. Vous pouvez utiliser n'importe quelle type de télécommande, une déjà utilisée à la maison ou une de récupération.
  
We'll use the code from our previous sketch for raw IR reading but this time we'll edit our printer-outer to have it give us the pulses in a C array, this will make it easier for us to use for pattern matching.
+
Nous allons utiliser le code du croquis/sketch précédent pour lire les données en provenance de la télécommande mais cette fois, nous allons afficher le contenu des informations sous forme de tableau afin de détecter plus facilement un ''pattern'' (un patron).
  
 
  <nowiki>
 
  <nowiki>
    void printpulses(void) {
+
void printpulses(void) {
 
     Serial.println("\n\r\n\rReceived: \n\rOFF \tON");
 
     Serial.println("\n\r\n\rReceived: \n\rOFF \tON");
 
     for (uint8_t i = 0; i < currentpulse; i++) {
 
     for (uint8_t i = 0; i < currentpulse; i++) {
    Serial.print(pulses[i][0] * RESOLUTION, DEC);
+
      Serial.print(pulses[i][0] * RESOLUTION, DEC);
    Serial.print(" usec, ");
+
      Serial.print(" usec, ");
    Serial.print(pulses[i][1] * RESOLUTION, DEC);
+
      Serial.print(pulses[i][1] * RESOLUTION, DEC);
    Serial.println(" usec");
+
      Serial.println(" usec");
 
     }
 
     }
 
     // print it in a 'array' format
 
     // print it in a 'array' format
Ligne 22 : Ligne 22 :
 
     Serial.println("// ON, OFF (in 10's of microseconds)");
 
     Serial.println("// ON, OFF (in 10's of microseconds)");
 
     for (uint8_t i = 0; i < currentpulse-1; i++) {
 
     for (uint8_t i = 0; i < currentpulse-1; i++) {
    Serial.print("\t"); // tab
+
      Serial.print("\t"); // tab
    Serial.print(pulses[i][1] * RESOLUTION / 10, DEC);
+
      Serial.print(pulses[i][1] * RESOLUTION / 10, DEC);
    Serial.print(", ");
+
      Serial.print(", ");
    Serial.print(pulses[i+1][0] * RESOLUTION / 10, DEC);
+
      Serial.print(pulses[i+1][0] * RESOLUTION / 10, DEC);
    Serial.println(",");
+
      Serial.println(",");
 
     }
 
     }
 
     Serial.print("\t"); // tab
 
     Serial.print("\t"); // tab
 
     Serial.print(pulses[currentpulse-1][1] * RESOLUTION / 10, DEC);
 
     Serial.print(pulses[currentpulse-1][1] * RESOLUTION / 10, DEC);
 
     Serial.print(", 0};");
 
     Serial.print(", 0};");
    }
+
}
 
</nowiki>
 
</nowiki>
  
I uploaded the new sketch and pressed the Play button on the Apple remote and got the following:
+
Le nouveau croquis téléversé sur notre Arduino, pressons le bouton "Jouer" de la télécommande et voyons le résutlat que nous allons obtenir:
  
 
  <nowiki>
 
  <nowiki>
 
+
int IRsignal[] = { // ON, OFF (in 10's of microseconds)
 
 
    int IRsignal[] = { // ON, OFF (in 10's of microseconds)
 
 
     912, 438,
 
     912, 438,
 
     68, 48,
 
     68, 48,
Ligne 77 : Ligne 75 :
 
     66, 3012,
 
     66, 3012,
 
     908, 212,
 
     908, 212,
     68, 0};
+
     68, 0 };
 
</nowiki>
 
</nowiki>
  
We'll try to detect that code. Lets start a new sketch called IR Commander ([http://github.com/adafruit/IR-Commander la version finale du code est disponible sur le GitHub d'AdaFruit]) this will use parts of our previous sketch. The first part we'll do is to create a function that just listens for an IR code an puts the pulse timings into the pulses[] array. It will return the number of pulses it heard as a return-value.
+
Nous allons essayer de détecter ce code. Essayons de démarrer un nouveau croquis appelé IR Commander ([http://github.com/adafruit/IR-Commander la version finale du code est disponible sur le GitHub d'AdaFruit]) qui utilisera une partie de notre précédent croquis.  
 +
 
 +
La première partie écourtera simplement le code Infrarouge et placera les temps d'impulsion dans le tableau {{fname|pulses[]}}. Il retournera le nombre d'impulsions détecté comme valeur de retour.
  
 
  <nowiki>
 
  <nowiki>
    int listenForIR(void) {
+
int listenForIR(void) {
    currentpulse = 0;
+
currentpulse = 0;
    while (1) {
+
while (1) {
 
     uint16_t highpulse, lowpulse; // temporary storage timing
 
     uint16_t highpulse, lowpulse; // temporary storage timing
 
     highpulse = lowpulse = 0; // start out with no pulse length
 
     highpulse = lowpulse = 0; // start out with no pulse length
 
     // while (digitalRead(IRpin)) { // this is too slow!
 
     // while (digitalRead(IRpin)) { // this is too slow!
 
     while (IRpin_PIN & (1 << IRpin)) {
 
     while (IRpin_PIN & (1 << IRpin)) {
    // pin is still HIGH
+
      // pin is still HIGH
    // count off another few microseconds
+
      // count off another few microseconds
    highpulse++;
+
      highpulse++;
    delayMicroseconds(RESOLUTION);
+
      delayMicroseconds(RESOLUTION);
    // If the pulse is too long, we 'timed out' - either nothing
+
      // If the pulse is too long, we 'timed out' - either nothing
    // was received or the code is finished, so print what
+
      // was received or the code is finished, so print what
    // we've grabbed so far, and then reset
+
      // we've grabbed so far, and then reset
    if ((highpulse >= MAXPULSE) && (currentpulse != 0)) {
+
      if ((highpulse >= MAXPULSE) && (currentpulse != 0)) {
    return currentpulse;
+
          return currentpulse;
    }
+
      }
 
     }
 
     }
 
     // we didn't time out so lets stash the reading
 
     // we didn't time out so lets stash the reading
Ligne 105 : Ligne 105 :
 
     // same as above
 
     // same as above
 
     while (! (IRpin_PIN & _BV(IRpin))) {
 
     while (! (IRpin_PIN & _BV(IRpin))) {
    // pin is still LOW
+
      // pin is still LOW
    lowpulse++;
+
      lowpulse++;
    delayMicroseconds(RESOLUTION);
+
      delayMicroseconds(RESOLUTION);
    if ((lowpulse >= MAXPULSE) && (currentpulse != 0)) {
+
      if ((lowpulse >= MAXPULSE) && (currentpulse != 0)) {
    return currentpulse;
+
          return currentpulse;
    }
+
      }
 
     }
 
     }
 
     pulses[currentpulse][1] = lowpulse;
 
     pulses[currentpulse][1] = lowpulse;
Ligne 116 : Ligne 116 :
 
     currentpulse++;
 
     currentpulse++;
 
     }
 
     }
    }
+
}
 
</nowiki>
 
</nowiki>
  
Our new '''loop()''' will start out just listening for pulses
+
Notre nouvelle fonction {{fname|loop()}} ne fera qu' "écouter" après les impulsions.
  
 
  <nowiki>
 
  <nowiki>
    void loop(void) {
+
void loop(void) {
 
     int numberpulses;
 
     int numberpulses;
 
     numberpulses = listenForIR();
 
     numberpulses = listenForIR();
Ligne 128 : Ligne 128 :
 
     Serial.print(numberpulses);
 
     Serial.print(numberpulses);
 
     Serial.println("-pulse long IR signal");
 
     Serial.println("-pulse long IR signal");
    }
+
}
 
</nowiki>
 
</nowiki>
  
When we run this it will print out something like...
+
Lorsqu'il fonctionne, il affiche quelque chose comme ceci...
  
 
{{ADFImage|IR-pulsecounter.jpg}}
 
{{ADFImage|IR-pulsecounter.jpg}}
  
OK time to make the sketch compare what we received to what we have in our stored array:
+
OK, il est maintenant temps de faire en sorte que notre croquis compare ce qu'il à reçu et ce qu'il a déjà dans le notre tableau de référence:
  
 
{{ADFImage|IR-ircompare.jpg}}
 
{{ADFImage|IR-ircompare.jpg}}
  
As you can see, there is some variation. So when we do our comparison we can't look for preciesely the same values, we have to be a little 'fuzzy'. We'll say that the values can vary by 20% - that should be good enough.
+
Comme vous pouvez le voir, il y a quelques variations. Lorsque nous faisons la comparaison, nous ne pouvons malheureusement pas attendre d'avoir exactement les mêmes valeurs, nous devons opter pour une méthode un peu plus 'créative'.  
 +
 
 +
Disons que la valeur peu varier d'environ 20% - cela devrait être suffisant.
  
 
  <nowiki>
 
  <nowiki>
 +
// Quel pourcentage de variation est toléré durant la comparaison de deux code
 +
#define FUZZINESS 20
  
 
+
void loop(void) {
    // What percent we will allow in variation to match the same code \\ #define FUZZINESS 20
 
    void loop(void) {
 
 
     int numberpulses;
 
     int numberpulses;
 
     numberpulses = listenForIR();
 
     numberpulses = listenForIR();
Ligne 152 : Ligne 154 :
 
     Serial.println("-pulse long IR signal");
 
     Serial.println("-pulse long IR signal");
 
     for (int i=0; i< numberpulses-1; i++) {
 
     for (int i=0; i< numberpulses-1; i++) {
    int oncode = pulses[i][1] * RESOLUTION / 10;
+
      int oncode = pulses[i][1] * RESOLUTION / 10;
    int offcode = pulses[i+1][0] * RESOLUTION / 10;
+
      int offcode = pulses[i+1][0] * RESOLUTION / 10;
    Serial.print(oncode); // the ON signal we heard
+
 
    Serial.print(" - ");
+
      Serial.print(oncode); // le signal ON réceptionné
    Serial.print(ApplePlaySignal[i*2 + 0]); // the ON signal we want
+
      Serial.print(" - ");
    // check to make sure the error is less than FUZZINESS percent
+
      Serial.print(ApplePlaySignal[i*2 + 0]); // Le signal ON attendu
    if ( abs(oncode - ApplePlaySignal[i*2 + 0]) <= (oncode * FUZZINESS / 100)) {
+
      // Vérifier pour s'arrure que l'erreur est inférieure à FUZZINESS pourcent
    Serial.print(" (ok)");
+
      if ( abs(oncode - ApplePlaySignal[i*2 + 0]) <= (oncode * FUZZINESS / 100)) {
    } else {
+
        Serial.print(" (ok)");
    Serial.print(" (x)");
+
      } else {
    }
+
        Serial.print(" (x)");
    Serial.print(" \t"); // tab
+
      }
    Serial.print(offcode); // the OFF signal we heard
+
      Serial.print(" \t"); // tab
    Serial.print(" - ");
+
 
    Serial.print(ApplePlaySignal[i*2 + 1]); // the OFF signal we want
+
      Serial.print(offcode); // Le signal OFF réceptionné
    if ( abs(offcode - ApplePlaySignal[i*2 + 1]) <= (offcode * FUZZINESS / 100)) {
+
      Serial.print(" - ");
    Serial.print(" (ok)");
+
      Serial.print(ApplePlaySignal[i*2 + 1]); // Le signal OFF attendu
    } else {
+
      if ( abs(offcode - ApplePlaySignal[i*2 + 1]) <= (offcode * FUZZINESS / 100)) {
    Serial.print(" (x)");
+
        Serial.print(" (ok)");
    }
+
      } else {
    Serial.println();
+
        Serial.print(" (x)");
    }
+
      }
 +
      Serial.println();
 
     }
 
     }
 +
}
 
</nowiki>
 
</nowiki>
  
 
{{ADFImage|IR-codecompareok.jpg}}
 
{{ADFImage|IR-codecompareok.jpg}}
  
 +
Cette fonction {{fname|loop()}}, est exécutée pour chaque impulsion, fait quelques opérations mathématique. Elle compare la différence absolue ({{fname|abs()}}) entre ce que code réceptionne (IR reçu) et le code auquel nous essayons de le faire correspondre {{fname|abs(oncode - ApplePlaySignal[i*2 + 0])}} et ensuire s'assurer que l'erreur est inférieure FUZZINESS pourcent de la longueur du code
 +
( {{fname| oncode * FUZZINESS / 100}} )
  
 +
Il est généralement nécessaire d'adapter un peu les valeurs stockées pour obtenir 100% correspondance à chaque fois. Le signal infrarouge n'est pas un protocol qui s'appuie sur la précision temporelle (''not a precision-timed protocol''), par conséquent une marge d'erreur de 20% (FUZZINESS=20%) et plus n'est pas une mauvaise chose.
  
This loop, as it goes through each pulse, does a little math. It compares the absolute ('''abs()''') difference between the code we heard and the code we're trying to match abs(oncode - ApplePlaySignal[i*2 + 0]) and then makes sure that the error is less than FUZZINESS percent of the code length (oncode * FUZZINESS / 100)
+
Pour finir, Le contenu de {{fname|loop()}} est transformé en sa propre fonction qui retourne '''true''' ou '''false''' en fonction du code que nous luis avons demandé de vérifier. Les lignes {{fname|Serial.print()}} ont également été mises en commentaire.
 
 
We found we had to tweak the stored values a little to make them match up 100% each time. IR is not a precision-timed protocol so having to make the FUZZINESS 20% or more is not a bad thing
 
 
 
Finally, we can turn the '''loop()''' into its own function which will retunr '''true''' or '''false''' depending on whether it matched the code we ask it to. We also commented out the printing functions
 
  
 
  <nowiki>
 
  <nowiki>
    boolean IRcompare(int numpulses, int Signal[]) {
+
boolean IRcompare(int numpulses, int Signal[]) {
 
     for (int i=0; i< numpulses-1; i++) {
 
     for (int i=0; i< numpulses-1; i++) {
    int oncode = pulses[i][1] * RESOLUTION / 10;
+
        int oncode = pulses[i][1] * RESOLUTION / 10;
    int offcode = pulses[i+1][0] * RESOLUTION / 10;
+
        int offcode = pulses[i+1][0] * RESOLUTION / 10;
    /*
+
 
    Serial.print(oncode); // the ON signal we heard
+
        /*
    Serial.print(" - ");
+
        Serial.print(oncode); // Le signal ON reçu
    Serial.print(Signal[i*2 + 0]); // the ON signal we want
+
        Serial.print(" - ");
    */
+
        Serial.print(Signal[i*2 + 0]); // Le signal ON attendu
    // check to make sure the error is less than FUZZINESS percent
+
        */
    if ( abs(oncode - Signal[i*2 + 0]) <= (Signal[i*2 + 0] * FUZZINESS / 100)) {
+
        // Vérifier que l'erreur est inférieure à FUZZINESS pourcent
    //Serial.print(" (ok)");
+
        if ( abs(oncode - Signal[i*2 + 0]) <= (Signal[i*2 + 0] * FUZZINESS / 100)) {
    } else {
+
            //Serial.print(" (ok)");
    //Serial.print(" (x)");
+
        } else {
    // we didn't match perfectly, return a false match
+
            //Serial.print(" (x)");
    return false;
+
            // Pas de correspondance parfaite, retourner false
    }
+
            return false;
     /*
+
        }
    Serial.print(" \t"); // tab
+
      
    Serial.print(offcode); // the OFF signal we heard
+
        /*
    Serial.print(" - ");
+
        Serial.print(" \t"); // tabulation
    Serial.print(Signal[i*2 + 1]); // the OFF signal we want
+
        Serial.print(offcode); // Le signal OFF reçu
    */
+
        Serial.print(" - ");
    if ( abs(offcode - Signal[i*2 + 1]) <= (Signal[i*2 + 1] * FUZZINESS / 100)) {
+
        Serial.print(Signal[i*2 + 1]); // Le signal OFF que nous attendons
    //Serial.print(" (ok)");
+
        */
    } else {
+
        if ( abs(offcode - Signal[i*2 + 1]) <= (Signal[i*2 + 1] * FUZZINESS / 100)) {
    //Serial.print(" (x)");
+
          //Serial.print(" (ok)");
    // we didn't match perfectly, return a false match
+
        } else {
    return false;
+
          //Serial.print(" (x)");
    }
+
          // Pas de correspondance parfaite, retourner false
    //Serial.println();
+
          return false;
 +
        }
 +
        //Serial.println();
 
     }
 
     }
     // Everything matched!
+
     // Tout correspond!
 
     return true;
 
     return true;
    }
+
}
 
</nowiki>
 
</nowiki>
  
 +
Ensuite, nous capturons plus de données infrarouge comme 'précédent' (''rewind'') ou 'suivant' (''fastforward'') et plaçons ces informations dans des tableaux stockés dans le fichier {{fname|ircodes.h}} pour éviter que le croquis/sketch principal ne devienne trop long et illisible ([http://github.com/adafruit/IR-Commander vous pouvez obtenir tout le code depuis le GitHib d'AdaFruit)
  
 
+
A la fin, la boucle principale ressemble à ceci:
We then took more IR command data for the 'rewind' and 'fastforward' buttons and put all the code array data into ircodes.h to keep the main sketch from being too long and unreadable ([http://github.com/adafruit/IR-Commander vous pouvez obtenir tout le code depuis le GitHib d'AdaFruit)
 
 
 
Finally, the main loop looks like this:
 
  
 
  <nowiki>
 
  <nowiki>
    void loop(void) {
+
void loop(void) {
 
     int numberpulses;
 
     int numberpulses;
 
     numberpulses = listenForIR();
 
     numberpulses = listenForIR();
 +
 
     Serial.print("Heard ");
 
     Serial.print("Heard ");
 
     Serial.print(numberpulses);
 
     Serial.print(numberpulses);
 
     Serial.println("-pulse long IR signal");
 
     Serial.println("-pulse long IR signal");
 
     if (IRcompare(numberpulses, ApplePlaySignal)) {
 
     if (IRcompare(numberpulses, ApplePlaySignal)) {
    Serial.println("PLAY");
+
      Serial.println("PLAY");
 
     }
 
     }
 
     if (IRcompare(numberpulses, AppleRewindSignal)) {
 
     if (IRcompare(numberpulses, AppleRewindSignal)) {
    Serial.println("REWIND");
+
      Serial.println("REWIND");
 
     }
 
     }
 
     if (IRcompare(numberpulses, AppleForwardSignal)) {
 
     if (IRcompare(numberpulses, AppleForwardSignal)) {
    Serial.println("FORWARD");
+
      Serial.println("FORWARD");
    }
 
 
     }
 
     }
 +
}
 
</nowiki>
 
</nowiki>
  
 +
Nous vérifions les données réçues par rapport aux codes infrarouges que nous connaissons déjà et affichons un message avec ce que nous avons détecté.
  
 
+
Voila, une fois nos tests réussis, il ne reste plus qu'a prendre ce code pour en faire quelque-chose de plus utile (en fonction du bouton pressé).
We check against all the codes we know about and print out whenever we get a match. You could now take this code and turn it into something else, like a robot that moves depending on what button is pressed.
 
 
 
After testing, success!
 
  
 
{{ADFImage|mulitirbutton.jpg}}
 
{{ADFImage|mulitirbutton.jpg}}
  
 
{{SenseurIR-TRAILER}}
 
{{SenseurIR-TRAILER}}

Version actuelle datée du 4 avril 2019 à 17:17

IR-appleremote.jpeg
Crédit: AdaFruit Industries www.adafruit.com

Pour notre projet final, nous allons utiliser une commande à distance pour envoyer des messages à un microcontrôleur. Par exemple, cela peut être utile afin de pouvoir piloter un robot à distance. C'est également un technique intéressante pour contrôler un projet à distance, sans avoir besoin de fils.

En guise de télécommande, ce tuto utilise une télécommande Apple. Vous pouvez utiliser n'importe quelle type de télécommande, une déjà utilisée à la maison ou une de récupération.

Nous allons utiliser le code du croquis/sketch précédent pour lire les données en provenance de la télécommande mais cette fois, nous allons afficher le contenu des informations sous forme de tableau afin de détecter plus facilement un pattern (un patron).

void printpulses(void) {
    Serial.println("\n\r\n\rReceived: \n\rOFF \tON");
    for (uint8_t i = 0; i < currentpulse; i++) {
       Serial.print(pulses[i][0] * RESOLUTION, DEC);
       Serial.print(" usec, ");
       Serial.print(pulses[i][1] * RESOLUTION, DEC);
       Serial.println(" usec");
    }
    // print it in a 'array' format
    Serial.println("int IRsignal[] = {");
    Serial.println("// ON, OFF (in 10's of microseconds)");
    for (uint8_t i = 0; i < currentpulse-1; i++) {
       Serial.print("\t"); // tab
       Serial.print(pulses[i][1] * RESOLUTION / 10, DEC);
       Serial.print(", ");
       Serial.print(pulses[i+1][0] * RESOLUTION / 10, DEC);
       Serial.println(",");
    }
    Serial.print("\t"); // tab
    Serial.print(pulses[currentpulse-1][1] * RESOLUTION / 10, DEC);
    Serial.print(", 0};");
}

Le nouveau croquis téléversé sur notre Arduino, pressons le bouton "Jouer" de la télécommande et voyons le résutlat que nous allons obtenir:

int IRsignal[] = { // ON, OFF (in 10's of microseconds)
    912, 438,
    68, 48,
    68, 158,
    68, 158,
    68, 158,
    68, 48,
    68, 158,
    68, 158,
    68, 158,
    70, 156,
    70, 158,
    68, 158,
    68, 48,
    68, 46,
    70, 46,
    68, 46,
    68, 160,
    68, 158,
    70, 46,
    68, 158,
    68, 46,
    70, 46,
    68, 48,
    68, 46,
    68, 48,
    66, 48,
    68, 48,
    66, 160,
    66, 50,
    66, 160,
    66, 52,
    64, 160,
    66, 48,
    66, 3950,
    908, 214,
    66, 3012,
    908, 212,
    68, 0 };

Nous allons essayer de détecter ce code. Essayons de démarrer un nouveau croquis appelé IR Commander (la version finale du code est disponible sur le GitHub d'AdaFruit) qui utilisera une partie de notre précédent croquis.

La première partie écourtera simplement le code Infrarouge et placera les temps d'impulsion dans le tableau pulses[]. Il retournera le nombre d'impulsions détecté comme valeur de retour.

int listenForIR(void) {
currentpulse = 0;
while (1) {
    uint16_t highpulse, lowpulse; // temporary storage timing
    highpulse = lowpulse = 0; // start out with no pulse length
    // while (digitalRead(IRpin)) { // this is too slow!
    while (IRpin_PIN & (1 << IRpin)) {
       // pin is still HIGH
       // count off another few microseconds
       highpulse++;
       delayMicroseconds(RESOLUTION);
       // If the pulse is too long, we 'timed out' - either nothing
       // was received or the code is finished, so print what
       // we've grabbed so far, and then reset
       if ((highpulse >= MAXPULSE) && (currentpulse != 0)) {
          return currentpulse;
       }
    }
    // we didn't time out so lets stash the reading
    pulses[currentpulse][0] = highpulse;
    // same as above
    while (! (IRpin_PIN & _BV(IRpin))) {
       // pin is still LOW
       lowpulse++;
       delayMicroseconds(RESOLUTION);
       if ((lowpulse >= MAXPULSE) && (currentpulse != 0)) {
          return currentpulse;
       }
    }
    pulses[currentpulse][1] = lowpulse;
    // we read one high-low pulse successfully, continue!
    currentpulse++;
    }
}

Notre nouvelle fonction loop() ne fera qu' "écouter" après les impulsions.

void loop(void) {
    int numberpulses;
    numberpulses = listenForIR();
    Serial.print("Heard ");
    Serial.print(numberpulses);
    Serial.println("-pulse long IR signal");
}

Lorsqu'il fonctionne, il affiche quelque chose comme ceci...

{{{2}}}
Crédit: AdaFruit Industries www.adafruit.com

OK, il est maintenant temps de faire en sorte que notre croquis compare ce qu'il à reçu et ce qu'il a déjà dans le notre tableau de référence:

{{{2}}}
Crédit: AdaFruit Industries www.adafruit.com

Comme vous pouvez le voir, il y a quelques variations. Lorsque nous faisons la comparaison, nous ne pouvons malheureusement pas attendre d'avoir exactement les mêmes valeurs, nous devons opter pour une méthode un peu plus 'créative'.

Disons que la valeur peu varier d'environ 20% - cela devrait être suffisant.

// Quel pourcentage de variation est toléré durant la comparaison de deux code
#define FUZZINESS 20

void loop(void) {
    int numberpulses;
    numberpulses = listenForIR();
    Serial.print("Heard ");
    Serial.print(numberpulses);
    Serial.println("-pulse long IR signal");
    for (int i=0; i< numberpulses-1; i++) {
      int oncode = pulses[i][1] * RESOLUTION / 10;
      int offcode = pulses[i+1][0] * RESOLUTION / 10;

      Serial.print(oncode); // le signal ON réceptionné
      Serial.print(" - ");
      Serial.print(ApplePlaySignal[i*2 + 0]); // Le signal ON attendu
      // Vérifier pour s'arrure que l'erreur est inférieure à FUZZINESS pourcent
      if ( abs(oncode - ApplePlaySignal[i*2 + 0]) <= (oncode * FUZZINESS / 100)) {
        Serial.print(" (ok)");
      } else {
        Serial.print(" (x)");
      }
      Serial.print(" \t"); // tab

      Serial.print(offcode); // Le signal OFF réceptionné
      Serial.print(" - ");
      Serial.print(ApplePlaySignal[i*2 + 1]); // Le signal OFF attendu 
      if ( abs(offcode - ApplePlaySignal[i*2 + 1]) <= (offcode * FUZZINESS / 100)) {
        Serial.print(" (ok)");
      } else {
        Serial.print(" (x)");
      }
      Serial.println();
    }
 }

{{{2}}}
Crédit: AdaFruit Industries www.adafruit.com

Cette fonction loop(), est exécutée pour chaque impulsion, fait quelques opérations mathématique. Elle compare la différence absolue (abs()) entre ce que code réceptionne (IR reçu) et le code auquel nous essayons de le faire correspondre abs(oncode - ApplePlaySignal[i*2 + 0]) et ensuire s'assurer que l'erreur est inférieure FUZZINESS pourcent de la longueur du code

(  oncode * FUZZINESS / 100 )

Il est généralement nécessaire d'adapter un peu les valeurs stockées pour obtenir 100% correspondance à chaque fois. Le signal infrarouge n'est pas un protocol qui s'appuie sur la précision temporelle (not a precision-timed protocol), par conséquent une marge d'erreur de 20% (FUZZINESS=20%) et plus n'est pas une mauvaise chose.

Pour finir, Le contenu de loop() est transformé en sa propre fonction qui retourne true ou false en fonction du code que nous luis avons demandé de vérifier. Les lignes Serial.print() ont également été mises en commentaire.

boolean IRcompare(int numpulses, int Signal[]) {
    for (int i=0; i< numpulses-1; i++) {
        int oncode = pulses[i][1] * RESOLUTION / 10;
        int offcode = pulses[i+1][0] * RESOLUTION / 10;

        /*
        Serial.print(oncode); // Le signal ON reçu
        Serial.print(" - ");
        Serial.print(Signal[i*2 + 0]); // Le signal ON attendu
        */
        // Vérifier que l'erreur est inférieure à FUZZINESS pourcent
        if ( abs(oncode - Signal[i*2 + 0]) <= (Signal[i*2 + 0] * FUZZINESS / 100)) {
            //Serial.print(" (ok)");
        } else {
            //Serial.print(" (x)");
            // Pas de correspondance parfaite, retourner false
            return false;
        }
    
        /*
        Serial.print(" \t"); // tabulation
        Serial.print(offcode); // Le signal OFF reçu
        Serial.print(" - ");
        Serial.print(Signal[i*2 + 1]); // Le signal OFF que nous attendons
        */
        if ( abs(offcode - Signal[i*2 + 1]) <= (Signal[i*2 + 1] * FUZZINESS / 100)) {
           //Serial.print(" (ok)");
        } else {
           //Serial.print(" (x)");
           // Pas de correspondance parfaite, retourner false
           return false;
        }
        //Serial.println();
    }
    // Tout correspond!
    return true;
}

Ensuite, nous capturons plus de données infrarouge comme 'précédent' (rewind) ou 'suivant' (fastforward) et plaçons ces informations dans des tableaux stockés dans le fichier ircodes.h pour éviter que le croquis/sketch principal ne devienne trop long et illisible ([http://github.com/adafruit/IR-Commander vous pouvez obtenir tout le code depuis le GitHib d'AdaFruit)

A la fin, la boucle principale ressemble à ceci:

void loop(void) {
    int numberpulses;
    numberpulses = listenForIR();

    Serial.print("Heard ");
    Serial.print(numberpulses);
    Serial.println("-pulse long IR signal");
    if (IRcompare(numberpulses, ApplePlaySignal)) {
       Serial.println("PLAY");
    }
    if (IRcompare(numberpulses, AppleRewindSignal)) {
       Serial.println("REWIND");
    }
    if (IRcompare(numberpulses, AppleForwardSignal)) {
       Serial.println("FORWARD");
    }
}

Nous vérifions les données réçues par rapport aux codes infrarouges que nous connaissons déjà et affichons un message avec ce que nous avons détecté.

Voila, une fois nos tests réussis, il ne reste plus qu'a prendre ce code pour en faire quelque-chose de plus utile (en fonction du bouton pressé).

{{{2}}}
Crédit: AdaFruit Industries www.adafruit.com


Source: IR Sensor

Crée par LadyAda pour AdaFruit Industries.

Traduit par Meurisse D. pour MCHobby

Traduit avec l'autorisation d'AdaFruit Industries - Translated with the permission from Adafruit Industries - www.adafruit.com

Toute référence, mention ou extrait de cette traduction doit être explicitement accompagné du texte suivant : «  Traduction par MCHobby (www.MCHobby.be) - Vente de kit et composants » avec un lien vers la source (donc cette page) et ce quelque soit le média utilisé.

L'utilisation commercial de la traduction (texte) et/ou réalisation, même partielle, pourrait être soumis à redevance. Dans tous les cas de figures, vous devez également obtenir l'accord du(des) détenteur initial des droits. Celui de MC Hobby s'arrêtant au travail de traduction proprement dit.