Forcer une alternance entre l'utilisation de deux contacteurs

Bonjour, j'ai récupéré la responsabilité d'une activité utilisant un arduino léonardo pour piloter le passage de diapositives dans le logiciel Powerpoint. On utilise deux contacteurs pour détecter un passage et changer de diapo (il y a également des diodes lumineuses et un buzzer qui s'actionnent au contact) .
Actuellement on peut actionner le bouton A ou le bouton B indifféremment: un appui sur l'un ou l'autre fait passer la diapo (juste une temporisation de 2 secondes entre chaque appui). On peut actuellement appuyer deux fois sur le même bouton consécutivement.
Je voudrais faire évoluer le code en obligeant à une alternance de passage entre BtA et BtB (pas de double appui successif sur l'un ou l'autre).
Action BtA-> BtA bloqué -> Action BtB -> BtB bloqué -> Action BtB ......
Toutefois on doit pouvoir initier la séquence en commençant indifféremment par BtA ou BtB.
Comme je suis un jeune débutant en Arduino (70 ans), je fais appel à la communauté pour m'aider à progresser, car je découvre progressivement les fonctions et la programmation..
Voici le code actuel

[code]
#include "Keyboard.h"

const int buttonPin1 = 2;
const int buttonPin2 = 4;
int buttonState1 = 0;
int buttonState2 = 0;
int prevButtonState1 = LOW;
int prevButtonState2 = LOW;

void setup() {
  pinMode(buttonPin1, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
  digitalWrite(buttonPin1, LOW);
  digitalWrite(buttonPin2, LOW);
  pinMode(13, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(12, OUTPUT);
  Keyboard.begin();
}

void loop() {
  buttonState1 = digitalRead(buttonPin1);
  buttonState2 = digitalRead(buttonPin2);
  if ((buttonState1 != prevButtonState1) && (buttonState1 == HIGH)) {
    Keyboard.press('d');
    delay(100);
    Keyboard.releaseAll();
    digitalWrite(13, HIGH);
    digitalWrite(7, LOW);
    digitalWrite(12, HIGH);
    delay (500);
    digitalWrite(12, LOW);
    delay(1500);
  }
  else {
    digitalWrite(13, LOW);
    digitalWrite(7, HIGH);
  }

  if ((buttonState2 != prevButtonState2) && (buttonState2 == HIGH)) {
    Keyboard.press('d');
    delay(100);
    Keyboard.releaseAll();
    digitalWrite(8, HIGH);
    digitalWrite(7, LOW);
    digitalWrite(12, HIGH);
    delay (500);
    digitalWrite(12, LOW);
    delay(1500);
  }
  else {
    digitalWrite(8, LOW);
    digitalWrite(7, HIGH);
  }

  prevButtonState1 = buttonState1;
  prevButtonState2 = buttonState2;
}

Merci à tous

C’est typiquement une définition de programme qui se prête bien à la programmation par machine à états (cf mon tuto éventuellement)

pour simplifier votre gestion des boutons, éventuellement utilisez la librairie de @bricoleau ou alors la librairie OneButton de Matthias Hertel.

Bonjour,

Comme dit JML tu peux faire une machine d'état.
Ca me parait quand même un peu surdimensionné. Il suffit de mémoriser le dernier bouton enfoncé et de regarder si le bouton enfoncé est différent.


void loop() {
  static byte nButton=0;   // numéro du dernier bouton enfoncé (0: pas de bouton précédemment enfoncé)
  buttonState1 = digitalRead(buttonPin1);
  buttonState2 = digitalRead(buttonPin2);
  if (nButton!=1 && (buttonState1 != prevButtonState1) && (buttonState1 == HIGH)) {
    nButton=1;
    Keyboard.press('d');
    delay(100);
    Keyboard.releaseAll();
    digitalWrite(13, HIGH);
    digitalWrite(7, LOW);
    digitalWrite(12, HIGH);
    delay (500);
    digitalWrite(12, LOW);
    delay(1500);
  }
  else {
    digitalWrite(13, LOW);
    digitalWrite(7, HIGH);
  }

  if (nButton!=2 && (buttonState2 != prevButtonState2) && (buttonState2 == HIGH)) {
    nButton=2;
    Keyboard.press('d');
    delay(100);
    Keyboard.releaseAll();
    digitalWrite(8, HIGH);
    digitalWrite(7, LOW);
    digitalWrite(12, HIGH);
    delay (500);
    digitalWrite(12, LOW);
    delay(1500);
  }
  else {
    digitalWrite(8, LOW);
    digitalWrite(7, HIGH);
  }

  prevButtonState1 = buttonState1;
  prevButtonState2 = buttonState2;
}

Une petite remarque:
Tu as donné un nom à tes entrées, pourquoi tu n'as pas donné de nom à tes sorties? Ca rendrait quand même le programme plus lisible.

Merci de vos réponses. J'ai pris en compte vos conseils et retravaillé le programme.
Il fonctionne désormais selon mes souhaits. (jusqu'à une nouvelle envie de fonctionnalité, probablement une gestion du temps...)

#include "Keyboard.h"

const int buttonPin1 = 2; // premier contacteur electrique
const int buttonPin2 = 4; // second contacteur electrique
const int ledRed = 8; // led rouge
const int ledGreen = 13; // led verte
const int ledBlue = 7; // led bleue
const int buzzer = 12; // Buzzer actif
int buttonState1 = 0;
int buttonState2 = 0;
int prevButtonState1 = LOW;
int prevButtonState2 = LOW;

void setup() {
  pinMode(buttonPin1, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
  digitalWrite(buttonPin1, LOW);
  digitalWrite(buttonPin2, LOW);
  pinMode(ledGreen, OUTPUT);
  pinMode(ledBlue, OUTPUT);
  pinMode(ledRed, OUTPUT);
  pinMode(buzzer, OUTPUT);
  Keyboard.begin();
}

void loop() {
  static byte nButton = 0;
  buttonState1 = digitalRead(buttonPin1);
  buttonState2 = digitalRead(buttonPin2);
  if (nButton != 1 && (buttonState1 != prevButtonState1) && (buttonState1 == HIGH)) {
    nButton = 1;
    Keyboard.press('d');
    delay(100);
    Keyboard.releaseAll();
    digitalWrite(ledGreen, HIGH);
    digitalWrite(ledBlue, LOW);
    digitalWrite(ledRed, LOW);
    digitalWrite(buzzer, HIGH);
    delay (500);
    digitalWrite (buzzer, LOW);
    delay(1500);
  }
  else {
    digitalWrite (ledGreen, LOW);
    digitalWrite(ledBlue, HIGH);
  }

  if (nButton != 2 && (buttonState2 != prevButtonState2) && (buttonState2 == HIGH)) {
    nButton = 2;
    Keyboard.press('d');
    delay(100);
    Keyboard.releaseAll();
    digitalWrite(ledRed, HIGH);
    digitalWrite(ledBlue, LOW);
    digitalWrite(ledGreen, LOW);
    digitalWrite(buzzer, HIGH);
    delay (500);
    digitalWrite (buzzer, LOW);
    delay(15ddddd00);
  }
  else {
    digitalWrite (ledRed, LOW);
    digitalWrite(ledBlue, HIGH);
  }

  prevButtonState1 = buttonState1;
  prevButtonState2 = buttonState2;
}

Une demande de précision: pour réinitialiser la possibilité de démarrer par le Bt1 ou le Bt2, le mieux est d'utiliser le port "Reset" avec un bouton?

Oui, tu peux faire un reset, ça demande un bouton supplémentaire si tu trouves que le bouton reset de la carte n'est pas pratique..
Tu pourrais envisager autre chose:

  • soit tu appuies longuement sur un bouton
  • soit tu appuies sur les deux boutons en même temps
  • soit tu appuies 5 fois de suite sur le même bouton
  • ...

Une variable et hop c’est l’état de la machine :slight_smile:

Je reviens avec une autre question: Mes deux entrées ButtonPin1 et ButtonPin2 sont reliées à des contacteurs éloignés, avec une longueur de fil de 4 à 5 mètres. Dans un cas comme cela, faut il mieux mettre une résistance PullUp par la programmation, ou créer une résistance PullDown avec une résistance?
Dans mon cas ces deux contacteurs commandent le passage d'une diapositive Powerpoint avec le clavier virtuel (lettre "s") et j'ai parfois des déclenchements fantômes. Merci

Si tu soupçonnes des perturbations sur les boutons, tu peux mettre une résistance de pullup externe (tu peux descendre jusqu'à 1k) et éventuellement mettre un condensateur de 100nF aux bornes des boutons.