Conseil gestion poussoir on/off

Bonjour à tous,

J'ai enfin reçu mon starting kit qui est livré avec un guide d'initiation.

En suivant le cours OC, j'avais vu cette logique pour gérer un poussoir en on/off:

/*
le bouton poussoir est connecté au pin 2 pour un mode INPUT_PULLUP
la Led est connectée au pins 4 avec une résistance de 220Ω
*/

//déclaration des variables
int pinBouton, pinLed;
boolean etatAllumage;
void setup()
{
  //initialisation des variables
  Serial.begin(9600);
  pinBouton = 2;
  pinLed = 4;
  etatAllumage=0;
  //définition des modes
  pinMode(pinBouton, INPUT_PULLUP);
  pinMode(pinLed, OUTPUT);
}
void loop()
{
  Serial.print(etatAllumage);
  
  if (etatAllumage) //on teste si etatAllumage est à 1
  {
    digitalWrite(pinLed, HIGH);//on allume la LED
  }
  else //sinon
  {
    digitalWrite(pinLed, LOW); //on éteint la LED
  }
  //lecture de l'état du bouton et stockage dans etatBouton
  boolean etatPinBouton = digitalRead(pinBouton);
  Serial.println(etatPinBouton);
  //test des conditions
  if (!etatPinBouton)//si bouton appuyé (donc le pin indique 0 car il est en mode INPUT_PULLUP)
  {
    if (etatAllumage) //si etatAllumage à 1
    {
      etatAllumage=0; //on le passe à 0
    }
    else //sinon
    {
      etatAllumage=1; //on le passe à 1
    }
  }
  delay(200);
}

En tant que développeur, c'est une approche que j'aurais pu avoir

Cependant, dans le guide que j'ai en main, ils insistent sur le phénomène de jitter et préconisent le code suivant:

int ledpin=11;            //definition digital 11 pins as pin to control the LED
int btnpin=2;             //Set the digital 2 to button interface 

volatile int state = LOW; // Defined output status LED Interface

void setup()
{
  pinMode(ledpin,OUTPUT);//Set digital 11 port mode, the OUTPUT for the output
  pinMode(btnpin,INPUT); //Set digital 2 port mode, the INPUT for the input
}

void loop()
{
  if(digitalRead(btnpin)==LOW)          //Detection button interface to low
  {   
      delay(10);                        //Delay 10ms for the elimination of key leading-edge jitter
      if(digitalRead(btnpin)==LOW)      //Confirm button is pressed
      {     
        while(digitalRead(btnpin)==LOW);//Wait for key interfaces to high
        delay(10);                      //delay 10ms for the elimination of key trailing-edge jitter
        while(digitalRead(btnpin)==LOW);//Confirm button release
        state = !state;                 //Negate operation, each time you run the program here, state the HGIH becomes LOW, or the state becomes the LOW HGIH.
        digitalWrite(ledpin,state);     //Output control status LED, ON or OFF 
      }
   }
}

ou encore la meme chose pour le jitter mais en utilisant les interruptions:

int ledpin=11;            //definition digital 11 pins as pin to control the LED
int btnpin=2;             //Set the digital 2 to button interface 
volatile int state = LOW; //Defined output status LED Interface

void setup()
{                
  pinMode(ledpin, OUTPUT);                  //Set digital 11 port mode, the OUTPUT for the output
  attachInterrupt(0, stateChange, FALLING); //Monitoring Interrupt 0 (Digital PIN 2) changes in the input pins FALLING
}
void loop()                     
{
  digitalWrite(ledpin, state);              //Output control status LED, ON or OFF 
}
void stateChange()                          //Interrupt function
{
  if(digitalRead(btnpin)==LOW)              //Detection button interface to low
  { 
   
      delayMicroseconds(10000);             //Delay 10ms for the elimination of key leading-edge jitter
      if(digitalRead(btnpin)==LOW)          //Confirm button is pressed
      {
          state = !state;                   //Negate operation, each time you run the program here, state the HGIH becomes LOW, or the state becomes the LOW HGIH.
      }
   }
}

Bon déjà, d'après la doc des fonctions Arduino, ils utilisent mal attachInterrupt à qui il est déconseillé de passer directement le n° de la pin mais vous, qui avez de l'expérience, quelle est la bonne pratique ?

Le but du montage est d'activer ou non un relais en fonction de différentes actions:

  • Via un poussoir on/off
  • Via un RTC
  • Via une instruction reçue en wifi

L'idée des interruptions me plait bien avec de la gestion événementielle. Pour le jitter, vaut il mieux le gérer coté soft comme ici ou bien coté hard avec un condo ?

Merci à vous tous
Chris

Pour gérer un bouton dont le "timing" n'est pas un impératif critique à la milliséconde près, j'ai rédigé ce tuto qui pourrait certainement te servir. Dans le même tuto il y a aussi comment gérer plusieurs boutons, ce qui peut être utile aussi... :wink:

Super, merci beaucoup

Le jitter étant un probleme hard, pourquoi ne pas le résoudre de façon hard ? Dans ma vision des choses, le soft n'a pas à se soucier de ces aspects là, non ?

tu peux aussi regarder les tutos/bib du Bricoleau

wAx:
Le jitter étant un probleme hard, pourquoi ne pas le résoudre de façon hard ? Dans ma vision des choses, le soft n'a pas à se soucier de ces aspects là, non ?

il y a les deux écoles, la mienne est plutôt hard mais nécessite un fer a souder ....

Bonjour,

Je suppose que ce que tu appelles jitter, ce sont les rebonds d'un poussoir.
Il y a des méthodes hard pour éliminer ou réduire ces rebonds, mais les méthode soft ne coutent rien (si ce n'est quelques instructions) et sont très efficaces.
Sachant que les rebonds durent au maximum quelques ms, la méthode la plus simple est de lire le bouton toutes les 10 ou 20 ms.

rjnc38:
il y a les deux écoles, la mienne est plutôt hard mais nécessite un fer a souder ....

Je suis intéressé par cette solution : surtout comment dimensionner les composants selon le besoin...

Merci à tous pour vos réponses

D'après ce que je lis, la méthode soft est satisfaisante... Je regarderai quand meme si je n'ai pas un petit condo sous la main et je ferai quelques tests.

Je prévois de déléguer la détection de l'appui bouton à l'interruption.

Je vais donc avoir quelques fonctions qui feront le job en cas de passage à ON ou de passage à OFF

Ma fonction loop va donc passer son temps à interroger:

  • le RTC pour voir si c'est l'heure de faire quelque chose
    et
  • le Wifi pour voir si une instruction a été reçue

De là, elle appellera les fonctions de passage à ON ou OFF et pour finir, elle fera un digitalWrite sur le relai pour appliquer l'étant en cours

Zorro_X:
Pour gérer un bouton dont le "timing" n'est pas un impératif critique à la milliséconde près, j'ai rédigé ce tuto qui pourrait certainement te servir. Dans le même tuto il y a aussi comment gérer plusieurs boutons, ce qui peut être utile aussi... :wink:

Je reviens sur ton tuto
J'ai l'impression dans tes exemples, que tu ne gères l'anti rebond que pour l'appui et non pas pour le relâchement.
Une raison particulière ?
Merci

wAx:
J'ai l'impression dans tes exemples, que tu ne gères l'anti rebond que pour l'appui et non pas pour le relâchement.
Une raison particulière ?

Merci pour ta question, je vais éclaircir cela dans le tutoriel lui-même :
"Pour une meilleure réactivité du bouton, seulement les rebonds lors de l'appui du bouton sont ignorés/masqués de la sorte et comme vous le constatez à l'utilisation, c'est suffisant. L'état relâché est donc considéré comme l'état "par défaut" du bouton, à priori "plus stable" que l'état appuyé. Les rebonds du relâchement sont ainsi automatiquement ignorés, ne menant pas sur un état "appuyé" stable. N'oubliez pas que l'objectif c'est de se rapprocher autant que possible du moment réel où l'action d'appui ou relâchement a vraiment été effectuée."

C'est plus clair comme ca ?