Problème détection séquence bouton

Bonjour,

J'essaie de créer un programme qui a pour but d'ouvrir une porte lorsque la bonne séquence de bouton est appuyer.
J'ai donc 4 bouton branché sur les broches 2, 3, 4, 5 - 4 LED branché sur les broches 6, 7, 8, 9 et un relai branché sur la broche 12.

Je suis la détection des boutons grâce au moniteur série et là je comprend plus, voici mon problème :

  • Déjà les boutons 3 et 4 ne sont pas détecté (broche 4 et 5), lorsque je les changes pour les mettre sur les broches 2 et 3 ils sont détecté donc ce n'est a priori pas le câblage. Si je branche QUE les 2 boutons et sur les broches 3 et 4 ils sont détecté.

  • Lorsque tout les boutons sont branchés, l'arduino ne détecte donc que les boutons 1 et 2, mais je ne peux pas appuyer comme je le veux. Si je commence par appuyer sur le bouton n°2 il n'est pas détecté, si j'appuie sur le bouton n°1 il l'est, mais je ne peux pas réappuyer sur le bouton n°1, en soi les boutons ne sont détecté que dans cette ordre là 1-2-1-2-1-2

Voici mon code :

const int buttonPins[] = {2, 3, 4, 5}; // Les pins des boutons
const int Led[] = {6, 7, 8, 9}; // Pins Led
const int relayPin = 12; // Le pin du relais

const int sequence[] = {0, 1, 0, 2, 0, 2}; // Séquence à suivre
const int sequenceLength = sizeof(sequence) / sizeof(sequence[6]);

int currentStep = 0;

void setup() {
  for (int i = 0; i < 5; i++) {
    pinMode(buttonPins[i], INPUT);
  }
  for (int j = 6; j < 9; j++){
    pinMode(Led[j], OUTPUT);
    digitalWrite(Led[j], LOW);
  }
  Serial.begin(9600);
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, LOW); // Assurez-vous que le relais est désactivé au début
}

void loop() {
  for (int i = 0; i < 4; i++) {
    if (digitalRead(buttonPins[i]) == HIGH) {
         Serial.print("bouton");
         Serial.print(i);
         digitalWrite(Led[i], HIGH);
      if (i == sequence[currentStep]) {
        currentStep++;
        delay(200); // Anti-rebond
        digitalWrite(Led[i], LOW);
        while (digitalRead(buttonPins[i]) == HIGH); // Attendez que le bouton soit relâché
      } else {
        currentStep = 0; // Réinitialiser la séquence si le mauvais bouton est pressé
      }
    }
  }

  if (currentStep == sequenceLength) {
    digitalWrite(relayPin, HIGH); // Activer le relais
    delay(5000); // Maintenir le relais activé pendant 5 secondes (par exemple)
    digitalWrite(relayPin, LOW); // Désactiver le relais
    currentStep = 0; // Réinitialiser la séquence
  }
}

Merci d'avance pour votre aide

Bonsoir
Sans trop rentrer dans les détails du programme, vous avez déjà un problème dans les boucles.
Dans le setup : i prend les valeurs 0 à 4 et j de 6 à 8.
Dans le loop : i prend les valeurs de 0 à 3.

Cordialement

j avais fait le meme style sur wokwi si ca peux t aider
wokwi

Bonsoir nips_o
Sur ces pin:
buttonPins[] = {2, 3, 4, 5}; // Les pins des boutons
As tu mis des résistances de PULLDOWN ?
En général 10k.
image
Sans ça, tes entrées sont dites "en l'air" et parfois, le simple fait d'approcher la main peut être pris comme un signal.

for (int i = 0; i < 5; i++)
doit être
for (int i = 0; i < 4; i++)
en effet tu n'as que 4 éléments dans ton tableau numérotés de 0 à 3 (< 4)

Idem pour
for (int j = 0; j < 9; j++)
doit être
for (int j = 0; j < 4; j++)
Les variables i et j ne sont pas les numéros des ports mais l'indice du tableau dans lequel est stocké le numéro du port.

A+
Cordialement
jpbbricole

Rebonsoir nips_o

Un petit conseil à propos du PULLDOWN et PULLUP, il est souvent plus pratique de faire la "technique" du PULLUP
image
et de profiter, ainsi, de la résistance interne de PULLUP de l'Arduino, ainsi plus besoin de résistances additionnelles.

Les changements à faire sont à l'initialisation des ports d'entrée:
pinMode(buttonPins[i], INPUT_PULLUP);

et la lecture d'un bouton pressé:
if (digitalRead(buttonPins[i]) == LOW)

Bonne soirée
Cordialement
jpbbricole

Bonsoir,
Déjà, merci d'avoir pris le temps de me répondre !

Si je dis pas de bêtise, je cherche a détecter la pression sur les boutons qui eux sont sur les broches de 2 à 5 et il y en a 4, donc c'est bien une écoute sur 4 entrée ?

Cordialement

Bonjour,

Et merci d'avoir pris le temps de répondre !

Merci pour la découverte de ce site ! Je connaissais Tinkercad mais Wokwi à l'air plus complet !

Je vais essayé d'analyser ton code mais je suis débutant et il y a plein de variable et et fonction que je ne connais pas encore (je me suis pris une formation sur Udemy, donc ça va venir ! :smiley: )

Mais sinon c'est le même concept que je veux faire ! Donc merci ton projet va beaucoup m'aider !

Bonjour,

Merci d'avoir pris le temps de me répondre de manière très clair et pédagogue !

Alors c'est vrai qu'entre temps j'ai mis une résistance PULLUP, mais merci pour l'explication et le lien ! Par contre si je met :

if (digitalRead(buttonPins[i]) == LOW)

Les détections se font en permanence, donc j'ai laissé sur HIGH ?

Merci de m'avoir fait comprendre mon erreur sur la déclaration des variable dans le setup

Bonne soirée également,
Cordialement,
Nips_o

Donc j'ai appliqué les modifications suggérer, voici l'update :

const int buttonPins[] = {2, 3, 4}; // Les pins des boutons
const int Led[] = {5, 6, 7, 8}; // Pins Led
const int relayPin = 9; // Le pin du relais

const int sequence[] = {0, 1, 0, 2, 0, 2}; // Séquence à suivre
const int sequenceLength = sizeof(sequence) / sizeof(sequence[0]);

int currentStep = 0;

void setup() {
  for (int i = 0; i < 4; i++) {
    pinMode(buttonPins[i], INPUT_PULLUP);
  }
  for (int j = 0; j < 4; j++){
    pinMode(Led[j], OUTPUT);
    digitalWrite(Led[j], LOW);
  }
  Serial.begin(9600);
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, LOW); // Assurez-vous que le relais est désactivé au début
}

void loop() {
  for (int i = 0; i < 5; i++) {
    if (digitalRead(buttonPins[i]) == HIGH) {
         Serial.print("bouton");
         Serial.print(i);
         digitalWrite(Led[i], HIGH);
      if (i == sequence[currentStep]) {
        currentStep++;
        delay(200); // Anti-rebond
        digitalWrite(Led[i], LOW);
        while (digitalRead(buttonPins[i]) == HIGH); // Attendez que le bouton soit relâché
      } else {
        currentStep = 0; // Réinitialiser la séquence si le mauvais bouton est pressé
      }
    }
  }

  if (currentStep == sequenceLength) {
    digitalWrite(relayPin, HIGH); // Activer le relais
    delay(5000); // Maintenir le relais activé pendant 5 secondes (par exemple)
    digitalWrite(relayPin, LOW); // Désactiver le relais
    currentStep = 0; // Réinitialiser la séquence
  }
}

Mais j'ai toujours le même problème à la détection, si j'appuie sur le bouton 1 il est détecté mais si en suite j'appuie sur le bouton 3 il ne l'est pas, mais le 2 oui, et je ne peux appuyer qu'avec cette séquence 1-2-1-2-1-2.

Au passage quand j'appuie sur le bouton 2 (sur la broche 3) il détecte une pression sur les broche 2 et 4, déclaré respectivement 0 et 2 dans la variable. (le moniteur série affiche "bouton 2 bouton 0"

Bon, c'est peut-être un peu flou comme description du coup j'ai fait un Wokwi

Encore merci !
Bonne soirée

Bonjour nips_o

Plusieurs choses dans ton nouveau code, tout d'abord tu as diminué les boutons sans adapter le reste du programme. L'attente du relâchement du bouton, while (digitalRead(buttonPins[i]) == LOW) n'était pas à la bonne place.

Je te mets ton programme modifié, à toi de voir les différences :wink:

Le programme:

const int buttonPins[] = {2, 3, 4}; // Les pins des boutons
const int Led[] = {5, 6, 7, 8}; // Pins Led
const int relayPin = 9; // Le pin du relais

const int sequence[] = {0, 1, 0, 2, 0, 2}; // Séquence à suivre
const int sequenceLength = sizeof(sequence) / sizeof(sequence[0]);

int currentStep = 0;

void setup() {
	for (int i = 0; i < 3; i++) {
		pinMode(buttonPins[i], INPUT_PULLUP);
	}
	for (int j = 0; j < 4; j++){
		pinMode(Led[j], OUTPUT);
		digitalWrite(Led[j], LOW);
	}
	Serial.begin(9600);
	pinMode(relayPin, OUTPUT);
	digitalWrite(relayPin, LOW); // Assurez-vous que le relais est désactivé au début
}

void loop() {
	for (int i = 0; i < 3; i++) {
		if (digitalRead(buttonPins[i]) == LOW) {
			Serial.print("bouton");
			Serial.print(i);
			digitalWrite(Led[i], HIGH);
			while (digitalRead(buttonPins[i]) == LOW){}; // Attendez que le bouton soit relâché
			delay(200); // Anti-rebond
			if (i == sequence[currentStep]) {
				currentStep++;
				digitalWrite(Led[i], LOW);
				} else {
				currentStep = 0; // Réinitialiser la séquence si le mauvais bouton est pressé
			}
		}
	}

	if (currentStep == sequenceLength) {
		digitalWrite(relayPin, HIGH); // Activer le relais
		delay(5000); // Maintenir le relais activé pendant 5 secondes (par exemple)
		digitalWrite(relayPin, LOW); // Désactiver le relais
		currentStep = 0; // Réinitialiser la séquence
	}
}

Cordialement
jpbbricole

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.