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;
}
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?
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
Bien vu infobarquee , ce serait plus logique de mettre un "!="
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é?
déjà un conseil, papier crayon
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! ] " 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
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! ] " 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
donc pas grand chose a voir avec le code
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
ç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...
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.
infobarquee:
déjà un conseil, papier crayon
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