[Partage] Boutons Poussoirs

Super librairie, merci Bricolo ! J'en ai utilisé plusieurs solutions, et gros gain de temps et de fiabilité, lisibilité et tout et tout ! J'ai apporté une petite modif sur l'exemple 10: Gestion d'un compteur avec un bouton + et un bouton - et répétition progressive en cas d'appui long.

j'ai ajouté une possiblité d'incrément par 1, ou 5 ou 10 pour augmenter encore la vitesse. l'incrémenteur, boostCompteur à déclarer en byte en public. le lignes que j'ai ajoutées sont marquées par "//************************" pour plus de visibilité.

//Exemple librairie simpleBouton.h
//Gestion d'un compteur avec un bouton + et un bouton -
//et répétition progressive en cas d'appui long

#include "simpleBouton.h"

simpleBouton bouton_plus(7);
simpleBouton bouton_moins(8);
//Cablage : pin---BP---GND

int compteur = 0;

void setup()
{
  Serial.begin(115200);
  Serial.println(compteur);
}

uint32_t delai;
bool blocage = false;

void loop()
{
  bouton_plus.actualiser();
  bouton_moins.actualiser();
  
  if (bouton_plus.vientDEtreEnfonce() || bouton_moins.vientDEtreEnfonce()) delai = 0;

  //Gestion du petit malin qui appuie sur les deux boutons en même temps
  if (bouton_plus.estEnfonce() && bouton_moins.estEnfonce()) blocage = true;
  if (bouton_plus.estRelache() && bouton_moins.estRelache()) blocage = false;
  if (blocage) return;
   
  if (bouton_plus.estEnfonceDepuisAuMoins(delai))  {
    Compteur += boostCompteur ; //************************
    //Serial.println(Compteur);
    delai = delai + delaiRepetition(bouton_plus.dureeEtatActuel());
  }

  if (bouton_moins.estEnfonceDepuisAuMoins(delai))  {
    Compteur -= boostCompteur ; //************************
    //Serial.println(Compteur);
    delai = delai + delaiRepetition(bouton_moins.dureeEtatActuel());
  }
}

uint32_t delaiRepetition(uint32_t duree){ //Exemple de cadence progressive
  if (duree <  500) {
    boostCompteur =1; //************************
    return 300;
  }
  if (duree <  2000) {
    boostCompteur =5; //************************
    return 150;
  }
  if (duree <  3000){
    boostCompteur =10;  //************************
    return 100;}
  return 10;  // 10ms de cadence
}

achess: // peut être modifié, l'essentiel est que le mot "Clic" soit présent

Le mot clic ??? Mais non...

Le nom de fonction n’a aucun impact, ces noms disparaissent à la compilation

Bonjour moi c'est Thomas je suis un "nul" d'arduino je ne sais pas si je poste ma question au bon endroit mais bon...

J'essaie d'occuper le garçon de ma compagne avec Arduino nous essayons de créer un feu tricolore avec feu piéton et bouton poussoir "piéton" cela fonctionne bien avec ce code trouvé sur le net un peu modifié mais il faut rester appuyer sur le BP jusqu'à ce que la boucle soit terminée pour quelle prenne en compte l'appui. Nous souhaiterions pouvoir faire une simple impulsion sur ce dernier et qu le programme passe directement au "feu orange" puis "feu rouge" et ensuite reprenne le fonctionnement normal.

merci pour votre aide.

// Constantes et variables pour le feu tricolore
const int ledRouge = 12;
const int ledOrange = 11;
const int ledVerte = 10;

// Constantes et variables pour le feu piéton
const int ledRouge_pieton = 9;
const int ledVerte_pieton = 8;

// Constante et variables pour le bouton poussoir
const int bouton = 2;
int etatBouton = 0;

void setup() {
pinMode (ledRouge, OUTPUT);
pinMode (ledOrange, OUTPUT);
pinMode (ledVerte, OUTPUT);

pinMode (ledRouge_pieton, OUTPUT);
pinMode (ledVerte_pieton, OUTPUT);

pinMode (bouton, INPUT);

}

void loop() {

etatBouton = digitalRead (bouton);
delay(100);

if (etatBouton == HIGH) {
  digitalWrite (ledRouge, LOW);
  digitalWrite (ledOrange, HIGH);
  digitalWrite (ledVerte, LOW);
  delay(3000);

  digitalWrite (ledRouge, HIGH);
  digitalWrite (ledOrange, LOW);

  digitalWrite (ledRouge_pieton, LOW);
  digitalWrite (ledVerte_pieton, HIGH);
  delay(15000);

  digitalWrite (ledRouge_pieton, HIGH);
  digitalWrite (ledVerte_pieton, LOW);

  digitalWrite (ledRouge, LOW);
  digitalWrite (ledVerte, HIGH);
  delay(10000);
  digitalWrite (ledVerte, LOW);  
}
else {
  digitalWrite (ledRouge_pieton, HIGH);
  digitalWrite (ledVerte_pieton, LOW);

  digitalWrite (ledOrange, HIGH);
  delay(3000);
  
  digitalWrite (ledOrange, LOW);
  digitalWrite (ledRouge, HIGH);
  digitalWrite (ledRouge_pieton, LOW);
  digitalWrite (ledVerte_pieton, HIGH);
  delay(10000);
  digitalWrite (ledRouge_pieton, HIGH);
  digitalWrite (ledVerte_pieton, LOW);
  delay(5000);

  digitalWrite (ledRouge, LOW);
  digitalWrite (ledVerte, HIGH);
  delay(10000);
  digitalWrite (ledVerte, LOW);
}
  
}

Auriez-vous une solution ?

Thomas et Mylan

Bonjour Thomas et Mylan

Ton post est mal placé, demande a un modérateur de déplacer ton message en cliquant sur "Report to moderator" en bas de ton msg

Le problème vient de tes "delay" qui bloquent la boucle,

La solution serait d'utiliser la fonction millis() : voir ici exemple utilisation de millis()

Et de le coupler avec la machine a état de J-M-L

Mise en ligne aujourd'hui d'une nouvelle version mineure

V4.2 du 07/08/2020

Suppression du warning parasite lors de la compilation

Vous voulez pas la publier dans github et la déclarer dans les bibliothèques? Ça permettrait les màj automatiques

ok je vais voir ça :)

Merci beaucoup pour le partage de cette librairie. Votre post m’a beaucoup aidé.
Karma+ :slight_smile:

Bonjour Bricoleau.

Tout d’abord un énorme merci pour vos librairies et tutoriels. Ça aide vraiment !

Deux petites questions :

-Je n’arrive pas à faire une action si deux boutons sont appuyés en même temps.
(ou si pendant que le premier est appuyé on appui sur le second)
pourtant, sur l’exemple “2 boutons”, si on maintient le 1er bouton appuyé et que l’on joue avec le second, ses états apparaissent bien dans la console…

ce que je cherche :

appui bouton1–>action 1
appui bouton2–>action 2
appui bouton1 et bouton2–>action 3

Désolé si cela a déjà été répondu, je n’ai pas trouvé…

  • 2eme question: vous présentez cette librairie comme une librairie “pour débutant”, mais elle semble si performante que je me demande comment font alors les “non-débutants” ? Qu’elles en sont les limitations qui refroidiraient quelqu’un de plus aguerri ?

Encore merci !

Julien

..voici ce que j'ai tenté... ..qu'elle est mon erreur (de débutant..=) ?

J'imagine que, si cela fonctionnait, qu'il faudrait rajouter une sorte de delai quelque part (comme pour un double clic) pour que l'appui des 2 boutons en même temps n'envoie pas l'action associée à chaque bouton seul. Mais comment ?

//Exemple librairie simpleBouton.h
//Affichage de l'état de deux boutons
#include "simpleBouton.h"

simpleBouton bouton1(2);
simpleBouton bouton2(4);
int pinLed = 3;
//Cablage : pin---BP---GND

void setup()
{
  Serial.begin(115200);
  pinMode(3, OUTPUT);
}

void loop()
{
  bouton1.actualiser();
  bouton2.actualiser();


  if ((bouton1.vientDEtreEnfonce()) && (bouton2.vientDEtreEnfonce()))
  {digitalWrite(pinLed, HIGH);}
  else
  {digitalWrite(pinLed, LOW);}
}

schlam:
…voici ce que j’ai tenté…
…qu’elle est mon erreur (de débutant…=) ?

l’appui des 2 boutons ne va pas être exactement simultané et votre arduino pédale vite, vous risquez donc de voir appui sur bouton 1 puis appui sur bouton 2 au prochain tour de loop et traiter cela comme des appuis simples.

il faut faire une machine à état plus poussée (cf mon tuto éventuellement)

cette discussion serait mieux dans le forum principal car elle concerne un projet particulier plutôt que la bibliothèque en elle même.

Merci de votre réponse. je fonce voir voir tuto !

schlam: Merci de votre réponse. je fonce voir voir tuto !

la machine à état devrait ressembler à cela:

je vous laisse essayer de coder en appliquant le tuto

machine.png|1986x994

Les boutons poussoir, ça a l'air tout bête au départ, et pourtant...

Avant même de parler lignes de code, peu importe la bibliothèque utilisée, il faut se poser deux secondes pour réfléchir à ton besoin.

schlam: ce que je cherche :

appui bouton1-->action 1 appui bouton2-->action 2 appui bouton1 et bouton2-->action 3

Cette description est trop... humaine et naïve ! :)

L'arduino détecte un appui bouton avec une précision temporelle de quelques microsecondes.

Es-tu vraiment en mesure d'appuyer sur les deux boutons "simultanément", c'est-à-dire en moins de quelques millionièmes de secondes ? Si oui, tu dois être à ranger dans la catégorie cyborg et non, je ne m'appelle pas Sarah Connor :)

Bref tout ça pour confirmer ce qu'indique JML : il faut introduire une notion de délai maximum entre les appuis sur les deux boutons. Délai à ajuster selon les capacité psychomotrices du "pousseur"...

Prenons par exemple 1/2 seconde. Cela veut dire que quand l'arduino détecte un appui bouton, il doit attendre 500 ms pour savoir si l'autre bouton est enfoncé, et décider de quelle action lancer.

C'est là que l'on commence à prendre une feuille blanche, faire des patatoïdes pour réfléchir à l'état du système à un instant t.

Jusqu'à répondre à des questions auxquelles tu n'avais pas pensé au départ.

Par exemple : que doit-il se passer en cas de double clic sur le bouton1 immédiatement suivi d'un clic sur le bouton2? Faut-il agir comme s'il n'y avait qu'un appui simultané BP1 & BP2 ? Ou bien faut-il enchaîner une action BP1 seul et une action BP1 & BP2 ? Et dans ce cas, l'action BP1 seul est déclenchée quand ? :smiling_imp:

Un karma de plus pour te remercier, du beau boulot ! :)

Merci beaucoup pour cette librairie.

Il y a un mois, je n'avais jamais vu une carte arduino et à 72 ans pas facile de s'y mettre.

J'aimerais utiliser cette librairie pour gérer 8 boutons.... plutôt que de définir 8 fois un bouton, est-ce qu'il ne serait pas plus aisé de permettre l'indicage.

Je vais regarder votre travail dans la journée

Cordialement

Philippe

philguen: J'aimerais utiliser cette librairie pour gérer 8 boutons.... plutôt que de définir 8 fois un bouton, est-ce qu'il ne serait pas plus aisé de permettre l'indicage.

Bonjour Philippe, bravo pour l’énergie investie - il n’y a pas d’âge pour commencer ;)

Concernant votre question, vous pouvez créer un tableau de SimpleBouton et ça vous donnera “l’indiçage” dont vous parlez.

Par exemple ici un tableau de 4 boutons connectés respectivement sur les pins 3,4,7 et 11

simpleBouton mesBoutons[] = {{3}, {4}, {7}, {11}};

rien de plus simple ... c'est parfait ... je vais commencer à apprence ca cet après-midi

Un énorme merci pour cette réponse pleine de courtoisie et trè réactive.

Je ne manquerai pas de faire appel à vos connaissances

Bonne fin de journée

Philippe

philguen: rien de plus simple ... c'est parfait ... je vais commencer à apprence ca cet après-midi

voici un petit bout de code pour commencer:

#include 
simpleBouton mesBoutons[] = {{3}, {4}, {7}, {11}};
const byte nombreDeBoutons = sizeof mesBoutons / sizeof mesBoutons[0];

void setup() {
  Serial.begin(115200);
}

void loop() {
  for (byte indiceBouton = 0; indiceBouton < nombreDeBoutons; indiceBouton++) {
    mesBoutons[indiceBouton].actualiser();    // on met à jour ce bouton
    if (mesBoutons[indiceBouton].vientDEtreEnfonce()) { // on teste l'appui
      Serial.print(F("APPUI   BOUTON: "));
      Serial.println(indiceBouton);
    }
    if (mesBoutons[indiceBouton].vientDEtreRelache()) { // on teste le relâchement
      Serial.print(F("RELACHE BOUTON: "));
      Serial.println(indiceBouton);
    }
  }
}

le moniteur série (ouvert à 115200 bauds) affichera les appuis et relâches des boutons avec leur indice

grand merci