Acquisition d'un signal de recepteur PPM

Bonjour,

J'ai un petit projet qui consiste a capturer des entrées d'un récepteur de télécommande en PPM.

J'ai réussi a compter le signal sur une voie, du récepteur, mais j'aimerais le faire pour deux voies ??

Comment dois je implémenter le code pour changer de voie ??

puis je utiliser la même interruptions, sur l'entrée 3 ?

je travail sur un Arduino "Duemilanove", et j'utilise un Timer, avec "attachinterrpt" sur change.

Voici mon code:

Merci pour votre aide .

// **********************************************
// *   LLA Capture d'un entrée de recepteur en microsecondes   *   
//***********************************************

float CH1=0;

void setup()
{
 Serial.begin(115200);
   attachInterrupt(0,Comptage1,CHANGE);  // 0 pour la Pin2

   pinMode(2,INPUT);
   pinMode(3,INPUT);

 // Parameters for timer1
 TCCR1A=B00000000; // Normal mode
 TCCR1B=B00000010; // 16 MHz (prescale a 8 soit 0.5 microsecondes)
 TIMSK1=B00100001; // Activate CAPTUREPIN
 interrupts();             // enable all interrupts
}


void loop()
{
     Serial.print("CH1=");Serial.print(CH1);
     Serial.println();
     delay(200);
}


void Comptage1()
{
    CH1=TCNT1/2;
     TCNT1=0;
}

1) tu a posté deux fois la même chose : supprime vite l'autre post avant que quelqu'un réponde dessus. 2) tu n'as visiblement pas lu : Faire un Nouveau Sujet avec les Balises Met ton code entre balises et lis aussi le message précédent : Bienvenue sur........

puis je utiliser la même interruptions, sur l'entrée 3 ?

Qu'est ce que tu appelle "la même interruption" , Les interruptions int0 et int1 sont sur des pins,elles se gèrent de la même façon.

Je vois que tu n'hésites pas à manipuler les registres, tu pourrais t'intéresser à la macro "ISR" de l'avr-libC . En fait attachinterrupt() le fais pour toi mais c'est souvent plus profitable de virer la cosmétique et d'aller aux fondamentaux.

PS : toutes les I/O peuvent générer des interruptions, seuls int0 et int1 sont associées à une pin précise, les autres interruptions (PCINTx) sont associées à des PORTs, c'est moins direct à gérer mais cela se fait.

Bonsoir,

Tout d'abord merci pour cette réponse.

En ce qui concerne l'autre Post , je crois que je l'ai posté sur le forum anglais ??*

Je ne trouve pas comment le supprimer .

Je suis débutant en ARDUINO, en fait je voudrais capturer 4 entrées de mon recepteur, et donc je voulais utiliser attachinterrupt0 et 1 sur les pin2 et 3,mais je ne savais comment gérer les deux interruptions en fonction des deux pin ??

Mais si il y a une solution pour générer une interruption sur 4 entrées, je suis preneur .

Merci

lla_net

Mais si il y a une solution pour générer une interruption sur 4 entrées, je suis preneur .

C'est pas bien loin : sous forum Tutoriaux Interruptions ATMega 328p

Bonjour,

Pouvez vous supprimer mon premier Post, je l'ai renommer "post a supprimer" Car apparemment la suppression m'est impossible.

Merci.

lla_net

Utilise "Report to moderator" (en bas du message à gauche)et explique bien quel post tu veux suprimer.

Sinon si personne n'a répondu tu peut supprimer un post : En bas (à droite) du post que tu as écrit tu trouve : Quote Quick edit et More Tu met la souris sur more et tu trouvera un sous menu Modify et Remove

Bonsoir,

J'ai modifie mon code pour utiliser les PCINT0 et les interruptions "PCINT0_vect" correspondantes pour capturer 4 voies de mon recepteur sur 4 entrées de mon Arduino.

Mais ça ne fonctionne pas

Pouvez vous m'aider ???

A+

LLa_net

// *************************************************************
// *   LLA Capture de 4 entrée de recepteur en microsecondes   *   
//**************************************************************

float CH1=0;
float CH2=0;
float CH3=0;
float CH4=0;

void setup()
{
  noInterrupts(); // desactive les interruptions
  Serial.begin(115200);

   
    pinMode(8,INPUT);//CH1
    pinMode(9,INPUT);//CH2
    pinMode(10,INPUT);//CH3
    pinMode(11,INPUT);//CH4

  // Parametres du  timer1
  
  TCCR1A=B00000000;   // Normal mode
  TCCR1B=B00000010;   // 16 MHz (prescale a 8 soit 0.5 microsecondes)
  TIMSK1=B00000001;   // Active l'interruption timer1  
    
  // parametres des interruptions
  
  PCMSK0=B00001111; // utilisation de 4 entrées Pin 8 9 10 & 11
  PCMSK1=0; 
  PCMSK2=0;
    EICRA=B00000101;  //Active l'interruption sur change
   
    
  interrupts();             // Activation des interruptions
}


void loop()
{ 
  TCNT1=0; //remise a zero du compteur Timer1 
  
  
       Serial.print("CH1=");Serial.print(CH1);Serial.print("   :   ");

       Serial.print("CH2=");Serial.print(CH2);Serial.print("   :   ");

       Serial.print("CH3=");Serial.print(CH3);Serial.print("   :   ");

       Serial.print("CH4=");Serial.print(CH4);Serial.print("   :   ");
      
       Serial.println();
      
         delay(100);
}


ISR (PCINT0_vect)//interuption sur l'entree 1
{

     CH1=TCNT1/2;
}

ISR (PCINT1_vect)//interuption sur l'entree 2
{

     CH2=TCNT1/2;
}
ISR (PCINT2_vect)//interuption sur l'entree 3
{

     CH3=TCNT1/2;
}
ISR (PCINT3_Vect)//interuption sur l'entree 4
{
  
     CH4=TCNT1/2;
}

Désolé mais j'ai écrit ce document il y a bien longtemps maintenant et il faudrait que je m'y replonge sérieusement ce pourquoi je n'éprouve aucune envie.

Néanmoins un rapide coupe d'oeil à ton code me laisse penser que quelque chose t'as échappé : 1) les int0 et int1 sont rivés sur des pins bien précises. 2) les PCINTx sont sur des ports. [u]Un PORT c'est un groupe de 1 à 8 I/O[/u]. Il faut que tu détermine laquelle des 1 à 8 I/O a générée l’interruption.

Tu pourra constater que dans mon document j'utilise le PORTC et que je teste laquelle des entrées a changé d'état. Il n'est pas utile d'utiliser plusieurs PCINTx et plusieurs PORTs. Il suffit de choisir dans ton cas 4 I/O appartenant à un même port et une seule interruption PCINTx. Avec une UNO --->micro-controleur AtMega328p , il y a 3 PORTs : le B, le C, le D.

La correspondance entre les dénominations Atmel (les seules valables quand tu consultes la datasheet) et celle de Wiring/arduino est disponible dans mon document.

PS : j'espère que tu ne te contente pas de mon document et que tu as téléchargé la datasheet du micro que tu utilise !

Salut,

Merci pour ta réponse. :)

J'ai modifié mon code, j'utilise une seule fois "ISR (PCINT0_vect)"

ISR (PCINT0_vect)//interuption sur l'une des entrées
{
 // recherche du changement d'état
    
      CH1=TCNT1/2;
}

J'ai configuré l'interruption sur changement d'état

Donc l'interruption est exécuté lors d'un changement d'état sur une des Pin prévue, mais quand retourne t'on dans le programme principal,quand il y a un nouveau changement d'état ??

La j'ai l'impression que je reste prisonnier dans mon "sub routine interruption".

Comment test on le changement de valeur de la PIN en question avec !

Le Timer est il toujours en fonction ou faut il le déclenché , avec un TIMR0ON ??

Merci pour ton aide . :)

LLA_NET

Comment test on le changement de valeur de la PIN en question avec !

Quand une interruption PCINTx se produit c'est qu'il y a un changement d'état (attention on a moins de choix qu'avec les deux int0 et int1). Dans le corps de la macro ISR tu testes juste quelle pin a changé d'état et tu place un drapeau pour indiquer la pin en question : c'est tout tu sort de l'interruption et tu retournes automatiquement dans loop à l'endroit où tu étais avant le déclenchement de l'interruption. Le drapeau ce peut être un entier auquel tu donnes la valeur 1,2,3,4 suivant la pin détectée. Attention les variables manipulées par les interruptions doivent être déclarée "volatile". exemple : volatile uint8_t drapeau ;

C'est dans la boucle infinie loop que tu gère ce que tu as à faire en fonction de l'état du drapeau.

Comment test on le changement de valeur de la PIN en question avec !

Dans mon document tu as une fonction test_boutonPortC() adaptée à tes besoins. Elle est volontairement générique. Note que j'utilisais un bouton poussoir connecté au 0V. Au repos j'avais un 5 volts et je cherchais donc à détecter un 0V.

Il faut bien dissocier les niveaux électriques 0 volt et 5 volts des valeurs logiques. Le terme logique négative vient de là . Le repos est considéré comme un 0 Logique mais compte tenu du câblage on obtient 5V. L'actif est considéré comme un 1 Logique mais compte tenu du câblage on obtient 0V.

Le résultat du if doit être "VRAI" pour la pin détectée et "FAUX" pour les autres. Comme le micro de l'arduino ne connais que la logique classique : 5V en entrée = 1 Logique, il faut faire attention dans l'équation de détection a bien inverser là ou il faut.

Sinon si ta tête explose tu peux aussi mettre le bouton entre l'alim 5V et l'entrée de la pin et ajouter une résistance de 10 k entre l'entrée de la pin et la masse. Comme cela au repos tu aura un 0 volt et en phase active tu aura 5 volts.

Merci

Pour ces précisions, je vais essayer de les mettre en pratique

A+

LLA_net

Bonsoir,

Après avoir réfléchi, il semble que l’utilisation du PCINT0 soit vraiment adapté a mon problème,
mais j’ai un peu de mal a le mettre en œuvre ??

Voici mon code, qui fonctionne pour la voie 1, mais par pour les autres voies

Merci pour votre aide, car la je sèche un peu ??? :confused:

// *************************************************************
// *   LLA Capture de 4 entrée de recepteur en microsecondes   *   
//**************************************************************

float CH1=0;  // valeur en Microsecondes du canal 1
float CH2=0;  // valeur en Microsecondes du canal 2
float CH3=0;  // valeur en Microsecondes du canal 3
float CH4=0;  // valeur en Microsecondes du canal 4
int CH=0;     // Numéro de la voie concernée

void setup()
{
  noInterrupts(); // desactive les interruptions
  Serial.begin(115200);

    pinMode(8,INPUT);//CH1
    pinMode(9,INPUT);//CH2
    pinMode(10,INPUT);//CH3
    pinMode(11,INPUT);//CH4

  // Parametres du  timer1
  
  TCCR1A=B00000000;   // Normal mode
  TCCR1B=B00000010;   // 16 MHz (prescale a 8 soit 0.5 microsecondes)
  TIMSK1=B00100001;    // Active l'interruption timer1  + capture pin
    
  // parametres des interruptions
  
     PCICR=B00000001; // PCIE0 =1
      PCMSK0=B00001111; // utilisation de 4 entrées Pin 8 9 10 & 11
    
  interrupts();             // Activation des interruptions
}


void loop()
{ 
  
      PORTB |=(1<<PORTB0);   // active le Pull-Up

     
        Serial.print("CH1=");Serial.print(CH1); Serial.print("  :  ");Serial.print("CH2=");Serial.print(CH2);
        Serial.println();
         delay(100);
}



ISR (PCINT0_vect)  // interruption sur changement d'état 
{
  
  
// l'interrruption a eu lieu sur la PIN8=PB0
    if(( (PINB & (1 << PINB0)) == 1)and (CH=0)) 
     { TCNT1= 0;CH=1;}
    else 
     {
      CH1=TCNT1/2;
      TCNT1=0;
      CH=0;
     }
    
// l'interrruption a eu lieu sur la PIN9=PB1
    if(( (PINB & (1 << PINB1)) == 1)and (CH=0)) 
     { TCNT1= 0;CH=2;}
    else 
     {
      CH2=TCNT1/2;
      TCNT1=0;
      CH=0;
     }
    
} // fin de ISR

Bonjour,

J’ai modifié mon code pour les 4 voies, en faisant comme ci dessous,
Je mes suis inspiré du document précité, et en fait il ne parcours qu’une seule fois l’interruption 2,
et affiche CH=2

Merci :confused:

void loop()
      {  
        
        if (CH==1)
        {Serial.print("CH=1");
          Serial.println();}
     
        if (CH==2)
        {Serial.print("CH=2");
          Serial.println();}

        if (CH==3)
        {Serial.print("CH=3");
          Serial.println();}

        if (CH==4)
        {Serial.print("CH=4");
          Serial.println();}
         
         delay(100);
         }

        

ISR (PCINT0_vect)  // interruption sur changement d'état 
{
// l'interrruption a eu lieu sur la PIN8=PB0
    if(((1<<PB0) & PINB) == (1<<PB0)) // front montant sur PB0
      { TCNT1= 0;CH=1;}

// l'interrruption a eu lieu sur la PIN9=PB1
    if(((1<<PB1) & PINB) == (1<<PB1)) // front montant sur PB1
      { TCNT1= 0;CH=2;}

// l'interrruption a eu lieu sur la PIN10=PB2
    if(((1<<PB2) & PINB) == (1<<PB2)) // front montant sur PB2
      { TCNT1= 0;CH=3;}

// l'interrruption a eu lieu sur la PIN11=PB3
    if(((1<<PB3) & PINB) == (1<<PB3)) // front montant sur PB1
      { TCNT1= 0;CH=4;}
  
    
} // fin de ISR