Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème clignotement LED et compteur appui BP

    27 décembre 2020 à 22:42:56

    Bonjour à tous,

    J'ai un problème avec une LED et 4 boutons poussoir. Ils sont tous reliés à un MCP23017.

    Je souhaite interrompre le clignotement de la LED et la rendre fixe lorsque j'appuie 3x sur l'un des quatre boutons. Ca peut-être sur le 1er, le 2nd, le 3eme ou le 4eme, qu'importe.

    Pour cela j'ai écrit un code qui compte le nombre d'appuis. Problème: il prend en compte le bouton 1 mais pas les trois autres ! J'ai beau appuyer dessus, ils sont comme transparents. Pourquoi ? Où se trouve mon erreur ?

    Merci d'avance...

    #include <Wire.h>
    #include "Adafruit_MCP23017.h"
    
    
    int buttonCounter1 = 0;// variable pour le comptage du nombre d'appuis sur le bouton poussoir
    int buttonCounter= 0;//Variable pour l'état actuel du bouton poussoir
    int lastButtonCounter = 0;// Variable pour l'état précédent du bouton poussoir
    
    bool clignotement1 = true; 
    const unsigned long Intervaldeclignotement = 250; 
    unsigned long Millisactuel; 
    unsigned long Millisprecedent;
    
    
    void setup() {
    
    Serial.begin(9600);
    mcp.begin();
    
    mcp.pinMode(1, OUTPUT);//LED
    mcp.pinMode(2, INPUT);//BP1
    mcp.pullUp(2, HIGH);
    mcp.pinMode(3, INPUT);//BP2
    mcp.pullUp(3, HIGH);
    mcp.pinMode(4, INPUT);//BP3
    mcp.pullUp(4, HIGH);
    mcp.pinMode(5, INPUT);//BP4
    mcp.pullUp(5, HIGH);
    
    }
    
    void loop() {
    
    if (clignotement1) {  
      
      Millisactuel = millis();
      if (((unsigned long)(Millisactuel - Millisprecedent) >= Intervaldeclignotement) ) {
       mcp.digitalWrite(1, !mcp.digitalRead(1));
       Millisprecedent = Millisactuel; 
       }
     } else {
     mcp.digitalWrite(1, HIGH);
    }
    
    
    
    buttonCounter1 = (mcp.digitalRead(2) | mcp.digitalRead(3) | mcp.digitalRead(4) | mcp.digitalRead(5));
    
    if (buttonCounter1 != lastButtonCounter) {
    if (buttonCounter1 == LOW) {
    buttonCounter++;
    }
    lastButtonCounter = buttonCounter1;
    }
    
    if (buttonCounter >= 3) {
    clignotement1 = false; 
     
     }
    
    
    }



    -
    Edité par MatthieuWilhelm 27 décembre 2020 à 22:50:07

    • Partager sur Facebook
    • Partager sur Twitter
      29 décembre 2020 à 1:08:04

      Bonjour Matthieu,

      Je trouve cette instruction un peu bizarre :

      buttonCounter1 = (mcp.digitalRead(2) | mcp.digitalRead(3) | mcp.digitalRead(4) | mcp.digitalRead(5));

      Cela veut dire lorsque tu appuis sur le bouton : bouttonCounter1 vaut 1 sinon il vaut 0.

      Ensuite tu dis :

      lastButtonCounter = buttonCounter1;

      Donc lastButtonCounter vaut 1.

      Après si je reboucle ton code :

      if (buttonCounter1 != lastButtonCounter)

      Si le bouton est lâché on rentre dedans : car bouttonCounter1 = 0 et lastButtonCounter vaut 1.

      Dans ta logique il faut que tu réinitialise 

      lastButtonCounter = buttonCounter1;

      lastButtonCounter à 0 alors.

      Mais après dans la façon de faire je suis pas fan du tout de ton code ;) Tu regardes tes entrées boutons en scrutation, c'est à dire que tu attends en boucle un changement d'état. Tu peux passer à coté d'un appui de bouton avec cette méthode je m'explique :

      Imaginons que lorsque tu appuies sur le bouton tu sois dans ta boucle if de ton programme.

      if (((unsigned long)(Millisactuel - Millisprecedent) >= Intervaldeclignotement) ) {
         mcp.digitalWrite(1, !mcp.digitalRead(1));
         Millisprecedent = Millisactuel;
         }

      Et que tu relâche aussitôt ton doigts du bouton,   et que tu n'arrives pas à l'instruction : 

      buttonCounter1 = (mcp.digitalRead(2) | mcp.digitalRead(3) | mcp.digitalRead(4) | mcp.digitalRead(5));

      Résultat : Ton action est totalement transparente pour le code. Ce n'est tout simplement la bonne méthode à prendre en compte. (Dans les faits tu as de la chance car ton processeur est assez rapide pour voir ton appui mais c'est pas propre du tout :p )

      Il faut que tu procèdes par interruption et non par scrutation : L'interruption est une fonction qui est appelé lorsqu'un événement est apparu (comme par exemple appui sur un bouton) : Pour cela je t'invite à regarder ceci : https://simple-duino.com/interruption-et-arduino/ et de reproduire le montage pour que tu comprennes le fonctionnement. C'est très simple à mettre en œuvre : et c'est professionnel ! :) 

      Ps : attention au phénomène de rebond il faut rajouter une résistance en série et un condensateur en parallèle de ton bouton. (Pour faire un filtre passe bas : en éviter les harmoniques de hautes fréquences): Attention suivant ta carte Arduino il y a des pins associés pour les interruptions : Je serais toi je mettrais mes boutons en parallèle sur la pin D2 par exemple (un seul condensateur et une seule résistance) :)

      Cordialement.

      Kasimashi.




      -
      Edité par Kasimashi 29 décembre 2020 à 1:18:59

      • Partager sur Facebook
      • Partager sur Twitter
        29 décembre 2020 à 10:53:21

        Merci beaucoup pour ta réponse et d'avoir pris le temps de me répondre. Je vais étudier ce que tu m'as dit.
        • Partager sur Facebook
        • Partager sur Twitter
          29 décembre 2020 à 11:02:07

          Pas de soucis : N'hésites pas à nous faire part de tes avancées et de tes problèmes rencontrés.

          Kasimashi.

          • Partager sur Facebook
          • Partager sur Twitter

          Problème clignotement LED et compteur appui BP

          × 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