Problème de code (bouton)

Bonjour :slight_smile:

j'ai actuellement un problème avec mon code que je n'arrive pas à détecter, le code est valide mais il ne fait pas ce que je souhaiterais qu'il fasse, je ne sais pas si c'est un problème dans mon code ou un problème au niveau du bouton poussoir, je l'ai équipé du système anti-rebond avec un condensateur 16v 10 µf, broché de la façon suivante au PIN 4 de mon Arduino Uno:

En fait lorsque j'appuie sur le bouton, le compte à rebours fonctionne parfaitement et lorsque je le relâche il s'arrête. J'ai remarqué que la led2 restait en marche alors que normalement elle devrait s'éteindre puisque les valeurs d' "EtatBoutonActuel" et "EtatBoutonPrecedent" sont censées changer et passer de HIGH à LOW puisque j'enfonce le bouton, donc je pense que c'est plus un problème au niveau de monde code...

Le voici:

const int bouton = 4;

//////// VARIABLES UTILISEES POUR CHRONO ////////
unsigned long ste; // Temps qui s'écoule
unsigned long currentMillis = 0;    // Millis actuel
unsigned long lastMillis = 0;       // Millis sauvegardé
unsigned long elapsedMillis = 0;    // Millis écoulé entre currentMillis et lastMillis
unsigned long counter = 180000;          // Valeur du chrono
unsigned long counterPrint = 0;     // Valeur du chrono lors du dernier print

/////////////////////////////////////////////////////////////
int EtatBoutonActuel;
int EtatBoutonPrecedent;
/////////////////////////////////////////////////////////////

const int led = 12;
const int led2 = 11;

void setup() {
	
	pinMode(led, OUTPUT);
	pinMode(led2, OUTPUT);
	Serial.begin(9600);
	
	pinMode(bouton, INPUT);
	EtatBoutonPrecedent = HIGH;

}

void loop() {
	
	// Mise à jour des temps currentMillis, elapsedMillis et lastMillis
	//  currentMillis aura la même valeur que lastMillis donc elapsedMillis vaudra 0

	currentMillis = millis();
	elapsedMillis = ( lastMillis - currentMillis );
	lastMillis = currentMillis;
	
	EtatBoutonActuel = digitalRead(bouton);
	
	// Si le bouton est enfoncé, on fait tourner le chrono
	if ((EtatBoutonActuel == LOW) && (EtatBoutonPrecedent == HIGH))
	{
		
		
		
		
		// Ajout du temps écoulé
		ste = counter += elapsedMillis;
		
		
		
		Serial.println(ste);
		
		
		
		if (ste > counter)
		{
			Serial.println("Compte à rebours terminé!");
		}
		
	}
	

	
		if ((EtatBoutonPrecedent == HIGH) && (EtatBoutonActuel == HIGH)) // si le bouton n'a pas encore été enfoncé une seule fois
		{
			digitalWrite(led2, HIGH);
		}
		
		if ((EtatBoutonPrecedent == LOW) && (EtatBoutonActuel == HIGH) && (counter > ste)) // si bouton relâché et compte rebours pas terminé
		{
			digitalWrite(led, HIGH);
		}
		
		if ((EtatBoutonPrecedent == LOW) && (EtatBoutonActuel == HIGH) && (ste > counter)) // si bouton relâché et compte rebours terminé
		{
			Serial.println("Compte à rebours terminé!");
		}
		
		EtatBoutonActuel = EtatBoutonPrecedent;
	
	
}

Merci d'avance

Salut,

Sans essayer de comprendre le code, pas une seule fois digitalWrite(led2, LOW); n'apparaît, pas étonnant qu'elle ne s'éteigne jamais :wink:

Oui, certes... mais ca n'a pas d'importance, le problème n'est pas là :wink: Des idées? :frowning:

Salut,
Dans ton code, c'est normal que le timer s’arrête, et que tes LEDs restent allumées... C'est quoi le problème, le timer doit continuer ?

PS : Je te conseil de passer par une interruption pour vérifier le changement d'etat du bouton ça sera plus simple :wink:

J'ai remarqué que la led2 restait en marche alors que normalement elle devrait s'éteindre puisque les valeurs d' "EtatBoutonActuel" et "EtatBoutonPrecedent" sont censées changer et passer de HIGH à LOW puisque j'enfonce le bouton

Oui, certes... mais ca n'a pas d'importance, le problème n'est pas là smiley-wink Des idées?

Faudrait savoir ce que tu veux ....

Pour traduire les propos de B@tto que tu sembles n'avoir pas compris.
Il est normal que les LED restent allumées car à aucun moment dans ton code tu ne demandes leur extinction.
Il n'y a aucune ligne de code avec un
digitalWrite(led, LOW);
ou un
digitalWrite(led2, LOW);

Si ce que tu voulais c'est :
-led2 allumée tant que le timer est off, mais éteinte si timer on
-led allumée si timer on et éteinte sinon (inverse de led2)
-timer se lance si appuie, continue peu importe l'etat du bouton et s'arrete apres le temps demandé

voila le code :

const int bouton = 4;

//////// VARIABLES UTILISEES POUR CHRONO ////////
unsigned long ste=0; // Temps qui s'écoule
unsigned long currentMillis = 0;    // Millis actuel
unsigned long lastMillis = 0;       // Millis sauvegardé
unsigned long elapsedMillis = 0;    // Millis écoulé entre currentMillis et lastMillis
unsigned long counter = 180000;     // Valeur du chrono

/////////////////////////////////////////////////////////////
int EtatBoutonActuel;
int EtatBoutonPrecedent;
/////////////////////////////////////////////////////////////

const int led = 12;
const int led2 = 11;

void setup() {
	
	pinMode(led, OUTPUT);
	pinMode(led2, OUTPUT);
	Serial.begin(9600);
	
	pinMode(bouton, INPUT);
	EtatBoutonPrecedent = HIGH;

}

void loop() {
	
	// Mise à jour des temps currentMillis, elapsedMillis et lastMillis
	//  currentMillis aura la même valeur que lastMillis donc elapsedMillis vaudra 0

  currentMillis = millis();
  elapsedMillis = ( lastMillis - currentMillis );
  lastMillis = currentMillis;
	
  EtatBoutonActuel = digitalRead(bouton);
	
  // Si le bouton est enfoncé, on fait tourner le chrono
  if ((EtatBoutonActuel == LOW) && (EtatBoutonPrecedent == HIGH))
  {
    // Mise hors tension de la LED2 et Allumage LED (compte a rebourd en cours)
    digitalWrite(led2, LOW);
    digitalWrite(led, HIGH);
    
    // Ajout du temps écoulé
    ste += elapsedMillis;
    Serial.println(ste);
    if (ste > counter)
    {
      // La LED1 s'eteint, le compte a rebourd est termine, et la LED2 s'allume le compte a rebourd est en attente de demarrage
      digitalWrite(led, LOW);
      digitalWrite(led2, HIGH);
      EtatBoutonPrecedent == HIGH;
      EtatBoutonActuel == HIGH;
      ste=0;
      Serial.println("Compte à rebours terminé!");
    }
  }
  
  if ((EtatBoutonPrecedent == HIGH) && (EtatBoutonActuel == HIGH)) // si le bouton n'a pas encore été enfoncé une seule fois
  {
    digitalWrite(led2, HIGH);
  }
  
  if ((EtatBoutonPrecedent == LOW) && (EtatBoutonActuel == HIGH) && (counter > ste)) // si bouton relâché et compte rebours pas terminé
  {
    digitalWrite(led, HIGH);
    // Ajout du temps écoulé
    ste += elapsedMillis;
    Serial.println(ste);
    if (ste > counter)
    {
      // La LED1 s'eteint, le compte a rebourd est termine, et la LED2 s'allume le compte a rebourd est en attente de demarrage
      digitalWrite(led, LOW);
      digitalWrite(led2, HIGH);
      EtatBoutonPrecedent == HIGH;
      EtatBoutonActuel == HIGH;
      ste=0;
      Serial.println("Compte à rebours terminé!");
    }
  }
		
  if ((EtatBoutonPrecedent == LOW) && (EtatBoutonActuel == HIGH) && (ste > counter)) // si bouton relâché et compte rebours terminé
  {
    // La LED1 s'eteint, le compte a rebourd est termine, et la LED2 s'allume le compte a rebourd est en attente de demarrage
    digitalWrite(led, LOW);
    digitalWrite(led2, HIGH);
    EtatBoutonPrecedent == HIGH;
    EtatBoutonActuel == HIGH;
    ste=0;
    Serial.println("Compte à rebours terminé!");
  }
  
  EtatBoutonActuel = EtatBoutonPrecedent;
  	
}

CEPENDANT, problème rencontrés :
-ça va defiler TRES vite sur le Serial
-possibilité de manquer un changement d'état du bouton
-une led de trop (en effet c'est l'inverse de l'autre..)
-j'ai pas optimiser et pas relu, il y a donc peut etre des fautes...
-tu dis que le timer fonctionne, (ste = counter += elapsedMillis; pour moi forcement plus grand que counter..... j'ai modifié) mais j'ai pas touché au moment ou il faut actualiser le tout

bonjour,
grillé par fdufnews :slight_smile:
pour un changement d'état, regardes du coté de boolean.
sinon dans les exemples de l'ide, regardes statechangedetection

edit
pourquoi mettre

 if ((EtatBoutonActuel == LOW) && (EtatBoutonPrecedent == HIGH))

alors qu'un

 if (EtatBoutonActuel  != EtatBoutonPrecedent )

suffit avec les conditions qui vont bien derrière.

Bien vu infobarquee :sweat_smile: , ce serait plus logique de mettre un "!=" :grin:

Mais je ne pense pas que ça corrigera le problème, si? Sinon je peux peux peut-être utiliser une interruption comme l'a évoqué Minicarpet pour justement détecter que l'état du bouton a changé?

pour un changement d'état, regardes du coté de boolean.

Je t’ai mis un code plus haut, je pense que ça corrigera ton problème :stuck_out_tongue:

Une interruption te permet d’être sur de pas rater un changement sur le bouton mais c’est pas forcément obligatoire :wink:

Avec l’interruption il te suffit de changer deux ou trois boolean et un ou deux if dans le loop font le reste :wink:

déjà un conseil, papier crayon :wink:
schéma de tout projet avec les conditions

rebours = zéro au départ
appuis bouton => début rebours
appuis de nouveau => ???????
==============> rebours non terminé => on fait quoi?
==============> rebours terminé => on fait quoi?
fin rebours => on fait quoi?

etc.....
une fois ca, c'est 90% du taf de fait pour le code et on trouve mieux la solution pour créer son code

Je pensais que ça n'avais pas d'importance de décrire exactement ce que je voulais mettre dans les conditions, mais puisque c'est nécessaire: lorsque j'appuie sur le bouton, le compte a rebours démarre et lorsque je le relâche, il se stop sur sa dernière valeur et redémarre ensuite sur sa dernière valeur lorsque je rappuie sur le bouton, et donc lorsque le bouton est relâché, je voudrais faire clignoter une led et faire biper un buzzer pour dire à l'utilisateur "Attention! Tu as relâché le bouton, dépêche toi de réappuyer sur le bouton! ]:smiley: " et lorsque le compte a rebours est terminé, je met l'arduino en veille. Après je ne peu pas vous dire pourquoi je veux faire ça et dans quel contexte, c'est pour un prototype d'invention donc c'est TOP SECRET pour le moment :zipper_mouth_face:

Bon du coup... Mon code ne va pas, je vais refaire ça

Pas besoin de savoir c'est pour faire quoi :wink: la on a toutes les informations :stuck_out_tongue:

tone5846:
Je pensais que ça n'avais pas d'importance de décrire exactement ce que je voulais mettre dans les conditions, mais puisque c'est nécessaire: lorsque j'appuie sur le bouton, le compte a rebours démarre et lorsque je le relâche, il se stop sur sa dernière valeur et redémarre ensuite sur sa dernière valeur lorsque je rappuie sur le bouton, et donc lorsque le bouton est relâché, je voudrais faire clignoter une led et faire biper un buzzer pour dire à l'utilisateur "Attention! Tu as relâché le bouton, dépêche toi de réappuyer sur le bouton! ]:smiley: " et lorsque le compte a rebours est terminé, je met l'arduino en veille. Après je ne peu pas vous dire pourquoi je veux faire ça et dans quel contexte, c'est pour un prototype d'invention donc c'est TOP SECRET pour le moment :zipper_mouth_face:

donc pas grand chose a voir avec le code :wink:
moi je verrais un truc de ce genre

rebours = 0
rebours_ancien = 0
rebours_start = XXXX secondes

loop
si rebours_ancien > 0  ET bouton = LOW => rebours = rebours_ancien ET led_alerte =>allumée
si rebours_ancien = 0 => rebours = rebours_start

while bouton appuyé => rebours
rebours_ancien = rebours
si rebours = 0 => led_fin => allumée ET bouton = LOW
si rebours > 0 => led_fin => off 
fin while

Alors en fait j’ai un peu raconté n’importe quoi, je me suis emmêlé les pinceau et du coup je me suis vraiment éloigné du problème principal, alors déjà je vais vous montrer mon code tel qu’il était quand j’ai eu le problème:

const int bouton = 4;
//////// VARIABLES UTILISEES POUR CHRONO ////////
unsigned long ste; // Temps qui s'écoule
unsigned long currentMillis = 0;    // Millis actuel
unsigned long lastMillis = 0;       // Millis sauvegardé
unsigned long elapsedMillis = 0;    // Millis écoulé entre currentMillis et lastMillis
unsigned long counter = 20000;          // Valeur du chrono
unsigned long counterPrint = 0;     // Valeur du chrono lors du dernier print
//////// VARIABLES UTILISEES POUR CONTROLE NIVEAU BATT ////////
int ValeurLue;
float tension ;
/////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////
const int led = 12;
const int led2 = 11;
void setup() {
	
	pinMode(led, OUTPUT);
	pinMode(led2, OUTPUT);
	Serial.begin(9600);
	
	pinMode(bouton, INPUT);

}

void loop() {
	
	// Mise à jour des temps currentMillis, elapsedMillis et lastMillis
	// Note : vu que loop est exécutée des millions de fois par seconde, dans 99% des cas,
	//        currentMillis aura la même valeur que lastMillis donc elapsedMillis vaudra 0
	currentMillis = millis();
	elapsedMillis = ( lastMillis - currentMillis );
	lastMillis = currentMillis;
	
	
	// Si le boutopn est enfoncé, on fait tourner le chrono
	if ( digitalRead(bouton) == LOW)
	{
		
		
		
		
		// Ajout du temps écoulé
		ste = counter += elapsedMillis; // le problème se situe peut être ici?
		
		
		
	   // pourtant cela m'affiche bien le décompte o.O
		
		
	 if (ste > 180000) // si le compte a rebours est terminé
	 {
		 digitalWrite(led, HIGH);
	 }
		
		
	}
	
   
   if (digitalRead(bouton) == HIGH)
   {
	   if () // ici je ne sais vraiment pas quoi mettre comme condition :/
	   {
		   
	   }
	   
	   if (ste > 180000) // si le compte a rebours est écoulé
	   {
		   
	   }
	   
	   if (ste < 180000) // si le compte a rebours n'est pas terminé 
	   {
		   
	   }
   }
	
	
		
	
	
}

Donc en fait je veux mettre une condition (ou pas) qui serais vide, dans le cas ou le bouton est à l’état relâché et qu’il n’a pas encore été appuyé, donc que le compte a rebours n’est pas démarré, et le problème c’est que "if (180000 > ste) est toujours vraie, donc lorsque le bouton n’a encore jamais été appuyé, il peut rentrer soit dans la première condition ou je n’ai pas mit le code ou soit dans la dernière…

Des idées de code? :% (Sans trop changer le code du compte a rebours)
Merci

sais pas pourquoi mais ca ressemble à une bombe factice pour airsoft
jetes un oeil ici
http://forum.semageek.com/viewtopic.php?id=54

ton bouton est NO ou NF?
car tu inverse ton HIGH et LOW

tu dis au début que tu dois rester appuyé sur le bouton, mais vu ton code, c'est pas le cas :wink:

Premièrement, initialise ste à 0.

Ensuite, rajoute un petit délai a la fin du loop pour éviter ton problème d’égalité sur elapsedmillis.

Ensuite selon ton branchement et ton bouton il faudra inverser tes HIGH et LOW

En effet si tu branches ton bouton :
soutirage 5V ------- bouton ------ masse
|
|
|
|
Arduino

et qu'il est NO si non pressé

ça veut dire que digitalRead(BP) sera égal a HIGH si tu appuies pas

Si c'est comme ça

soutirage 5V ------- bouton ------ masse
|
|
|
|
Arduino

et qu'il est NO si non pressé

ça veut dire que digitalRead(BP) sera égal a LOW si tu appuies pas

ste = counter += elapsedMillis; comme je l'ai dis plus haut il me semble que ste sera forcément plus grand que counter non ? ça veut dire que ton timer est toujours au dessus de la fin du timer....

Le if ou tu sais pas quoi mettre je vois pas ce que tu voulais en faire...

Enfin, rajoute des Serial.print() pour debugger

C'est la troisième fois que je relis ce fil depuis le début et je n'ai toujours pas compris ce que tu veux faire au final.
Du coup je ne comprends pas non plus ce qui ne fonctionne pas (et je pense ne pas être le seul).

Si tu décrivais clairement l'enchaînement des actions on y comprendrait peut être quelque chose.
De ce que j'ai vaguement compris c'est un système séquentiel. Des actions peuvent être interrompue et/ou reprise. il faut donc décrire toutes les combinaisons possibles avec leur enchaînement sinon dans 10 ans tu y seras encore et nous aussi (ou pas, si on se lasse).
Donc un peu de méthode:
Au départ le programme est dans cette état : .....
Si on fait rien le programme fait telle chose : .....
Si on appuie sur le bouton il se passe ça : .....
Si on le relâche il se passe ça : .....
Et ainsi de suite.

+1, ca rejoins ce que j'avais déjà écris :wink:

infobarquee:
déjà un conseil, papier crayon :wink:
schéma de tout projet avec les conditions

rebours = zéro au départ
appuis bouton => début rebours
appuis de nouveau => ???????
==============> rebours non terminé => on fait quoi?
==============> rebours terminé => on fait quoi?
fin rebours => on fait quoi?

etc.....
une fois ca, c'est 90% du taf de fait pour le code et on trouve mieux la solution pour créer son code