Bouton arduino qui ne fonctionne pas

Bonjour.

Mon code ci-dessous gère un coffre fort. Il est majoritairement constitué de fonctions qui ont pour but de changer le code administrateur de mon coffre.
Je code sur un simulateur d'arduino qui se nomme Wokwi et j'ai un problème de bouton qui ne s'active pas. Dans mon cas, c'est le bouton "bouton_validation" dans la fonction "validation".

J'ai tout essayé :

  • Ne pas mettre de conditions dans des conditions,
  • Changer le pin auquel est associé le bouton,

J'ai parcouru mon code de fond en comble mais je ne comprends pas pourquoi il ne fonctionne pas.

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 10, 9, 8, 7);

#include <Servo.h>

Servo servo1;
Servo servo2;

int valeur1; //valeur du potentiomètre1
int valeur2; //valeur du potentiomètre2
int administrator_code1; //code administrateur potentimomètre1 (définit au démarrage)
int administrator_code2; //code administrateur potentimomètre2 (définit au démarrage)

int bouton_changer_code = 3;
int bouton_validation = 4;

int potentiometre1 = A0;
int potentiometre2 = A1;

int actif_bouton_valid;

void setup() {
  Serial.begin(9600);
  pinMode(A0,INPUT);
  servo1.attach(5);
  
  servo2.attach(6);
  
  pinMode(bouton_changer_code, INPUT);
  digitalWrite(bouton_changer_code, LOW);

  pinMode(bouton_validation, INPUT);
  digitalWrite(bouton_validation, LOW);

  lcd.begin(16, 2);
  lcd.print("Entrer le code:");

  actif_bouton_valid = 0;
}

void loop() {
  valeur1 = analogRead(potentiometre1);
  valeur2 = analogRead(potentiometre2);
  lcd.setCursor(0, 1);
  lcd.print(valeur1);
  lcd.print("   ");
  lcd.setCursor(6, 1);
  lcd.print(valeur2);
  lcd.print("   ");



  if(digitalRead(bouton_changer_code) == HIGH){
    if(valeur1 != administrator_code1 or valeur2 != administrator_code2){
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Code admin");
      lcd.setCursor(0, 1);
      lcd.print("incorrect");
      delay(1000);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Entrer le code:");
    }
    else{
      changer_code();
      validation();
    }
  }
  if(administrator_code1 == valeur1 && administrator_code2 == valeur2){
    servo1.write(90);
    servo2.write(90);
  }
  else{
    servo1.write(0);
    servo2.write(0);
  }
}

void changer_code(){
  if(digitalRead(bouton_changer_code) == HIGH){  
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Entrer nouveau");
    lcd.setCursor(0, 1);
    lcd.print("code administrateur:");
    delay(1000);
    lcd.clear();
    lcd.print("Nouveau code:");
    lcd.setCursor(0, 1);
    lcd.print(valeur1);
    lcd.print(" ");
    lcd.setCursor(1, 6);
    lcd.print(valeur2);
    lcd.print(" ");
    actif_bouton_valid = 1;
    /*administrator_code1 = valeur1;
    administrator_code2 = valeur2;*/
    }
  }

void validation(){
  if(actif_bouton_valid = 1){
    if(digitalRead(bouton_validation) == HIGH){
      administrator_code1 = valeur1;
      administrator_code2 = valeur2;
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Code admin");
      lcd.setCursor(0, 1);
      lcd.print("modifié :)");
    }
  }
}

Pour faire un test c'est ==

Même en modifiant le = en == le code ne fonctionne pas. Pourquoi utiliser la résistance de pullupe interne ?

Bonsoir pandaroux007

Tu ne peut pas changer ça aussi facilement, la lecture d'un bouton en PULLUP, pressé, donne un LOW, alors qu'ils sont testés HIGH
if(digitalRead(bouton_changer_code) == HIGH)

Il faut, surtout, que le bouton soit, d'un côté, câblé au GND.

Cordialement
jpbbricole

Voici le shéma arduino :


Le bouton_validation est le vert.

Il faudrait d'abord savoir comment sont câblés les boutons avant de s'avancer dans la façon de les lire..

C'est pas toi qui doit faire un schéma c'est @xouney qui doit nous décrire SON montage. D'après son code, on pourrait supposer qu'ils sont câblés entre I/O et +5V. Ce qui nécessiterait plutôt une résistance de pull down.

@xouney dans validation tu n'affiches pas les codes. C'est voulu?

Bonjour fdufnews

C'est dans le programme:

on peut en déduire que c'est câblé en PULLDOWN.

Cordialement
jpbbricole

Bonjoiur pandaroux007

Une petite recherche Arduino PULLUP devrait suffire?

Cordialement
jpbbricole

Bonjour pandaroux007

Oui, mais non.
Ton raisonnement, quoi qu'un peu compliqué ne change rien au fait qu'il faille changer le câblage du bouton.
Et pour lire le bouton:
if(digitalRead(bouton_changer_code) == LOW)
est quand même plus simple.

Una variable booléenne vaut false ou true. et pour l'état d'un port par digitalRead, int est le plus usité.

Cordialement
jpbbricole

Bonjour @xouney
En mettant : validation()
dans le loop ça devrais fonctionner

et ajoute un delay juste apres: "lcd.print("modifié :)");"
sinon tu verra pas que ça a été pris en compte.
(les accents ne sont pas pris en compte sur un lcd donc à enlever )

@pandaroux007

Si de base cela ne fonctionne pas en pulldown pourquoi cela devrais fonctionner en pullup ?

L'appel à la fonction: validation(); dans le "else " n'est pas lu dans le code, donc c'est pas en changeant le type de l'entrée que cela fonctionnera mieux ..

Bonjour,
Le montage est correct.
Les conditions d'appui sur les boutons doivent se trouver dans la loop()
La variable actif_bouton_valid ne doit pas rester à 1
L'affichage permanent de la valeur des potentiomètres entre en conflit avec les autres affichages.

Voilà un bout de code qui devrait fonctionner (notez que code1 et 2 sont à 0 au départ) :

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
#include <Servo.h>

Servo servo1;
Servo servo2;

int valeur1; //valeur du potentiomètre1
int valeur2; //valeur du potentiomètre2
int administrator_code1 = 0; //code administrateur potentimomètre1 (définit au démarrage)
int administrator_code2 = 0; //code administrateur potentimomètre2 (définit au démarrage)

int bouton_changer_code = 3;
int bouton_validation = 4;

int potentiometre1 = A0;
int potentiometre2 = A1;

int actif_bouton_valid;

void setup() {
  Serial.begin(9600);
  pinMode(A0,INPUT);
  servo1.attach(5);
  
  servo2.attach(6);
  
  pinMode(bouton_changer_code, INPUT);
  digitalWrite(bouton_changer_code, LOW);

  pinMode(bouton_validation, INPUT);
  digitalWrite(bouton_validation, LOW);

  lcd.begin(16, 2);
  lcd.print("Entrer le code:");

  actif_bouton_valid = 0;
}

void loop() {
  valeur1 = analogRead(potentiometre1);
  valeur2 = analogRead(potentiometre2);
  lcd.setCursor(0, 1);
  lcd.print(valeur1);
  lcd.print("   ");
  lcd.setCursor(6, 1);
  lcd.print(valeur2);
  lcd.print("   ");



  if(digitalRead(bouton_changer_code) == HIGH){
    if(valeur1 != administrator_code1 or valeur2 != administrator_code2){
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Code admin");
      lcd.setCursor(0, 1);
      lcd.print("incorrect");
      delay(1000);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Entrer le code:");
    }
    else{
     changer_code();
    }
  }

  if(digitalRead(bouton_validation) == HIGH && actif_bouton_valid == 1){
      administrator_code1 = valeur1;
      administrator_code2 = valeur2;
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Code adm modifie");
      actif_bouton_valid = 0;
    }

  if(administrator_code1 == valeur1 && administrator_code2 == valeur2){
    servo1.write(90);
    servo2.write(90);
  }
  else{
    servo1.write(0);
    servo2.write(0);
  }
}

void changer_code(){
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Entrer nouveau");
    lcd.setCursor(0, 1);
    lcd.print("code administrateur:");
    delay(1000);
    lcd.clear();
    lcd.print("Nouveau code:");
    lcd.setCursor(0, 1);
    lcd.print(valeur1);
    lcd.print(" ");
    lcd.setCursor(1, 6);
    lcd.print(valeur2);
    lcd.print(" ");
    actif_bouton_valid = 1;
    /*administrator_code1 = valeur1;
    administrator_code2 = valeur2;*/
    
  }

Bon courage.

PS : Je ne suis pas entré dans les détails du code. A supprimer :
digitalWrite(bouton_changer_code, LOW), il faudra déclarer vos valeurs qui ne changent pas en constantes ... Voilà tout au plus de quoi commencer à structurer votre programme.

Comment ça je n'affiche pas les codes ?

Les ":" à la fin du texte me donne à penser que quelque chose devrait suivre.

@fdufnews :

bonjour,
je pense qu'il s'agit plus d'un smiley que d'une invitation à une suite dans le texte...

Pourquoi ?
Pour pouvoir utiliser une résistance de tirage au Vcc OK.
Mais la plupart des micros récents ont aussi des résistances de tirage à la masse.

Sinon c'est une bonne habitude pour les boutons poussoirs en "habillage" métal.
Le métal qui peut faire antenne, on préfère le connecter à la masse.
Avec du tout plastique, connecter à la masse ou au Vcc ne changera pas grand-chose.

Bonsoir 68tjs

Oh que oui!

"Travailler en PULLUP" a l'avantage d'éviter de devoir amener un potentiel au(x) boutons et autres commutareurs..., seul le GND est nécessaire ce qui est quand même plus pratique.

Avis d'un expert en bricolage sur un coin de table :grinning:

Cordialement
jpbbricole

Ce serait bien de se recentrer sur la question de @xouney et d'arrêter de vouloir réparer les choses qui marchent.
Que le bouton soit tiré au +5V ou à GND ne change rien du moment que les tests dans le code sont adaptés.
Le montage de @xouney montre des poussoirs connectés à +5V avec des pull down c'est son choix. Il teste l'appui en vérifiant que le signal est HIGH c'est correct. On peut lui dire que ce serait plus simple de faire le contraire et d'utiliser les pullup interne mais ce n'est pas la peine d'insister lourdement pendant plusieurs posts et d'entamer une polémique sur le sujet donc je suggère que l'on passe à autre chose.

@xouney tu dis que le code ne fonctionne pas comme prévu mais je ne vois aucun Serial.print() dans le code qui te permettrait de tracer le déroulement du code et de comprendre ce qui se passe ou ne se passe pas.
Qu'est-ce qui te permet d'affirmer que le bouton ne fonctionne pas?
Comme l'a fait remarquer @matth122 le fait qu'il n'y ait pas de délai peut donner à penser que le code ne passe pas dans une certaine partie du code.
Si tu ne traces pas le déroulement du programme en faisant afficher le passage dans les différentes parties du code ainsi que la valeur de quelques variables c'est difficile de comprendre ce qui ne va pas.

1 Like

hello
ou un lien vers le wokwi