IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

Clignotement LED et plusieurs BP


Sujet :

Arduino

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Mars 2017
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mars 2017
    Messages : 41
    Points : 26
    Points
    26
    Par défaut Clignotement LED et plusieurs BP
    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...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
     #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;
     
     }
     
     
    }

  2. #2
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 722
    Points : 5 411
    Points
    5 411
    Par défaut
    Bonsoir

    décrivez précisément tous les branchements, quel Arduino vous utilisez et comment le tout est alimenté.

    comme vous avez un pull up, par défaut tous les boutons sont HIGH quand ils sont au repos

    regardez sinon du côté de l'expression (qui devrait être effectuée en calcul booléen)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    buttonCounter1 = (mcp.digitalRead(2) | mcp.digitalRead(3) | mcp.digitalRead(4) | mcp.digitalRead(5));
    va donner 1 donc sauf si les 4 boutons sont appuyés (à 0) puisque avec un OU (le |) le résultat est vrai dès qu'un des éléments est vrai

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Mars 2017
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mars 2017
    Messages : 41
    Points : 26
    Points
    26
    Par défaut
    Merci pour votre réponse.
    Il s'agit d'un Arduino UNO, câblé très exactement pareil que sur ce schéma, à la différence que 3 autres BP ont été ajouté et que 1 seule LED est présente.


    Nom : mcp23017_breadboard.jpg
Affichages : 403
Taille : 24,9 Ko

    Donc pour vous, mon code ne contient pas d'erreur ? Car les 3 autres boutons sont inactifs dans le comptage...

  4. #4
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 722
    Points : 5 411
    Points
    5 411
    Par défaut
    Citation Envoyé par ochey54 Voir le message
    Merci pour votre réponse.
    Il s'agit d'un Arduino UNO, câblé très exactement pareil que sur ce schéma, à la différence que 3 autres BP ont été ajouté et que 1 seule LED est présente.
    donc le schéma ne correspond pas et si vous avez un souci de câblage ailleurs on ne le sait pas. Il ne faut pas prendre l’habitude de partager un schéma Fritzing ce n’est pas simple à lire. Faites plutôt un schéma avec des traits, les symboles des composants et leur valeurs etc...


    Donc pour vous, mon code ne contient pas d'erreur ? Car les 3 autres boutons sont inactifs dans le comptage...
    Il me semble que je n’ai pas dit cela. Avez vous réfléchi à votre expression
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     buttonCounter1 = (mcp.digitalRead(2) | mcp.digitalRead(3) | mcp.digitalRead(4) | mcp.digitalRead(5));

  5. #5
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 335
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 335
    Points : 4 158
    Points
    4 158
    Par défaut Boutons & bouton
    Bonjour,

    Déjà les boutons sont traités comme un seul bouton. La duplication du rôle des boutons ne permet pas d'en différencier un parmi les autres. Tous marchent ou aucun. Ici sauf à appuyer sur les quatre en même temps, il n'y aura aucun effet car c'est la seule manière de mettre buttonCounter1 à 0. Donc, s'il y a un comportement différencié c'est que le câblage n'est pas le même pour chaque bouton.

    D'autre part, outre le fait qu'un & serait préférable, le principe d'une seule variable buttonCounter1 unifie les 4 boutons en un seul. Cela permet d'appuyer brièvement sur un bouton puis un autre et un autre encore pour avoir 3 impulsions. Si c'est le choix fait, pourquoi ne pas brancher les 4 boutons en // et ne faire qu'une lecture ?

    Par ailleurs comment réactiver le clignotement (rien dans le code) ?

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
       buttonCounter1 = (mcp.digitalRead(2) & mcp.digitalRead(3) & mcp.digitalRead(4) & mcp.digitalRead(5)); // Bof
       buttonCounter += buttonCounter1 <  lastButtonCounter;  // En écrivant buttonCounter =  (buttonCounter + (buttonCounter1 <  lastButtonCounter) & 3 on réactive le clignotement avec un quatrième appui
       lastButtonCounter = buttonCounter1;
       clignotement1 = buttonCounter < 3;

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  6. #6
    Membre émérite
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 012
    Points : 2 341
    Points
    2 341
    Par défaut
    Bonjour ochey54

    Je pense que le principal problème se situe ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    buttonCounter1 = (mcp.digitalRead(2) | mcp.digitalRead(3) | mcp.digitalRead(4) | mcp.digitalRead(5));
    Tu utilises la fonction boolenne OR en manipulation de bits alors qu'il faut utiliser la comparaison ||. C'est la même chose que = et ==, & et && etc.

    Je n'ai pas refait tout ton programme mais me suis permis quelques retouches au niveau du nom des variables et de leur type.
    L'essentiel est ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
         buttonPressed = !mcp.digitalRead(2) || !mcp.digitalRead(3) || !mcp.digitalRead(4) || !mcp.digitalRead(5);
    Comme tu travailles avec des boutons actif à 0 (LOW), il faut "inverser" la lecture avec la fonction NOT !
    et le tout:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
     #include <Adafruit_MCP23017.h>
     
     
     
    Adafruit_MCP23017 mcp;
     
     
     boolean buttonPressed = false; // Variable pour l'état actuel du bouton poussoir
     boolean lastButtonStatus = false;// Variable pour l'état précédent du bouton poussoir
     int buttonCounter= 0;  // variable pour le comptage du nombre d'appuis sur le bouton poussoir
     
     void setup()
     {
         Serial.begin(115200);
         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()
     {
         buttonPressed = !mcp.digitalRead(2) || !mcp.digitalRead(3) || !mcp.digitalRead(4) || !mcp.digitalRead(5);
     
         if (buttonPressed != lastButtonStatus)
         {
             if (buttonPressed == true)
             {
                 buttonCounter ++;
                 Serial.println(buttonCounter);
                 if (buttonCounter >= 3)
                 {
                     buttonCounter = 0;
                 }
             }
             lastButtonStatus = buttonPressed;
         }
     
     
     }
    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  7. #7
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 722
    Points : 5 411
    Points
    5 411
    Par défaut
    welcome back @JP

    oui pour dire "si un des boutons est appuyé" il faut donc regarder si au moins une des valeurs est à LOW (0)

    donc en explicitant totalement la formulation de la condition ce serait

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    if (
        (mcp.digitalRead(2) == LOW) ||   // est-ce que le 1er  bouton est appuyé OU
        (mcp.digitalRead(3) == LOW) ||   // est-ce que le 2ème bouton est appuyé OU
        (mcp.digitalRead(4) == LOW) ||   // est-ce que le 3ème bouton est appuyé OU
        (mcp.digitalRead(5) == LOW)      // est-ce que le 4ème bouton est appuyé
      ) {
      // un des boutons est appuyé
     
    }
    si on se souvient que LOW c'est 0 et que le C++ effectue la promotion de type automatiquement, si on applique l'opérateur logique NOT (!) à un nombre, le nombre est d'abord promu en valeur de vérité (false s'il vaut 0, true sinon) lorsque l'on fait !0le compilateur traduit cela en ! false ce qui fait donc true et inversement si on fait !1le compilateur traduit cela en ! true ce qui fait donc false

    c'est le principe retenu par @JP pour écrire sa formule en raccourci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    buttonPressed = !mcp.digitalRead(2) || !mcp.digitalRead(3) || !mcp.digitalRead(4) || !mcp.digitalRead(5);
    ça génère le même code que si on fait le test avec == LOW.

    PS: Dans ce cas précis, comme on n'a que des 0 (LOW) et des 1 (HIGH), utiliser le OU bit bit | ou le OU logique || ne changerait rien au résultat, mais il vaut mieux être cohérent et utiliser le OU logique donc ||

  8. #8
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 335
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 335
    Points : 4 158
    Points
    4 158
    Par défaut Au temps pour moi...
    Bonjour,

    C'est toujours bien d'utiliser une temporisation qui ne bloque pas un processus, mais un statut conservé, par exemple, dans une variable booléenne globale isLedOn éviterait de relire une entrée qui a la valeur que nous venons de lui imposer (cela n'a cependant pas d'incidence sur le bon déroulement du programme).

    Hélas, il ne faut pas oublier que "toute bonne action ne peut rester impunie". Ainsi, le fait d'avoir un timer non bloquant entraîne une accélération forte de la lecture des boutons et donc une sensibilité au moindre rebond des contacts. A régler soit par un câblage avec filtrage par RC, soit par une temporisation sur détection de front descendant.

    Ceci étant, le montage réel demandé par Jay M reste un élément important de la résolution des problèmes rencontrés.

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  9. #9
    Nouveau membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Mars 2017
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mars 2017
    Messages : 41
    Points : 26
    Points
    26
    Par défaut
    Merci infiniment pour vos réponses !

    Je vais essayer d'appliquer vos conseils dans mon code.

    Bien à vous.

Discussions similaires

  1. Timer TMR1 pour clignotement LED
    Par Akitah dans le forum MPLAB
    Réponses: 5
    Dernier message: 23/09/2020, 17h21
  2. clignotement Leds, Timer
    Par faycal91 dans le forum Autres architectures
    Réponses: 0
    Dernier message: 10/01/2011, 20h12
  3. Ajout de fonction : faire clignoter une led
    Par Nono69690 dans le forum C
    Réponses: 16
    Dernier message: 06/06/2009, 13h37
  4. ecouteurs externes sur plusieurs leds
    Par nelob dans le forum Interfaces Graphiques en Java
    Réponses: 2
    Dernier message: 05/11/2007, 03h11
  5. Led qui "presque" clignote
    Par Blue_Strike dans le forum Composants
    Réponses: 5
    Dernier message: 27/04/2007, 21h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo