Besoin d'aide pour un débutant sur bouton asynchronisé

Bonjour à tous,
Je suis nouveau sur le forum et également nouveau dans le monde de l’Arduino et de du code (ça commence bien!!!).
J’ai un projet personnel et ai un besoin de coder un arduino Uno pour celui-ci, mon problème réside en mes capacités à coder, je bloque très rapidement.
Mon projet consiste a obtenir un comportement spécifique des directions sur une manette avec 4 directions.
Je recherche principalement à résoudre le comportement des directions gauche et droite.
Je recherche à obtenir le comportement suivant:
Quand j’appuie sur la direction gauche, seul la direction gauche doit apparaitre en sortie
Quand j’appuie sur la direction droite seule la directions droite doit apparaitre en sortie.
Jusque la tout va bien.

C’est la partie suivante qui me pose problème:
Quand le bouton gauche est appuyé et que je presse par la suite le droit, je souhaite que la direction droite prenne la priorité et que la gauche soit éteinte.
et
quand le bouton droit est appuyé et que je presse par la suite le gauche, je souhaite que la direction gauche prenne la priorité et que le droit soit éteint.

Je n’arrive pas a trouver de solution pour les deux éléments ci-dessus par méconnaissance de la programmation.
Est ce que quelqu’un saurait me venir en aide?

//Controller button pins
const uint8_t leftIN = 9;
const uint8_t rightIN = 10;
const uint8_t upIN = 11;
const uint8_t downIN = 12;
const uint8_t switchIN = 3;

//Output to other PCB pins
const uint8_t leftOUT = 6;
const uint8_t rightOUT = 8;
const uint8_t upOUT = 5;
const uint8_t downOUT = 7;

uint8_t leftRead;
uint8_t downRead;
uint8_t upRead;
uint8_t rightRead;
uint8_t switchRead;

void setup() {
pinMode(leftIN, INPUT_PULLUP);
pinMode(rightIN, INPUT_PULLUP);
pinMode(upIN, INPUT_PULLUP);
pinMode(downIN, INPUT_PULLUP);
pinMode(leftOUT, OUTPUT);
pinMode(rightOUT, OUTPUT);
pinMode(downOUT, OUTPUT);
pinMode(upOUT, OUTPUT);
}

void loop() {
leftRead = digitalRead(leftIN);
rightRead = digitalRead(rightIN);
upRead = digitalRead(upIN);
downRead = digitalRead(downIN);
switchRead = digitalRead(switchIN);

//Horizontal inputs charge mode
if (leftRead == LOW)// Comportement bouton Gauche
{
digitalWrite(leftOUT, LOW);
digitalWrite(rightOUT, HIGH);
}
else
{
digitalWrite(leftOUT, HIGH);
digitalWrite(rightOUT, HIGH);
}

if (rightRead == LOW)// Comportement bouton Droit
digitalWrite(rightOUT, LOW);
else
digitalWrite(rightOUT, HIGH);

//Vertical inputs block
if (upRead == LOW) // Up overrides down inputs
{
digitalWrite(downOUT, HIGH);
digitalWrite(upOUT, LOW);
}
else if (downRead == LOW) // Down only
{
{
digitalWrite(downOUT, LOW);
digitalWrite(upOUT, HIGH);
}
}
else // No vertical inputs
{
digitalWrite(upOUT, HIGH);
digitalWrite(downOUT, HIGH);
}
}

Déjà, tu as oublié de déclarer le bouton switchIN:
pinMode(switchIN, INPUT_PULLUP);

Le plus simple serait de faire une petite machine à états. Tu déclares des variables booléennes qui contiennent chacun l’état d’une led. Selon les boutons appuyés et l’état courant tu ajustes ces états.

Lorsque tout est ajusté, tu fais les digitalWrite.

Par exemple, si tu as déclaré

bool etatLedLeft = LOW;

tu fais le test comme tu veux :

if (leftRead == LOW && etatLedLeft == LOW) {
    etatLedLeft = HIGH;
    etatLedRight = LOW;
 }

Pense à ajouter un petit temps d’attente des rebonds des boutons après leur lecture:

delay(30);

Merci pour ta réponse, je ne connais pas encore la machine a état ni les variables booléennes, je vais essayer de me renseigner sur ces deux aspects faire des tests et en cas d’échecs je me permettrai de revenir vers toi.

Bonne soirée.

Je suis désolé mais je crois que mes connaissances sont vraiment trop faible pour comprendre ou appliquer ce que tu viens de me conseiller. il n’existe pas de fonctions qui permettent de prendre en compte la hiérarchie dans l’appuie des boutons pour enfin y appliquer le résultat voulu?

Non je ne crois pas.

J’ai du mal à comprendre ce que tu veux faire ici :

Est-ce que tu appuies sur le gauche, puis le relâches pour ensuite appuyer sur le droit ?
Si oui, tu peux faire comme je te suggère. Je peux t’aider.

Si non, il faut m’expliquer un peu mieux…

En faite je cherche à avoir 4 comportements bien distinct pour les touches gauches et droites:

1 quand la gauche est la seule enfoncée, la sortie gauche est active

2 quand la droite est la seule enfoncée, la sortie droite est active

3 quand la gauche est enfoncée et que j’appuie sur la droite (la touche gauche reste enfoncée), seule la sortie droite est active.

4 quand la droite est enfoncée et que j’appuie sur la gauche (la touche droite reste enfoncée), seule la touche gauche est active.

Merci encore pour ton aide.

Désolé pour les explications du départ, j’éspere que celle-ci seront plus claire

J’ ai essaye de coder la partie ce-dessous, je me rend bien compte qu il y a des incohérences, le comportement des sorties est anarchiques mais c est plus pour clarifier les idées ci dessus.

if ((leftRead == LOW) && (rightRead == HIGH))

{
if (rightRead == LOW)
{
digitalWrite(leftOUT, HIGH);
digitalWrite(rightOUT, LOW);
}
else
{
digitalWrite(leftOUT, LOW);
digitalWrite(rightOUT, HIGH);
}
}

if ((leftRead == HIGH) && (rightRead == LOW))

{
if (leftRead == LOW)
{
digitalWrite(leftOUT, LOW);
digitalWrite(rightOUT, HIGH);
}
else
{
digitalWrite(leftOUT, HIGH);
digitalWrite(rightOUT, LOW);
}
}

Pour gérer ton problème, il faut tenir compte du changement d’état des boutons et non de leur état courant.

  • à l’initialisation, tous les boutons sont considérés inactifs et tu sauvegarde cet état dans une variable
  • dans loop,
    • tu lis l’état des boutons
    • si tu vois un changement par rapport à l’état mémorisé précédemment tu exécutes la fonction associée.
    • tu mémorises ce nouvel état et tu continues

Bonjour et merci pour votre réponse.

Pourriez vous l indiquer le nom des fonctions que je puisse faire des recherches ?

Vous parlez de la fonctions while?

Bonsoir, est ce type de code que vous suggérez?

{
if((leftRead == HIGH) && (rightRead == HIGH))
{
digitalWrite(leftOUT, HIGH);
digitalWrite(rightOUT, HIGH);
}
while(leftRead == LOW)
{
if(rightRead == LOW)
{
digitalWrite(leftOUT, HIGH);
digitalWrite(rightOUT, LOW);
}
else
{
digitalWrite(leftOUT, LOW);
digitalWrite(rightOUT, HIGH);
}
}
while(rightRead == LOW)
{
if(leftRead == LOW)
{
digitalWrite(leftOUT, LOW);
digitalWrite(rightOUT, HIGH);
}
else
{
digitalWrite(leftOUT, HIGH);
digitalWrite(rightOUT, LOW);
}
}

}

Voici ce que je propose :

//Controller button pins
const uint8_t leftIN = 9;
const uint8_t rightIN = 10;
const uint8_t upIN = 11;
const uint8_t downIN = 12;
const uint8_t switchIN = 3;

//Output to other PCB pins
const uint8_t leftOUT = 6;
const uint8_t rightOUT = 8;
const uint8_t upOUT = 5;
const uint8_t downOUT = 7;

// état des boutons
uint8_t leftRead = LOW;
uint8_t downRead = LOW;
uint8_t upRead = LOW;
uint8_t rightRead = LOW;

// état précédent
uint8_t leftReadPrec = LOW;
uint8_t downReadPrec = LOW;
uint8_t upReadPrec = LOW;
uint8_t rightReadPrec = LOW;
uint8_t switchRead;

bool etatLedLeft = LOW;
bool etatLedRight = LOW;
bool etatLedDown = LOW;
bool etatLedLeftUp = LOW;

void setup(){
	Serial.begin(9600);

	pinMode(leftIN, INPUT_PULLUP);
	pinMode(rightIN, INPUT_PULLUP);
	pinMode(upIN, INPUT_PULLUP);
	pinMode(downIN, INPUT_PULLUP);
	pinMode(switchIN, INPUT_PULLUP);

	pinMode(leftOUT, OUTPUT);
	pinMode(rightOUT, OUTPUT);
	pinMode(downOUT, OUTPUT);
	pinMode(upOUT, OUTPUT);
}

void loop(){
	leftRead   = digitalRead(leftIN);
	rightRead  = digitalRead(rightIN);
	upRead     = digitalRead(upIN);
	downRead   = digitalRead(downIN);
	switchRead = digitalRead(switchIN);

// 1 quand la gauche est la seule enfoncée, la sortie gauche est active
	if (leftRead == LOW && rightRead == HIGH) {
		etatLedLeft = HIGH;
	}

// 2 quand la droite est la seule enfoncée, la sortie droite est active
	if (leftRead == HIGH && rightRead == LOW) {
		etatLedLefRight = HIGH;
	}

// 3 quand la gauche est enfoncée et que j’appuie sur la droite (la touche gauche reste enfoncée), seule la sortie droite est active.
	if (leftRead == LOW && rightRead == LOW && rightReadPrec == HIGH) {
		etatLedLeft = LOW;
		etatLedLefRight = HIGH;		
	}

// 4 quand la droite est enfoncée et que j’appuie sur la gauche (la touche droite reste enfoncée), seule la touche gauche est active.
	if (rightRead == LOW && leftRead == LOW && leftReadPrec == HIGH) {
		etatLedLeft = HIGH;
		etatLedLefRight = LOW;		
	}

	leftReadPrec  = leftRead;
	rightReadPrec  = rightRead;
	upReadPrec    = upRead;
	downReadPrec = downRead;

	digitalWrite(leftOUT, etatLedLeft);
	digitalWrite(rightOUT, etatLedRight);
	digitalWrite(downOUT, etatLedDown);
	digitalWrite(upOUT, etatLedUp);
}

Je n’ai pas testé, je ne sais pas si ça fera ce que tu veux.
Ton explication est incomplète :

Dans ce cas, qu’en est-il de la droite ? Dans mon code, je la laisse inchangée.

Merci beaucoup pour cette précieuse aide, je vais tester demain le montage.

En faite en considérant les deux direction gauche et droite, quand le seul bouton gauche est enfoncé j’attend que la sortie gauche soit la seule active

Alors il faut ajouter
etatLedLefRight = LOW;
dans le if, et de même pour le if suivant

Bonjour,

Merci encore pour ton aide.

Pour t’aider dans la compréhension de mon besoin je recherche à reproduire le comportement du joystick dans cette vidéo donc deux modes différents pour la gestion horizontal.

L’objectif est de mettre l’arduino entre la partie commande et le pcb du joystick avec le bout switch faisant basculer le fonction du shoto mode au charge mode.
Pour la gestion du shoto mode j’ai déjà réussi a gérer le fonctionnement mais c’est cette partie désynchronisation des directions qui me pose toujours problème.

En testant le programme que tu m’as envoyé toutes les LED sont allumées au démarrage (j’utilise des LED connectés vers le 5V pour simuler le PCB) et il n’y a pas de réactions lors de l’appuie sur les boutons.

Voici ci-dessous mon programme complet avec la bascule entre les deux modes avec le boutons switch. Peu être qu’une vision d’ensemble du projet sera plus parlante.

sketch_apr16a.ino (2.3 KB)

//Controller button pins
const uint8_t leftIN = 9;
const uint8_t rightIN = 10;
const uint8_t upIN = 11;
const uint8_t downIN = 12;
const uint8_t switchIN = 3;

//Output to other PCB pins
const uint8_t leftOUT = 6;
const uint8_t rightOUT = 8;
const uint8_t upOUT = 5;
const uint8_t downOUT = 7;

uint8_t leftRead;
uint8_t downRead;
uint8_t upRead;
uint8_t rightRead;
uint8_t switchRead;

void setup() {
pinMode(leftIN, INPUT_PULLUP);
pinMode(rightIN, INPUT_PULLUP);
pinMode(upIN, INPUT_PULLUP);
pinMode(downIN, INPUT_PULLUP);
pinMode(leftOUT, OUTPUT);
pinMode(rightOUT, OUTPUT);
pinMode(downOUT, OUTPUT);
pinMode(upOUT, OUTPUT);
pinMode(switchIN, INPUT_PULLUP);
}

void loop() {
leftRead = digitalRead(leftIN);
rightRead = digitalRead(rightIN);
upRead = digitalRead(upIN);
downRead = digitalRead(downIN);
switchRead = digitalRead(switchIN);

if (switchRead == LOW) // shoto mode
{

//Horizontal inputs block shoto mode
if (leftRead == LOW)
{
if (rightRead == HIGH) //Left only
{
digitalWrite(rightOUT, HIGH);
digitalWrite(leftOUT, LOW);
}
else //Right+Left = Neutral
{
digitalWrite(rightOUT, HIGH);
digitalWrite(leftOUT, HIGH);
}
}
else if (rightRead == LOW) //Right only
{
digitalWrite(leftOUT, HIGH);
digitalWrite(rightOUT, LOW);
}
else // No horizontal inputs
{
digitalWrite(rightOUT, HIGH);
digitalWrite(leftOUT, HIGH);
}
}
//CHARGE MODE***
else
{
if (leftRead == LOW)// Comportement bouton Gauche
{
digitalWrite(leftOUT, LOW);
digitalWrite(rightOUT, HIGH);
}
else
{
digitalWrite(leftOUT, HIGH);
digitalWrite(rightOUT, HIGH);
}

if (rightRead == LOW)// Comportement bouton Droit
digitalWrite(rightOUT, LOW);
else
digitalWrite(rightOUT, HIGH);
}

//Vertical inputs block

if (upRead == LOW) // Up overrides down inputs
{
digitalWrite(downOUT, HIGH);
digitalWrite(upOUT, LOW);
}
else if (downRead == LOW) // Down only
{
{
digitalWrite(downOUT, LOW);
digitalWrite(upOUT, HIGH);
}
}
else // No vertical inputs
{
digitalWrite(upOUT, HIGH);
digitalWrite(downOUT, HIGH);
}
}

//Controller button pins
const uint8_t leftIN = 9;
const uint8_t rightIN = 10;

//Output to other PCB pins
const uint8_t leftOUT = 6;
const uint8_t rightOUT = 8;

// état des boutons
uint8_t leftRead = LOW;
uint8_t rightRead = LOW;

// état précédent
uint8_t leftReadPrec = LOW;
uint8_t rightReadPrec = LOW;

bool etatLedLeft = LOW;
bool etatLedRight = LOW;

void setup(){
Serial.begin(9600);

pinMode(leftIN, INPUT_PULLUP);
pinMode(rightIN, INPUT_PULLUP);

pinMode(leftOUT, OUTPUT);
pinMode(rightOUT, OUTPUT);

}

void loop(){
leftRead = digitalRead(leftIN);
rightRead = digitalRead(rightIN);

// 0 quand la gauche et droite ne sont pas enfoncées
if (leftRead == HIGH && rightRead == HIGH) {
etatLedLeft = HIGH;
etatLedRight = HIGH;
}

// 1 quand la gauche est la seule enfoncée, la sortie gauche est active
if (leftRead == LOW && rightRead == HIGH) {
etatLedLeft = LOW;
etatLedRight = HIGH;
}

// 2 quand la droite est la seule enfoncée, la sortie droite est active
if (leftRead == HIGH && rightRead == LOW) {
etatLedLeft = HIGH;
etatLedRight = LOW;
}

// 3 quand la gauche est enfoncée et que j’appuie sur la droite (la touche gauche reste enfoncée), seule la sortie droite est active.
if (leftRead == LOW && rightRead == LOW && rightReadPrec == HIGH) {
etatLedLeft = HIGH;
etatLedRight = LOW;
}

// 4 quand la droite est enfoncée et que j’appuie sur la gauche (la touche droite reste enfoncée), seule la touche gauche est active.
if (rightRead == LOW && leftRead == LOW && leftReadPrec == HIGH) {
etatLedLeft = LOW;
etatLedRight = HIGH;
}

leftReadPrec  = leftRead;
rightReadPrec  = rightRead;


digitalWrite(leftOUT, etatLedLeft);
digitalWrite(rightOUT, etatLedRight);

}
J’ai modifié le code comme ci-dessus et cela fonctionne à merveille
Merci beaucoup pour votre aide.

Cool :sunglasses:

//Boutons du contrôleur vers Arduino
const uint8_t leftIN = 2;
const uint8_t rightIN = 4;
const uint8_t upIN = 5;
const uint8_t downIN = 3;
const uint8_t switchIN = 7;

//Arduino vers PCB
const uint8_t leftOUT = 11;
const uint8_t rightOUT = 12;
const uint8_t upOUT = 10;
const uint8_t downOUT = 9;

// état des boutons
uint8_t leftRead = LOW;
uint8_t rightRead = LOW;

// état précédent
uint8_t leftReadPrec = LOW;
uint8_t rightReadPrec = LOW;

bool etatLedLeft = LOW;
bool etatLedRight = LOW;

uint8_t downRead;
uint8_t upRead;
uint8_t switchRead;

void setup() {
Serial.begin(9600);

pinMode(leftIN, INPUT_PULLUP);
pinMode(rightIN, INPUT_PULLUP);
pinMode(upIN, INPUT_PULLUP);
pinMode(downIN, INPUT_PULLUP);
pinMode(leftOUT, OUTPUT);
pinMode(rightOUT, OUTPUT);
pinMode(downOUT, OUTPUT);
pinMode(upOUT, OUTPUT);
pinMode(switchIN, INPUT_PULLUP);
}

void loop() {
leftRead = digitalRead(leftIN);
rightRead = digitalRead(rightIN);
upRead = digitalRead(upIN);
downRead = digitalRead(downIN);
switchRead = digitalRead(switchIN);

if (switchRead == LOW) // shoto mode
{

//Horizontal inputs block shoto mode
if (leftRead == LOW)
{
if (rightRead == HIGH) //Left only
{
digitalWrite(rightOUT, HIGH);
digitalWrite(leftOUT, LOW);
}
else //Right+Left = Neutral
{
digitalWrite(rightOUT, HIGH);
digitalWrite(leftOUT, HIGH);
}
}
else if (rightRead == LOW) //Right only
{
digitalWrite(leftOUT, HIGH);
digitalWrite(rightOUT, LOW);
}
else // No horizontal inputs
{
digitalWrite(rightOUT, HIGH);
digitalWrite(leftOUT, HIGH);
}
}
//CHARGE MODE***
else
{
// 0 quand la gauche et droite ne sont pas enfoncées
if (leftRead == HIGH && rightRead == HIGH) {
etatLedLeft = HIGH;
etatLedRight = HIGH;
}

// 1 quand la gauche est la seule enfoncée, la sortie gauche est active
if (leftRead == LOW && rightRead == HIGH) {
etatLedLeft = LOW;
etatLedRight = HIGH;
}

// 2 quand la droite est la seule enfoncée, la sortie droite est active
if (leftRead == HIGH && rightRead == LOW) {
etatLedLeft = HIGH;
etatLedRight = LOW;
}

// 3 quand la gauche est enfoncée et que j’appuie sur la droite (la touche gauche reste enfoncée), seule la sortie droite est active.
if (leftRead == LOW && rightRead == LOW && rightReadPrec == HIGH) {
etatLedLeft = HIGH;
etatLedRight = LOW;
}

// 4 quand la droite est enfoncée et que j’appuie sur la gauche (la touche droite reste enfoncée), seule la touche gauche est active.
if (rightRead == LOW && leftRead == LOW && leftReadPrec == HIGH) {
etatLedLeft = LOW;
etatLedRight = HIGH;
}
}

//Vertical inputs block

if (upRead == LOW) // Up overrides down inputs
{
digitalWrite(downOUT, HIGH);
digitalWrite(upOUT, LOW);
}
else if (downRead == LOW) // Down only
{
{
digitalWrite(downOUT, LOW);
digitalWrite(upOUT, HIGH);
}
}
else // No vertical inputs
{
digitalWrite(upOUT, HIGH);
digitalWrite(downOUT, HIGH);
}
leftReadPrec = leftRead;
rightReadPrec = rightRead;

digitalWrite(leftOUT, etatLedLeft);
digitalWrite(rightOUT, etatLedRight);
}

Bonsoir,

Je me permets de revenir vers toi car après avoir acquis et monté le matériel je rencontre un problème.

Déjà tu trouveras ci-dessus le programme définitif .

Quand le bouton switch n’est pas appuyé tout fonctionne à merveille (tu reconnaitras la partie que tu m’as donné) mais lorsque le boutton Switch est appuyé les directions se comportent comme si j’appuyais à répétition dessus plutôt que comme si je laissais appuyé dessus.

Aurais tu une idée d’où peu venir le problème?