Outils pour utilisateurs

Outils du site


Action disabled: edit
tdethindus4distanciel

TD Bus de communication : Communication infrarouge NEC étendue

bvdp.inetdoc.net_files_iut_tp_pic_warning.jpeg

Vos réponses à toutes les questions devront être remises pour évaluation à l'enseignant lors de la prochaine séance de TP et participeront à votre note.

Cours

Visionner le cours sur la partie Infrarouge jusqu'à la minute 11:

Format des trames

Le format de trame présenté dans le cours est le format NEC. Dans ce TD, nous considérons le format NEC étendu, qui est très légèrement différent: une trame NEC étendue est constituée d'un train de bits modulé à 38Khz. Il existe 2 types de trames:

  1. les trames complètes
  2. les trames de répétition

La trame complète contient:

  1. un entête de trame
  2. une adresse sur 16 bits (codant le numéro de la télécommande), octet de poids fort d'abord et bit de poids faible d'abord
  3. une valeur sur 8 bits (codant le numéro de la touche), bit de poids faible d'abord
  4. une valeur sur 8 bits codant le complément à 1 de la précédente valeur sur 8 bits (redondance pour la détection d'erreur)
  5. l'envoi d'un bit à 1 et un retour à l'état de repos

La trame de répétition contient:

  1. un entête de trame
  2. l'envoi d'un bit à 1 et un retour à l'état de repos

La durée séparant le début de 2 trames (complète ou de répétition) doit être au moins de 110ms.

Codage des bits

Les bits sont représentés de la manière suivante:

  1. Le bit “1” est représenté par un train d'impulsion à 38Khz (avec rapport cyclique 50%) pendant 560us suivi par une inactivité. La durée totale du bit est de 2.25ms.
  2. Le bit “0” est représenté par un train d'impulsion à 38Khz (avec rapport cyclique 50%) pendant 560us suivi par une inactivité. La durée totale du bit est de 1.12ms.

Les entêtes de trames sont codés de la manière suivante:

  1. La trame complète commence par un train d'impulsion à 38Khz (avec rapport cyclique 50%) pendant 9ms suivi par une inactivité de durée 4.5ms.
  2. La trame de répétition commence par un train d'impulsion à 38Khz (avec rapport cyclique 50%) pendant 9ms suivi par une inactivité de durée 2.25ms.

1. Dessin des chronogrammes

Question 1.1

Dessiner l'allure (dessiner l'enveloppe du signal lorsqu'il est longtemps à l'état haut ou bas et tracer en hachuré lorsque le signal est à 38Khz) des chronogrammes pour l'envoi d'une trame complète depuis la télécommande d'adresse 0x1234 pour la touche de commande 0x56 en faisant apparaître la valeur des différents bits transmis et la correspondance avec les données à transmettre (adresse bits de A15 à A0, commande bits de B7 à B0).

Question 1.2

Dessiner l'allure des chronogrammes pour l'envoi d'une trame de répétition depuis la télécommande 0x1234 pour la touche 0x56 (attention au piège!).

Question 1.3

Déterminer la durée nécessaire pour l’émission des trames des question 1.1 et 1.2.

Question 1.4

Déterminer la durée nécessaire minimum et maximum pour l’émission d'une trame complète (en indiquant les valeurs des bits correspondants). En déduire le débit maximum en octets par secondes (en considérant que les données utiles sont codées par le code commande, alors que le code d'adresse indique juste l’émetteur de la donnée.

2. Programmation pour l’émission

Dans la suite, nous considérons que le TIMER 2 du microcontroleur ATMEGA328P de l'Arduino est utilisé pour la génération du signal modulé à 38Khz.

Deux fonctions sont fournies pour activer (Mark) ou désactiver (Space) le signal carré de fréquence 38Khz sur la broche pilotant la LED infrarouge:

ir1.ino
//////////////////////////////////////////////////////////////////////// 
void mark(int time) // pulse parameters in usec
{
  // Sends an IR mark for the specified number of microseconds.
  // The mark output is modulated at the PWM frequency.
  TCCR2A |= _BV(COM2B1); // Enable pin 3 PWM output
  if (time > 0) delayMicroseconds(time);
}
////////////////////////////////////////////////////////////////////////
void space(int time) // pulse parameters in usec
{
  // Sends an IR space for the specified number of microseconds.
  // A space is no output, so the PWM output is disabled.
  TCCR2A &= ~(_BV(COM2B1)); // Disable pin 3 PWM output
  if (time > 0) delayMicroseconds(time);
}
////////////////////////////////////////////////////////////////////////

Question 2.1

Proposer (en utilisant les fonctions fournies) l'algorithme pour la fonction void sendNECBYTE(unsigned char data) qui permet d'envoyer, bit de poids faible d'abord, les 8 bits de data.

Question 2.2

Proposer l'algorithme pour la fonction void sendNECFrame(unsigned int adr, unsigned char cmd) qui permet d'envoyer la trame NEC complète, adr étant le numéro de télécommande et cmd le numéro de la touche. Vous pourrez bien sûr faire appel à la fonction sendNECBYTE(…)

Question 2.3

Proposer l'algorithme pour la fonction void sendNECFrameRepeat() qui permet d'envoyer la trame NEC de répétition.

3. Démodulation pour la réception

Nous considérons le composant récepteur VISHAY TSOP2238 - RECEPTEUR IR 38KHZ , ref farnell 4913073

Lire la documentation, pages 1 et 3 du datasheet: http://www.farnell.com/datasheets/30485.pdf

Question 3.1

Traduire en francais le chapitre “Description”

Question 3.2

Analyser le “Block Diagram” et faire une recherche pour expliquer le rôle des différents blocs (AGC est l'acronyme de Automatic Gain Control)

Question 3.3

Expliquer pourquoi le composant existe en différentes référence de TSOP2230 à TSOP2256, et pourquoi nous considérons le TSOP2238

Question 3.4

Par rapport au signal que vous avez tracé dans l'exercice 1, expliquer comment est le signal en sortie de ce composant (notamment la polarité).

Question 3.5

Proposer un schéma de raccordement de ce composant à l'Arduino.

4. Programmation pour la réception

Le programme ci dessous permet la réception des trames NEC étendues sur l'Arduino UNO R3:

testrecep2.ino
//B.Vandeportaele 2018
 
#define PIN_RX_IR  8 
////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////// Function to print in hexadecimal with a known number of digits
void printHex(int num, int precision) {
     char tmp[16];
     char format[128];
     sprintf(format, "%%.%dX", precision);
     sprintf(tmp, format, num);
     Serial.print(tmp);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
inline bool DetecteBas()
{
  return  (digitalRead(PIN_RX_IR) == 0);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
inline bool DetecteHaut()
{
  return (digitalRead(PIN_RX_IR) != 0);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup()
{
  pinMode(PIN_RX_IR, INPUT);
  digitalWrite(PIN_RX_IR, LOW);
  Serial.begin(9600);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int temps = 0;
unsigned int temps2 = 0;
unsigned int deltat = 0;
unsigned char etat = 0;  
unsigned char cptbit = 0;
unsigned char bytes[4];
////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop()
{
  switch (etat)
  {
    case 0:
      if (DetecteBas())
      {
        temps = micros();
        etat = 1; 
      }
      break;
    case 1:
      if (DetecteHaut())
      {
        temps2 = micros();  
        deltat = temps2 - temps; 
        temps = temps2;
        if ( (deltat > 8000) && (deltat < 9000))
        {
          etat = 2;
        }
        else
          etat = 0;
      }
      break;
    case 2:
      if (DetecteBas())
      {
        temps2 = micros();  
        deltat = temps2 - temps; 
        temps = temps2;
        if ( (deltat > 4000) && (deltat < 5000))
        {
          etat = 3; 
          cptbit = 0;
          bytes[0] = 0;
          bytes[1] = 0;
          bytes[2] = 0;
          bytes[3] = 0;
        }
        else   if ( (deltat > 2000) && (deltat < 2500))
        {
          etat = 0; 
          Serial.print("+");
        }
        break;
      case 3:
        if (DetecteHaut())
        {
          temps2 = micros();  
          deltat = temps2 - temps; 
          temps = temps2;
          if (cptbit < 32)
            etat = 4;
          else
          {
            etat = 0;
            if (bytes[2] == ~bytes[3])
            {
              Serial.print("=");
              printHex(bytes[0],2); 
              Serial.print(" ");
              printHex(bytes[1],2);  
              Serial.print(" ");
              printHex(bytes[2],2);  
              Serial.print(" ");
            }
          }
        }
        break;
      case 4:
        if (DetecteBas() )
        {
          temps2 = micros();  
          deltat = temps2 - temps; 
          temps = temps2;
          if (deltat > 800)
            bytes[cptbit >> 3] |= (1 << (cptbit & 7));
          etat = 3;
          cptbit++;
        }
        break;
      }
  }
}

Question 4.1

Déterminer la brôche de l'arduino connectée au composant TSOP22..

Question 4.2

Lire la documentation de la fonction micros() de l'Arduino et déterminer dans le programme fourni comment est réalisée la mesure de la durée entre deux fronts

Question 4.3

Indiquer quelle ligne du programme permet de faire le contrôle d'erreur

Question 4.4

Dessiner la machine à états réalisée par ce programme

tdethindus4distanciel.txt · Dernière modification : 2021/03/18 17:48 de bvandepo