Bibliothèque OneButton ( état de plusieurs boutons )

Bonjour à tous,

Je gère quatre boutons qui ont chacun une fonction distincte , j'aimerais une fois rentré dans la fonction dédiée suite à un clic avoir l'état de mon bouton et pouvoir créer une condition relative à l'état du bouton.

L'état int state() du bouton est passé de 0 à 1 mais pendant combien de temps ? ( jusqu’à le clic d'un autre bouton ? )

J'ai fais un mini exemple fictif pour avoir juste le principe de fonctionnement :

#include "OneButton.h"

OneButton boutonUn;  
OneButton boutonDeux;
OneButton boutonTrois;
OneButton boutonQuatre;

void setup() {

  boutonUn.setup(2, INPUT);
  boutonDeux.setup(3, INPUT);
  boutonTrois.setup(4, INPUT);
  boutonQuatre.setup(5, INPUT);

  boutonUn.attachClick(simpleClickBoutonUn);
  boutonDeux.attachClick(simpleClickBoutonDeux);
  boutonTrois.attachClick(simpleClickBoutonTrois);
  boutonQuatre.attachClick(simpleClickBoutonQuatre);
  
}

void loop() {
  
  boutonUn.tick();
  boutonDeux.tick();
  boutonTrois.tick();
  boutonQuatre.tick();
  
}

void simpleClickBoutonUn() {

  // gère différentes tâches à lancer une fois

   while ( int state(boutonUn) == 1 ){ // L'état 1 reste il à 1 en boucle tant qu'un autre bouton n'est pas appuyé et repasse à 0 ?
    // fonction qui gère une bande Néopixel en couleur rouge par exemple
   }
}

void simpleClickBoutonDeux(){
  
}

void simpleClickBoutonTrois(){
  
}

void simpleClickBoutonQuatre(){
  
}

Bonjour udina

Je n'ai pas bien compris ta question, pourrais tu me dire la finalité de ton montage pour m'aider à comprendre.
Est ce que plusieurs boutons peuvent être pressés en même temps?
Veux tu le temps entre la pression de n'importe quels 2 boutons?
.... :wink:

A+
Cordialement
jpbbricole

La fonction est appelée quand le bouton est appuyé puis relâché avec OneButton si je me souviens bien, donc dans votre fonction callback, vous êtes à peu près sûr que le bouton est relâché

Cf la doc Arduino OneButton Library

Si vous voulez gérer correctement vos boutons il faut appeler tick() super souvent donc Il ne faut pas que le callback rentre dans une boucle d’attente

Non, c'est un programme qui ne détecte qu'un appui simple pour chaque bouton.
J'ai testé sur Tinkercad comme tu m'as montré sur un autre post pour pouvoir débuger moi même l'état des boutons mais je n'arrive pas à intégrer la bibliothèque OneButton.

https://www.tinkercad.com/things/0QtTDXzorqX-ingenious-crift

J'ai tenté une approche comme si dessous, dites moi si ça peut être fonctionnel ?

[code]
#include "OneButton.h"

OneButton boutonUn;  
OneButton boutonDeux;
OneButton boutonTrois;
OneButton boutonQuatre;

int stateBoutonUn = 0;
int stateBoutonDeux = 0;
int stateBoutonTrois = 0;
int stateBoutonQuatre = 0;


void setup() {

  boutonUn.setup(2, INPUT);
  boutonDeux.setup(3, INPUT);
  boutonTrois.setup(4, INPUT);
  boutonQuatre.setup(5, INPUT);

  boutonUn.attachClick(simpleClickBoutonUn);
  boutonDeux.attachClick(simpleClickBoutonDeux);
  boutonTrois.attachClick(simpleClickBoutonTrois);
  boutonQuatre.attachClick(simpleClickBoutonQuatre);
  
}

void loop() {
  
  boutonUn.tick();
  boutonDeux.tick();
  boutonTrois.tick();
  boutonQuatre.tick();
  
}

void simpleClickBoutonUn() {
  stateBoutonUn = 1;
  stateBoutonDeux = 0;
  stateBoutonTrois = 0;
  stateBoutonQuatre = 0;

   while ( stateBoutonUn == 1 ){ 
    // fonction qui gère une bande Néopixel en couleur rouge par exemple
   }
}

void simpleClickBoutonDeux(){
  stateBoutonUn = 0;
  stateBoutonDeux = 1;
  stateBoutonTrois = 0;
  stateBoutonQuatre = 0;

while ( stateBoutonDeux == 1 ){ 
    // fonction qui gère une bande Néopixel en couleur bleu par exemple
   }
}

void simpleClickBoutonTrois(){
  stateBoutonUn = 0;
  stateBoutonDeux = 0;
  stateBoutonTrois = 1;
  stateBoutonQuatre = 0;

while ( stateBoutonTrois == 1 ){ 
    // fonction qui gère une bande Néopixel en couleur verte par exemple
   }
}

void simpleClickBoutonQuatre(){
  stateBoutonUn = 0;
  stateBoutonDeux = 0;
  stateBoutonTrois = 0;
  stateBoutonQuatre = 1;

while ( stateBoutonQuatre == 1 ){ 
    // fonction qui gère une bande Néopixel en couleur orange par exemple
   }
}

[/code]

Le callback ne peut pas être bloquant sinon vous ne revenez pas à la loop

Postez tout le code.

Wokwi supporte la bibliothèque OneButton

Je fini le code et je te le post, merci à toi

C’est pas forcément nécessaire

Expliquez nous ce que vous cherchez vraiment à faire.

C’est peut être un programme qui se prête bien à la programmation par machine à états (cf mon tuto éventuellement)

Voici le programme, il est présent sur plusieurs sujets donc ça va vous dire quelque chose. Je continue de tenter de l'améliorer.

/* --------------  Déclaration du bandeau Leds ------------------------ */

#include <Adafruit_NeoPixel.h>
#define LED_PIN    6
#define LED_COUNT 17

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

unsigned long tempsDeClignotement = 0;

/* --------------  Déclaration des boutons  --------------------------- */

#include "OneButton.h"

OneButton boutonAppuiPedale;  
OneButton boutonRelanchementPedale;
OneButton boutonArretVehicule;
OneButton boutonRelanceVehicule;

int stateBoutonAppuiPedale = 0;
int stateBoutonRelanchementPedale = 0;
int stateBoutonArretVehicule = 0;
int stateBoutonRelanceVehicule = 0;

/* --------------  Déclaration des relais + valeurs pédale d'accélérateur */

const int relaisInverseur = 2;
const int relaisCanal_A_B_PedaleAccelerateur = 12;
const int relaisParking = 13;

const int valeurFilVertInverseur = 8;
const int valeurFilBlancInverseur = 3;
const int valeurFilBleuInverseur = 4;

const int Canal_A = 6; // possibilité d'inversement avec le Canal_B ( inverseur les Pins 6 et 5 )
int pwmValue_A;
const int Canal_B = 5;
int pwmValue_B;

const int pwmValMin = 95; // Valeurs qui doivent correspondre à la vitesse en mise en marche avant )
const int pwmValMax = 160; // Valeurs qui doivent correspondre à la vitesse en mise en marche avant )

// ____________________________________________________________________________  SETUP  ______________________________________________________________________________________

void setup() {

  Serial.begin(115200);

  // __________________  Initialisation SETUP des boutons  _____________________ //

  boutonAppuiPedale.setup(9, INPUT);
  boutonRelanchementPedale.setup(10, INPUT);
  boutonArretVehicule.setup(11, INPUT);
  boutonRelanceVehicule.setup(A0, INPUT);

  boutonAppuiPedale.attachClick(simpleClickAppuiPedale);
  boutonRelanchementPedale.attachClick(simpleClickRelachementPedale);
  boutonArretVehicule.attachClick(simpleClickArretVehicule);
  boutonRelanceVehicule.attachClick(simpleClickRelanceVehicule);

// ___________________  Initialisation SETUP des relais + valeurs pédale d'accélérateur __________________ //

  pinMode(relaisInverseur, OUTPUT);

  pinMode(valeurFilVertInverseur, OUTPUT);
  pinMode(valeurFilBlancInverseur, OUTPUT);
  pinMode(valeurFilBleuInverseur, OUTPUT);

  pinMode(relaisCanal_A_B_PedaleAccelerateur, OUTPUT);

  pinMode(relaisParking, OUTPUT);

  pinMode(Canal_A, OUTPUT);
  pinMode(Canal_B, OUTPUT);

pwmValue_A = pwmValMax;
pwmValue_B = pwmValMin;

//  ____________________  Initialisation SETUP des Leds  _____________________________  //
  strip.begin();           
  strip.show();            
  strip.setBrightness(50);


  arretDuVehiculeAuDemarrageDuProgramme();

}

// __________________________________________________________________________________  LOOP  __________________________________________________________________________________


void loop() {

unsigned long tempsActuel = millis();

  boutonAppuiPedale.tick();
  boutonRelanchementPedale.tick();
  boutonArretVehicule.tick();
  boutonRelanceVehicule.tick();

 if(tempsActuel - dernierTemps >= 1000 ) {
    Serial.println(compteurImpulsion);
    compteurImpulsion = 0;
    dernierTemps = tempsActuel;    
  }
  
 if (compteurImpulsion >= 100) {
    arretDuVehiculeAuDemarrageDuProgramme();
  }  
}

// _________________________________________________________________  FONCTION(S) _____________________________________________________________


//  _____________________________  Fonction de d'accélération de la pédale  ________________________________  //

void simpleClickAppuiPedale() {
  
  stateBoutonRelanceVehicule = 0;
  stateBoutonArretVehicule = 0;
  stateBoutonAppuiPedale = 1;
  stateBoutonRelanchementPedale = 0;
  
  extinctionLeds();
  int pwmValue_Aold = pwmValue_A;
  pwmValue_A -=8; // Diminuer A
  pwmValue_A = constrain(pwmValue_A, pwmValMin, pwmValMax); // Pour limiter les valeurs  https://docs.arduino.cc/language-reference/en/functions/math/constrain/
  pwmValue_B = 255 - pwmValue_A; //

  for ( int a = pwmValue_Aold; a >= pwmValue_A; a-- ) {
    analogWrite(Canal_A, a);
    analogWrite(Canal_B, 255 -a);
    delay(50);
    Serial.println("A " + String(a) + "\t" + "B " + String(255 - a));
  }
    Serial.println("");
    while (stateBoutonAppuiPedale == 1){
    if(Canal_A >= 144){
      strip.setPixelColor(3, 62, 214, 17);
      strip.show();
    } 
    if(Canal_A >= 120){
      strip.setPixelColor(7, 62, 214, 17);
      strip.show();
    }
    if(Canal_A >= 96){
      strip.setPixelColor(11, 62, 214, 17);
      strip.show();
    }
    if(Canal_A >= 56){
      strip.setPixelColor(16, 62, 214, 17);
      strip.show();
    }
  }
}

//  _____________________________  Fonction de décélération de la pédale  ________________________________  //

void simpleClickRelachementPedale() {
  
  stateBoutonRelanceVehicule = 0;
  stateBoutonArretVehicule = 0;
  stateBoutonAppuiPedale = 0;
  stateBoutonRelanchementPedale = 1;
  
  extinctionLeds();
  int pwmValue_Bold = pwmValue_B;
  pwmValue_B -=10; // Diminuer B
  pwmValue_B = constrain(pwmValue_B, pwmValMin, pwmValMax); // Pour limiter les valeurs  https://docs.arduino.cc/language-reference/en/functions/math/constrain/
  pwmValue_A = 255 - pwmValue_B; //

  for ( int b = pwmValue_Bold; b >= pwmValue_B; b-- ) {
    analogWrite(Canal_B, b);
    analogWrite(Canal_A, 255 -b);
    delay(50);
    Serial.println("A " + String(255 - b) + "\t" + "B " + String(b));
  }
  Serial.println("");
  while (stateBoutonRelanchementPedale == 1) {
    if(Canal_A <= 80){
      strip.setPixelColor(16, 62, 214, 17);
      strip.show();
    } 
    if(Canal_A <= 112){
      strip.setPixelColor(11, 62, 214, 17);
      strip.show();
    }
    if(Canal_A <= 136){
      strip.setPixelColor(7, 62, 214, 17);
      strip.show();
    }
    if(Canal_A <= 160){
      strip.setPixelColor(3, 62, 214, 17);
      strip.show();
    }
  }
}

//  _____________________________  Fonction d'arrêt du véhicule en cours de programme  ________________________________  //

void simpleClickArretVehicule() {
  
  stateBoutonRelanceVehicule = 0;
  stateBoutonArretVehicule = 1;
  stateBoutonAppuiPedale = 0;
  stateBoutonRelanchementPedale = 0;
  
  extinctionLeds();
  digitalWrite(relaisCanal_A_B_PedaleAccelerateur, LOW);
  delay(2000);
  digitalWrite(relaisParking, HIGH);
  delay(500);
  digitalWrite(relaisParking, LOW);

  while (stateBoutonArretVehicule == 1) {
    ledsArretDuVehicule();
  }
}

//  _____________________________  Fonction de relance du véhicule en marche avant  ________________________________  //

void simpleClickRelanceVehicule() {
  
  stateBoutonRelanceVehicule = 1;
  stateBoutonArretVehicule = 0;
  stateBoutonAppuiPedale = 0;
  stateBoutonRelanchementPedale = 0;
  
  extinctionLeds();
  digitalWrite(relaisInverseur, HIGH);

  digitalWrite(valeurFilVertInverseur, LOW);
  digitalWrite(valeurFilBlancInverseur, LOW);
  digitalWrite(valeurFilBleuInverseur, HIGH);
  delay(1000);
  digitalWrite(relaisInverseur, LOW);
  digitalWrite(relaisCanal_A_B_PedaleAccelerateur, HIGH);
  delay(1000);
  analogWrite(Canal_A, 160); // Valeur qui peut être réglé pour affiner le lancement en marche avant du tracteur
  analogWrite(Canal_B, 95);  // Valeur qui peut être réglé pour affiner le lancement en marche avant du tracteur ( penser à modifier les valeurs de butée plus haut )

  while (stateBoutonRelanceVehicule == 1){
    if(Canal_A >= 160){
      strip.setPixelColor(3, 62, 214, 17);
      strip.show();
    }
  }
}

//  _____________________________  Fonction Arrêt du véhicule au démarrage du programme  ________________________________  //

void arretDuVehiculeAuDemarrageDuProgramme() {
  
  stateBoutonRelanceVehicule = 0;
  stateBoutonArretVehicule = 0;
  stateBoutonAppuiPedale = 0;
  stateBoutonRelanchementPedale = 0;
  
  digitalWrite(relaisInverseur, LOW);

  analogWrite(Canal_A, 205);  
  analogWrite(Canal_B, 50);
  delay(1000);
  digitalWrite(relaisCanal_A_B_PedaleAccelerateur, HIGH);
  delay(1000);
  digitalWrite(relaisParking, HIGH);
  delay(2000);
  digitalWrite(relaisParking, LOW);

  ledsArretDuVehicule();
}

//  _____________________________  Fonction clignotant rouge d'un problème de réglage vitesse trop rapide  ________________________________  //

void ledsProblemeVitesse() {
if(tempsActuel - tempsDeClignotement >= 750 ) {   // clignotement rouge pour problème de vitesse trop importante
  strip.setBrightness(175);
  strip.setPixelColor(16, 242, 23, 20);
  strip.show();
  tempsDeClignotement = tempsActuel;
  }
 }

//  ____________________________  Fonction Leds fixe rouge d'arrêt du véhicule  ______________________________________  //

void ledsArretDuVehicule() {
  strip.setBrightness(175);
  strip.setPixelColor(16, 242, 23, 20);
  strip.show();
 }

// _____________________________  Fonction d'extinction des leds  __________________________ //

void extinctionLeds() {
strip.setPixelColor(16, 0, 0, 0);
strip.show();
}

// ____________________________  Fonction Leds verte progressive selon la position de la pédale d'accélérateur  _________________________ //


/* OIC canal un de la pédale : 53  ==> pédale relevée : 17.8 -- 1,79V  /  pédale enfoncée : 81.4 -- 8V
   OIC canal deux de la pédale : 54  ==> pédale relevée : 81.8 -- 8,18V  / pédale enfoncée : 18.7 -- 2V
*/

Bonsoir udina

C'est le problème avec Tinkercad, c'est compliqué. Un autre émulateur, Wokwi doit le permettre et le spécialiste est @J-M-L, il pourra te répondre.

Cordialement
jpbbricole

Comme déjà dit 2 fois, si vous engagez une boucle infinie dans un callback, vous ne retournerez jamais à la loop…

Oui, pardon, c'est vrai qu'il n'y a rien qui fait sortir de ces boucles !
J'ai supprimé les boucles while et laissé les comparaison pour le moment, je passe au test demain.