millis() + appui long/court : methode plus simple ?

Bonjour à tous,

j’aimerai savoir s’il existe une méthode plus simple pour pouvoir enregistrer une différence de temps ou toute autre calcul lors d’un appui long ou court sur un bouton.

je vous explique le process :

1- bouton LOW-> enregistrement de l’instant millis()
2- bouton HIGH → affichage du temps qui s’est écoulé entre l’étape 1 et l’étape 2.

si je fait cette méthode (en le schématisant de manière simple)

if (digitalRead(bouton1) == LOW { // étape 1
   begin_timer = millis();
}
if (digitalRead(bouton1) == HIGH { // étape 2
   end_timer = millis();
   Serial.println(end_timer - begin_timer);
}

On voit donc tout de suite ici l’erreur qu’il va y avoir :
=> Etape 1, begin_timer va constamment se réinitialiser lors de l’appui long/court.
La soustraction (end_timer - begin_timer) donnera un résultat proche de 1ms (6 à 7ms pour mon cas, mais peu importe).

A ce jour la seule méthode que j’ai trouvé en tâtonnant le code dans tous les sens, pour faire les enregistrements à l’instant T lorsque j’appuie sur le bouton, et avoir un affichage propre, est ce code ci dessous :

unsigned long begin_timer;
unsigned long end_timer;
variable1 = false;
variable2 = false;
boucle = false;

  if (digitalRead(bouton1) == LOW) { // étape 1
    if (variable1 == false) {
      begin_timer = millis();
      variable1 = true;
      boucle = true;
    }
  }

  if ((digitalRead(bouton1) == HIGH) && boucle == true) { // étape 2
      if (variable2 == false) {
      end_timer = millis();
      variable2 = true;
      Serial.println(end_timer - begin_timer);
    }
}

note : J’ai omis volontairement de ne pas mettre toutes les autres variables, qu’il faudrait rajouter pour permettre de réinitialiser ces dernières, afin de pouvoir enregistrer de nouveau les différence de temps.

=> Existe t’il une méthode plus simple qui permettrait d’alléger le code et permettrait de faire les enregistrements millis() à l’instant que je souhaite, sans passer par ce process de déclaration de variables en tout genre. car je ne sais pas du tout si c’est une bonne ou mauvaise méthode.
Mais c’est la seule que j’ai réussi à trouver, à mon niveau.

Cordialement.

Il faut travailler sur les transitions de l’état du bouton et non pas sur l’état de celui-ci

Au départ on suppose le bouton à l’état haut.
On déclare une variable qui conserve l’état précédent du bouton.
On initialise cette variable que l’on va appeler etat_prec à HIGH dans setup().

Dans loop(), on fait
etat_bouton = digitalRead(bouton1)
if (etat_prec==HIGH && etat_bouton==LOW)
begin_timer = millis();
if (etat_prec==LOW && etat_bouton==HIGH)
end_timer = millis();
à la fin de loop on fait
etat_prec = etat_bouton

Ah oui en effet, j'avais pas pensé à ça !
Je suis sur un projet où j'ai de multitude état en LOW et HIGH, avec ma méthode cela fonctionne très bien, mais je voulais vraiment essayé de voir s'il existait autre chose comme méthode et surtout une manière d'alléger tout ça.

Par contre est ce qu'il est essentiel d'utiliser cette méthode pour tous les cas de figure ou juste pour la fonction millis() ?

Bref, merci ! je vais aller tester tout ça et .... refaire toutes mes lignes de code :cry:

Bonjour

Tu es pile poil dans la bonne approche.

C'est-à-dire constituer un ensemble de variables globales qui, à un instant t, permettent de qualifier l'état du système.
Et donc de savoir quoi faire quand un événement se produit.

Pour ne pas être perdu dans le code, il est très important de choisir des noms de variables parlants.
Dans ton exemple, variable1 devrait s'appeler boutonEnfonce.

Une fois ceci assimilé, tu peux ensuite opter pour des lib qui te simplifient la vie.

Par exemple pour la gestion des boutons, voir le lien dans ma signature.
Lorgne aussi du côté des machines à états de JML.

Et si tu as envie de tout faire toi-même, urbanise bien ton code en sections (variables & fonctions ou mieux : objets) indépendantes pour les mettre au point séparément.

Y a rien de pire que d'arriver au final avec un code qui démarre par 50 variables globales, utilisées ensuite à droite à gauche dans le code. On finit par ne plus savoir qui la met à jour et qui l'utilise. Grosse source de bug à chaque retouche.

Merci pour le retour ! J’utilise en effet quelques variables et librairie dans mon code pour que la lecture soit le plus clair possible pour savoir où je me trouve si tel ou tel événement se produit.

La méthode des états sur les boutons est sans doute une des meilleurs méthode, mais elle se révèle finalement un véritable casse tête chinois pour moi. Car j'utilise 2 boutons avec des conditions différentes en fonction des différents temps appuyé ou non qui désactive d'autre partie du code et qui change de nouveau si tel ou tel bouton fait un appui ou non, en même temps ou pas.

Des conditions dans des sous conditions qui sont eux même dans des sous conditions mais en lien avec les premières conditions blablabla...
Je me suis arraché les cheveux toute la nuit ou presque en repartant de 0, pour essayer de sortir qq chose, mais sans réel succès par rapport à ce que j'avais fait, sans doute pas opti, mais qui fonctionne bien et surtout, lisible et finalement pas si lourd que ça. Je mis prends sans doute mal, c'est certain :slight_smile:

En tout cas, ça ma permis d'apprendre de nouvelle chose pour envisager d'autre projets !
Thx.

Si vous vous êtes arraché les cheveux en essayant de gérer le conditions à la main dans un sac de spaghetti , c'est sans doute un programme qui se prête bien à la programmation par machine à états (cf mon tuto éventuellement)

Il y a aussi des librairies pour faire ça