Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Arduino] Calcul du temps qu'un Bp est appuyé

Gestion du timer1 chaotique

Sujet résolu
    15 juin 2017 à 16:55:00

    Bonjour a tous/toutes 

    J'essaie depuis quelque temps de savoir pendant combien de temps un bouton poussoir a était actionné. De ce fait je cherche a calculé la différence de temps entre l'appui et le relâchement a l'aide du Timer 1 de l'arduino. Je me suis aidé de ce cours pour réaliser cette fonction:  

    http://www.locoduino.org/spip.php?article198

    On parle bien dedans de comment réaliser cette fonction, mais je n'arrive pas a la mettre en oeuvre.

    Je vous transmets mon code. 

    // On fait fonctionner le timer1 en mode normal, de 0 a 65535
    // avec un prediviseur regle sur 8. La durée du cycle est de 0.032s
    // Chaque debordement crée une action sur la LED qui s allume et s eteint
    // toutes les 0.032secondes.
    // Chaque debordement augmente egalement numeroCycle d une unite.
    // Une capture sur l'entree 8 (detection front )affiche le nombre d'overflow, la dureeTotale entre le debut du programme et l evenement,
    // et la date de l evenement calculee avec la valeur du registre ICR1.
    //-------------------------------------------------------------------------------
    
    #define ledPin 12
    #define poussoirPin 8
    unsigned long duree = 0;
    float event = 0;
    int nombre = 0;
    
    void setup() {
    
      pinMode (poussoirPin, INPUT_PULLUP);
      Serial.begin(115200);
      noInterrupts();
      TCCR1A = 0;
      TCCR1B = 0b00000010; // prediviseur 8  table 16-5 doc atmegaICES1 front descendant =06emebit 7eme bit noise cancel
      TIMSK1 = 0b00100001; // autorisation interruption TOV et Input Capture
      TCNT1 = 0;
      ICR1 = 0;
      interrupts();
    }
    
    ISR(TIMER1_OVF_vect)
    {
      digitalWrite (ledPin, !digitalRead (ledPin)); // A chaque overflow, action sur LED qui change d'état
      nombre++;
    }
    
    ISR(TIMER1_CAPT_vect) {
      //acquisition pas fiable car rebonds de contacts sur le BP -> condo a prévoir
      TCCR1B = 0b00000010;            //détection sur front descendant (bp appuyé)
      duree = millis();
      event = nombre * 32.7675 + ICR1 * 0.0000005;
      Serial.println(nombre);
      Serial.println(duree);
      Serial.println(event);
      TCCR1B = 0b01000010;       //détection sur front montant (relachement du BP)
    event = nombre * 32.7675 + ICR1 * 0.0000005;
      Serial.println(nombre);
      Serial.println(duree);
      Serial.println(event);
     
    }
    
    void loop() {
    
    }

    J'ai un problème au niveau de comment faire comprendre au programme que je veux faire une aquisition sur front descendant puis sur front montant. Pour l'instant c'est assez aléatoire. Le programme ce bloque généralement en détection de front montant, je n'arrive pas a le faire revenir sur front descendant par la suite :(

    Voilà ce que j'obtient sur le moniteur série, les 2 premières acquisitions fonctionnent, mais les suivantes correspondent plus que a des front montants. Merci de votre aide je sèche pas mal sur ce coup là :colere2:

    -
    Edité par Jr.Soraka 15 juin 2017 à 17:00:01

    • Partager sur Facebook
    • Partager sur Twitter
      15 juin 2017 à 17:18:13

      Est-ce franchement utile de monopoliser un timer hardware pour calculer un temps d'appuis ???

      Tu pourrais tout simplement faire ça avec la fonction millis() :

      • Quand tu appuis, tu sauvegardes la valeur de millis dans une variable
      • Quand tu relâches, tu fais la soustraction de la valeur de millis avec ta valeur sauvegardée
      • Partager sur Facebook
      • Partager sur Twitter
        15 juin 2017 à 17:55:27

        Salut lorrio, merci pour ta réponse rapide. Je veux bien essayer ta solution. J'ai juste besoin d'une petite précision, j'utilise quelle fonction pour détecter l'appui puis le relâchement ? J'ai tenté avec deux conditions if mais cela n'a rien donné.
        • Partager sur Facebook
        • Partager sur Twitter
          15 juin 2017 à 20:34:58

          Salut,

          Un front est une simple comparaison entre un état actuel et son état précédent :

          if(bt && !memo) //RE
            timeOn = millis();
          else if (!bt && memo) //FE
            timeElapsed = millis()-timeOn;
          
          memo = bt;

          Bonne continuation.

          • Partager sur Facebook
          • Partager sur Twitter

          Bonhomme !! | Jeu de plateforme : Prototype.

            15 juin 2017 à 20:57:56

            2 méthodes possible :

            Soit tu mets le bouton sur INT0 ou INT1 et tu utilises l'interruption.

            Soit tu scan périodiquement ton bouton dans le loop et tu détecte les changements d'état.

            • Partager sur Facebook
            • Partager sur Twitter
              15 juin 2017 à 21:24:25

              Ok merci je test ça demain. Le but de tout cela est de voir si l'on peut automatiser un fonctionnement avec arduino.
              • Partager sur Facebook
              • Partager sur Twitter
                16 juin 2017 à 15:32:16

                Bonjour a tous , 

                Donc après quelque tests, les solutions proposées ne conviennent pas a mon besoin :honte:

                Je souhaite pouvoir faire l’acquisition de mon temps d'appuie a n'importe quel moment du programme d'ou mon idée d’utiliser une Interruption via le Timer1.

                Je n'ai pas beaucoup progresser depuis hier. Je n'arrive pas a faire "comprendre" au programme que je souhaite qu'il détecte un front descendant puis un front montant. Jusqu’à là, je n'arrive que a avoir l'un ou l'autre. Cela vient probablement du fait que je place mal la demande de changement de détection de front. Si vous pouvez m'orientez comment écrite ce bazar cela serait super. Mon code actuellement :

                #define poussoirPin 8
                unsigned long duree = 0;
                float event = 0;
                int nombre = 0;
                
                void setup() {
                
                  pinMode (poussoirPin, INPUT_PULLUP);
                  Serial.begin(115200);
                  noInterrupts();
                  TCCR1A = 0;
                  TCCR1B = 0b00000010; // prediviseur 8  table 16-5 doc atmegaICES1 front descendant =06emebit 7eme bit noise cancel
                  TIMSK1 = 0b00100001; // autorisation interruption TOV et Input Capture
                  TCNT1 = 0;
                  ICR1 = 0;
                  interrupts();
                }
                
                
                ISR(TIMER1_CAPT_vect) {
                  TCCR1B = 0b00000010;   //front descendant
                  Serial.println("Appuye");
                  /*duree = millis();
                  event = nombre * 32.7675 + ICR1 * 0.0000005;
                  Serial.println(nombre);
                  Serial.println(duree);
                  Serial.println(event);*/
                  TIFR1 = 0b00100000;            //reset du flag          C'est cette partie la qui me pose problème, je ne sais pas comment
                  TCCR1B = 0b01000010;          //front montant           gérer correctement le changement de détection avec le Timer
                  Serial.println("Relache");
                 }
                
                void loop() {
                
                }



                • Partager sur Facebook
                • Partager sur Twitter
                  17 juin 2017 à 22:15:11

                  Alors déjà, mettre un appel à Serial.println dans une interruption, c'est une très mauvaise idée.

                  Une interruption doit s'exécuter le plus rapidement possible donc mieux vaut éviter de faire des Serial.print qui prennent énormément de temps.

                  De plus, sur les dernières versions, il me semble que le driver du Serial est sous interruption donc interdiction de l'utiliser dans une interruption.

                  Mais sinon, comme je te le disais : pourquoi ne pas utiliser millis et INT0 ???

                  Exemple de code :

                  const byte btnPin = 2;		// Bouton sur pin 2...
                  const byte btnIrq = 0;		// Bouton sur pin 2, soit INT0 sur arduino UNO.
                  
                  unsigned long tFall = 0;	// Valeur de millis() lors du front descendant
                  unsigned long tRise = 0;	// Valeur de millis() lors du front montant
                  
                  
                  void onFall(void);
                  void onRise(void);
                  void setup(void);
                  void loop(void);
                  
                  void onFall() {										// Interruption lors d'un front descendant
                  	tFall = millis();								// On sauvegarde la valeur de millis dans tFall
                  	attachInterrupt(btnIrq, onRise, RISING);		// Puis on passe la détection d'interruption sur front montant
                  }
                  
                  void onRise() {										// Interruption lors d'un front montant
                  	tRise = millis();								// On sauvegarde la valeur de millis dans tRise
                  	attachInterrupt(btnIrq, onFall, FALLING);		// Puis on passe la détection d'interruption sur front descendant
                  }
                  
                  void setup(void) {									// Setup:
                  	attachInterrupt(btnIrq, onFall, FALLING);		// Détection d'interruption sur front descendant au départ
                  	Serial.begin(115200);							// Serial à 11500 bauds
                  }
                  
                  void loop(void) {									// Loop:
                  	if ( ( tRise != 0 ) && ( tFall != 0 ) ) {		// Si les 2 fronts ont été détectés, alors on affiche tout
                  		Serial.print("tRise=");
                  		Serial.println(tRise);
                  		Serial.print("tFall=");
                  		Serial.println(tFall);
                  		Serial.print("tDiff=");
                  		Serial.println(tFall-tRise);
                  	}
                  }



                  • Partager sur Facebook
                  • Partager sur Twitter
                    19 juin 2017 à 14:51:08

                    Merci Lorrio ton aide m'a bien débloqué. Par contre il y a un truc que je comprends pas, cela marche a l'envers. Le timer compte le temps ou le Bp n'est pas appuyé au lieu du temps ou il est appuyé o_O . Je me suis dis que cela venait peut etre du fait que j'avais une front montant lors de l'appui sur le Bp mais non cela ne change rien. Une idée de là où ça coince ? Je continue de mon côté .

                    • Partager sur Facebook
                    • Partager sur Twitter
                      19 juin 2017 à 15:41:22

                      Tout dépend de comment tu câble ton bouton.

                      Théoriquement, un bouton devrait être câblé de façon à donner :

                      - LOW quand il est enfoncé (avec GND commuté par le bouton), donc front descendant à l'appuie

                      - HIGH quand il est relaché (avec une résistance de pull-up), donc front montant au relachement

                      Mais si tu l'as câblé dans l'autre sens (commutation du 5V et résistance de pulldown), alors les fronts sont inversés et il te faut changer le code.

                      Il y a aussi une petite erreur dans mon code : tFall-tRise qu'il faudrait changer en tRise-tFall

                      • Partager sur Facebook
                      • Partager sur Twitter
                        19 juin 2017 à 16:29:21

                        Mon bp est effectivement câblé dans l'autre sens, j'ai bien un font montant quand j'appuie. Dans le coup j'ai modifié le code 
                        const byte btnPin = 2;        // Bouton sur pin 2...
                        const byte btnIrq = 0;       // Bouton sur pin 2, soit INT0 sur arduino UNO.
                        unsigned long tFall = 0;     // Valeur de millis() lors du front descendant
                        unsigned long tRise = 0;    // Valeur de millis() lors du front montant
                        
                        void onRise(void);
                        void onFall(void);
                        void setup(void);
                        void loop(void);
                        
                        void onRise() {                                     // Interruption lors d'un front montant
                          tRise = millis();                                // On sauvegarde la valeur de millis dans tRise
                          attachInterrupt(btnIrq, onFall, FALLING);       // Puis on passe la détection d'interruption sur front descendant
                        
                        }
                        void onFall() {                                     // Interruption lors d'un front descendant
                          tFall = millis();                                // On sauvegarde la valeur de millis dans tFall
                          attachInterrupt(btnIrq, onRise, RISING);        // Puis on passe la détection d'interruption sur front montant
                        }
                        
                        void setup(void) {                                  // Setup:
                          attachInterrupt(btnIrq, onRise, RISING);        // Détection d'interruption sur front montant au départ
                          Serial.begin(115200);                           // Serial à 11500 bauds
                        }
                        void loop(void) {
                        
                          if ( ( tFall != 0 ) && ( tRise != 0 ) ) {
                            Serial.print("tRise=");
                            Serial.println(tRise);
                            Serial.print("tFall=");
                            Serial.println(tFall);                   // Si les 2 fronts ont été détectés, alors on affiche tout
                        
                            Serial.print("tDiff=");
                            Serial.println(tFall - tRise);
                            tRise = 0;
                            tFall = 0;
                          }
                        }

                        Mais j'ai toujours le même problème. Je compte le temps de relâchement du BP. Vraiment étrange.  Je vais tester en détectant seulement un changement d'état sur la broche 2, sans me préoccuper de son niveau précédent. On verra bien ce que cela donne :)


                        • Partager sur Facebook
                        • Partager sur Twitter
                          19 juin 2017 à 16:52:03

                          C'est effectivement assez étrange...

                          Tu n'aurais pas des rebonds sur ton bouton par hasard ?

                          • Partager sur Facebook
                          • Partager sur Twitter
                            19 juin 2017 à 17:11:59

                            C'est ce que je pensais au début, j'ai ajouté un condo de 220nF et cela ne change rien. Mon montage des fois que j'ai commis une erreur .

                            • Partager sur Facebook
                            • Partager sur Twitter
                              19 juin 2017 à 18:05:28

                              Le montage que tu nous présente est un montage classique avec court-circuit du GND quand le bouton est enfoncé.

                              Du coup, quand tu appuies sur ton bouton, tu vas avoir un front descendant qui donnera l'état LOW.

                              Et quand tu relâches, c'est R1 qui va polariser l'état HIGH et donc faire un front montant.

                              • Partager sur Facebook
                              • Partager sur Twitter
                                19 juin 2017 à 18:13:10

                                • Les entrées de l'arduino intègrent un pullup, suffit de le demander  pinMode(pin, INPUT_PULLUP);
                                • rebonds : ça doit pouvoir aussi se traiter par logiciel / timer : considérer que le bouton est à 1 si il n'est pas passé à l'état 0 pendant n millisecondes, et inversement. (c'est quoi une valeur raisonnable pour un rebond ?)

                                l'état "1?" représente la situation "ah, ça fait un moment que je ne suis pas revenu à 0, serai-je en train de passer à l'état 1 ?"

                                Quand le moment commence à être long, timeout, on dit que oui, et on considère qu'on est passé à 1.

                                 Si on a conservé le temps (millis())auquel on est rentré dans (0), et celui où on est rentré dans (1?), ça donne la durée pendant laquelle on considère que le bouton était relâché.

                                -
                                Edité par michelbillaud 19 juin 2017 à 18:20:17

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  20 juin 2017 à 9:08:16

                                  Salut, encore une fois merci de votre aide :D

                                  Donc suite de mon combat avec mon arduino : 

                                  J'ai réussi a faire en sorte que cela fonctionne mais ( bah oui forcement ), j'ai remarqué que lors d'appui trop rapides le programme "ce perd". En effet tFall deviens plus petit que tRise, et donc j'obtiens une valeur qui ne me conviens pas. 

                                  Le programme dans sa version qui fonctionne mais il ne faut pas appuyer trop vite ( Merci lorrio ! ).

                                  const byte btnPin = 2;        // Bouton sur pin 2...
                                  const byte btnIrq = 0;       // Bouton sur pin 2, soit INT0 sur arduino UNO.
                                  unsigned long tFall = 0;     // Valeur de millis() lors du front descendant
                                  unsigned long tRise = 0;    // Valeur de millis() lors du front montant
                                  unsigned long tDiff =0;     //Valeur appuie Bp 
                                  
                                  void onRise(void);
                                  void onFall(void);
                                  void setup(void);
                                  void loop(void);
                                  
                                  void onFall() {                                     // Interruption lors d'un front descendant
                                    tFall = millis();                                // On sauvegarde la valeur de millis dans tFall
                                    attachInterrupt(btnIrq, onRise, RISING);        // Puis on passe la détection d'interruption sur front montant
                                  }
                                  void onRise() {                                     // Interruption lors d'un front montant
                                    tRise = millis();                                // On sauvegarde la valeur de millis dans tRise
                                    attachInterrupt(btnIrq, onFall, FALLING);       // Puis on passe la détection d'interruption sur front descendant
                                  }
                                  
                                  void setup(void) {                                  // Setup:
                                    attachInterrupt(btnIrq, onFall, FALLING);        // Détection d'interruption sur front descendant au départ
                                    Serial.begin(115200);                           // Serial à 11500 bauds
                                  }
                                  void loop(void) {
                                  
                                    if ( ( tRise != 0 ) && ( tFall != 0 ) ) {
                                      tDiff= tRise - tFall;
                                      Serial.println(tDiff);
                                      tFall=0;tRise=0;tDiff=0;
                                      /*Serial.print("tRise=");
                                      Serial.println(tRise);
                                      Serial.print("tFall=");
                                      Serial.println(tFall);                   // Si les 2 fronts ont été détectés, alors on affiche tout
                                      Serial.print("tDiff=");*/
                                      
                                    }
                                  }

                                  J'ai enlevé quelques affichages sur le moniteur série, cela a rendu l'acquisition beaucoup plus fluide.

                                  Et ce que cela donne sur le moniteur série. On voit bien ce qui arrive lors d'appui trop frénétique. 


                                  Les trois dernières lignes correspondent a des appuis trop rapprochés.

                                  Voilà pour l'instant, je posterai mon avancement dans le développement du programme au fur et à mesure.

                                  Encore une fois merci du gros coup de pouce ;)

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    20 juin 2017 à 10:05:53

                                    L'arduino est un processeur 8bits donc il fait tous les calculs en 8bits.

                                    Si on lui demande de faire des calculs sur des 32bits (unsigned long), il est obligé de le faire en plusieurs fois.

                                    Mais si une interruption se déclenche en pleins milieux, cela peut poser des problèmes.

                                    Par exemple, imaginons que ton programme fasse la soustraction de tDiff et qu'une interruption arrive à ce moment là, alors celle-ci va changer la valeur de tRise ou tFall alors que le processeur était en plein milieu de son opération de soustraction, ce qui donne n'importe quoi comme résultat.

                                    Pour éviter ce problème, il est conseillé de désactiver temporairement les interruptions.

                                    A noter qu'il faut désactiver les interruptions le moins longtemps possible, donc pas de print pendant une désactivation.

                                    Ce qui donne :

                                    void loop(void) {
                                    	
                                    	noInterrupts();
                                    	if ( ( tRise != 0 ) && ( tFall != 0 ) ) {
                                    		tDiff = ( tRise - tFall );
                                    		tRise = 0;
                                    		tFall = 0;
                                    	}
                                    	interrupts();
                                    	
                                    	if ( tDiff != 0 ) {
                                    		Serial.println(tDiff);
                                    		tDiff = 0;
                                    	}
                                    	
                                    }



                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      20 juin 2017 à 10:09:41

                                      Problème presque résolue ( des fois une valeur incorrecte arrive a passer mais cela est assez rare, et il faut vraiment faire des appuis très rapides ).

                                      Le code :)

                                      const byte btnPin = 2;        // Bouton sur pin 2...
                                      const byte btnIrq = 0;       // Bouton sur pin 2, soit INT0 sur arduino UNO.
                                      unsigned long tFall = 0;     // Valeur de millis() lors du front descendant
                                      unsigned long tRise = 0;    // Valeur de millis() lors du front montant
                                      unsigned long tDiff = 0;    //Valeur appuie Bp
                                      
                                      void onRise(void);
                                      void onFall(void);
                                      void setup(void);
                                      void loop(void);
                                      
                                      void onFall() {                                     // Interruption lors d'un front descendant
                                        tFall = millis();                                // On sauvegarde la valeur de millis dans tFall
                                        attachInterrupt(btnIrq, onRise, RISING);        // Puis on passe la détection d'interruption sur front montant
                                      }
                                      void onRise() {                                     // Interruption lors d'un front montant
                                        tRise = millis();                                // On sauvegarde la valeur de millis dans tRise
                                        attachInterrupt(btnIrq, onFall, FALLING);       // Puis on passe la détection d'interruption sur front descendant
                                      }
                                      
                                      void setup(void) {                                  // Setup:
                                        attachInterrupt(btnIrq, onFall, FALLING);        // Détection d'interruption sur front descendant au départ
                                        Serial.begin(9600);                           // Serial à 11500 bauds
                                      }
                                      void loop(void) {
                                      
                                        if ( ( tRise != 0 ) && ( tFall != 0 ) ) {
                                          tDiff = tRise - tFall;
                                          Serial.println(tDiff);
                                          tFall = 0; tRise = 0; tDiff = 0;
                                        }
                                      }



                                      Je continue dans la progression de mon travail !

                                      Edit, d'accord lorrio, je verrai l'impact de ce fonctionnement sur le reste du programme. Je garde ça au chaud ;)

                                      -
                                      Edité par Jr.Soraka 20 juin 2017 à 10:19:15

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        22 juin 2017 à 14:28:56

                                        Salut a tous :) Donc c'est bon grâce a vous mon programme fonctionne. Je mémorise correctement le temps d'appuie du BP, et ensuite je peux demander a la Led de s'allumer sur la même durée. La finalité  sera de réaliser cela avec un moteur et de commander tout cela via Ethernet normalement.

                                        Le code ci cela intéresses quelqu'un ;)

                                        const byte led = 8;                 //Led sur pin 8
                                        const byte btnPin = 2;             // Bouton sur pin 2...
                                        const byte btnIrq = 0;            // Bouton sur pin 2, soit INT0 sur arduino UNO.
                                        unsigned long tFall = 0;         // Valeur de millis() lors du front descendant
                                        unsigned long tRise = 0;        // Valeur de millis() lors du front montant
                                        unsigned long tDiff = 0;       //Valeur appuie Bp
                                        unsigned long mem;            //Variable mémoire
                                        byte varCompteur = 0;        // La variable compteur
                                        char c;
                                        
                                        void onRise(void);
                                        void onFall(void);
                                        void setup(void);
                                        void loop(void);
                                        
                                        void onFall() {                                     // Interruption lors d'un front descendant
                                          tFall = millis();                                // On sauvegarde la valeur de millis dans tFall
                                          attachInterrupt(btnIrq, onRise, RISING);        // Puis on passe la détection d'interruption sur front montant
                                        }
                                        
                                        void onRise() {                                     // Interruption lors d'un front montant
                                          tRise = millis();                                // On sauvegarde la valeur de millis dans tRise
                                          attachInterrupt(btnIrq, onFall, FALLING);       // Puis on passe la détection d'interruption sur front descendant
                                        }
                                        
                                        void setup(void) {
                                          pinMode(led, OUTPUT);
                                          attachInterrupt(btnIrq, onFall, FALLING);         // Détection d'interruption sur front descendant au départ
                                          Serial.begin(9600);                              // Serial à 9600 bauds
                                        }
                                        
                                        void loop(void) {
                                          digitalWrite(led, LOW);
                                        
                                          while (Serial.available()) {
                                            c = Serial.read();
                                            if ( c == 'a') {                                        //Mode "apprentissage"
                                              if ( ( tRise != 0 ) && ( tFall != 0 ) ) {
                                                tDiff = tRise - tFall;                            //On fait la diffèrence entre l'appui et le relachement
                                                Serial.println(tDiff);                           //On affiche le temps d'appui
                                                mem = tDiff;                                    // On sauvegarde la valeur de tDiff dans mem
                                                tFall = 0; tRise = 0; tDiff = 0;               //On remets les variables a zéro
                                              }
                                            }
                                            if ( c == 'b') {                                //Mode "automatique" la led reste allumée pendant le meme temps que tDiff
                                              digitalWrite(led, HIGH);
                                              delay(mem);
                                            }
                                          }
                                        }
                                        
                                        
                                        



                                        -
                                        Edité par Jr.Soraka 22 juin 2017 à 14:29:36

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          22 juin 2017 à 17:44:12

                                          A ta place, j'ajouterais quand même une protection sur la variable mem avant de faire un delay ;)

                                          Comme ça, si jamais il y a eu une erreur de mesure avec un temps de 4294964733 ms, ton programme ne bloquera pas une éternité.

                                          if ( c == 'b') {
                                              if ( mem < 10000 ) {            // Maxi 10 secondes d'allumage
                                                  digitalWrite(led, HIGH);
                                                  delay(mem);
                                                  digitalWrite(led, LOW);
                                              }
                                          }



                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            23 août 2019 à 18:28:13

                                            Bonsoir,

                                            J'obtiens de bon résultat avec ce code.

                                            <code >
                                            const byte btnPin = 2;        // Bouton sur pin 2...
                                            const byte btnIrq = 0;       // Bouton sur pin 2, soit INT0 sur arduino UNO.
                                            unsigned long tFall = 0;     // Valeur de millis() lors du front descendant
                                            unsigned long tRise = 0;    // Valeur de millis() lors du front montant
                                            unsigned long tDiff =0;     //Valeur appuie Bp
                                            void onRise(void);
                                            void onFall(void);
                                            void setup(void);
                                            void loop(void);
                                            void onFall() {                                     // Interruption lors d'un front descendant
                                            tFall = millis();                                // On sauvegarde la valeur de millis dans tFall
                                            attachInterrupt(btnIrq, onRise, RISING);        // Puis on passe la détection d'interruption sur front montant
                                            }
                                            void onRise() {                                     // Interruption lors d'un front montant
                                            tRise = millis();                                // On sauvegarde la valeur de millis dans tRise
                                            attachInterrupt(btnIrq, onFall, FALLING);       // Puis on passe la détection d'interruption sur front descendant
                                            }
                                            void setup(void) {                                  // Setup:
                                            attachInterrupt(btnIrq, onFall, FALLING);        // Détection d'interruption sur front descendant au départ
                                            Serial.begin(115200);                           // Serial à 11500 bauds
                                            }
                                            void loop(void) {
                                            if ( ( tRise != 0 ) && ( tFall != 0 ) ) {
                                            tDiff= tRise - tFall;
                                            Serial.println(tDiff);
                                            tFall=0;tRise=0;tDiff=0;
                                            /*Serial.print("tRise=");
                                            Serial.println(tRise);
                                            Serial.print("tFall=");
                                            Serial.println(tFall);                   // Si les 2 fronts ont été détectés, alors on affiche tout
                                            Serial.print("tDiff=");*/
                                            }
                                            }
                                            < /code>


                                            Cependant je n'arrive pas à donner un déclenchement sur le Pin 8 en fonction de la valeur de tDiff ( compris entre deux valeurs )

                                            Le pin 8 Active un relais.

                                            Je n'arrive pas à saisir un code correct.

                                            Pouvez vous m'aider ?

                                            Merci d'avance

                                            Voici mon script, il fonctionne une pièce sur deux ( quelque soit l'intervalle de temps de passage )

                                            <code >
                                            // DECLARATION DES CAPTEURS
                                            int air = 8; // vers relais AIR
                                            const byte cap = 2; // vers CAPTEUR LASER
                                            const byte btnIrq = 0;
                                            
                                            // DETECTION DES FRONTS
                                            
                                            static unsigned long tFall = 0;         // Valeur de millis() lors du front descendant
                                            static unsigned long tRise = 0;        // Valeur de millis() lors du front montant
                                            unsigned long tDiff = 0;       //Valeur appuie Bp
                                            unsigned long mem;            //Variable mémoire
                                            
                                            //SETUP
                                            void onRise(void);
                                            void onFall(void);
                                            void setup(void);
                                            void loop(void);
                                             
                                            void onFall()
                                            {                                     // Interruption lors d'un front descendant
                                              tFall = millis();                                // On sauvegarde la valeur de millis dans tFall
                                              attachInterrupt(btnIrq, onRise, RISING);        // Puis on passe la détection d'interruption sur front montant
                                            
                                            }
                                            
                                            void onRise()
                                            {                                     // Interruption lors d'un front montant
                                            tRise = millis();                                // On sauvegarde la valeur de millis dans tRise
                                            attachInterrupt(btnIrq, onFall, FALLING);       // Puis on passe la détection d'interruption sur front descendant
                                             
                                            }
                                             
                                            void setup(void)
                                            {
                                            // PULLUP  
                                            pinMode(cap, INPUT_PULLUP);
                                            
                                            //
                                            pinMode(air, OUTPUT);
                                            attachInterrupt(btnIrq, onFall, FALLING);         // Détection d'interruption sur front descendant au départ
                                            ///////////////////
                                            Serial.begin(115200);                              // Serial à 9600 bauds
                                            }
                                            void loop(void) {
                                            
                                            digitalWrite(air, LOW);
                                            noInterrupts();
                                            
                                            ///////////////0  
                                            if ( ( tRise != 0 ) && ( tFall != 0 ) )
                                            {
                                                    tDiff = ( tRise - tFall );
                                                    mem = tDiff;        
                                            }
                                            interrupts();
                                            
                                            if ( mem > 150 && mem < 300  )
                                            {            
                                            Serial.println(tDiff);
                                            //  Serial.println(tDiff);
                                            //Serial.println(tFall);
                                            //Serial.println(tRise);
                                            digitalWrite(air, HIGH);
                                            delay(300); // EXPULSION DE LA PIECE
                                            //   digitalWrite(air, LOW);
                                            mem = 0; tFall = 0; tRise = 0; tDiff = 0; // REMISE A ZERO 
                                            
                                            
                                            }}
                                            < /code>

                                            -
                                            Edité par FrankLessard 23 août 2019 à 21:16:21

                                            • Partager sur Facebook
                                            • Partager sur Twitter

                                            [Arduino] Calcul du temps qu'un Bp est appuyé

                                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                            • Editeur
                                            • Markdown