Soucis pour sortir d'une tempo

Bonjour à tous!

Voila, je fait appelle à vous car je rencontre un soucis pour gérer une sortie de tempo!

mon programme est basique mais je tourne en rond!

je veux modifier l'état d'une led en 3 états :

  • État 1 : Allumée;
  • État 2 : Éteinte;
  • État 3 : clignote.

Ce choix d'état se fait pour l'instant via les commande du moniteur Série.

Je n'ai aucun soucis pour changer d'état sauf pour le 3ème (clignotement!).

J'ai essayé avec des Switch case, des If, et des While.

Actuellement je suis avec des whiles :

int b=13; 
const unsigned long BLINK_INTERVAL1 = 500;
const unsigned long BLINK_INTERVAL2 = 1000;
void setup() {

pinMode(13,OUTPUT); // MOC3041 negatif
digitalWrite(b,LOW);
Serial.begin(9600); //débute la communication avec le moniteur série
Serial.println("*********\nListe des ordres\n*********");
}

void loop() {
  if (Serial.available()) { //teste s'il y a une saisie en attente
  String chaine = ""; // création d'un String vide
  //lecture de la saisie
  while (Serial.available()) { //tant que caractères en attente.
    delay(10); //petit délai de lecture
    char c = Serial.read(); //on lit le message
    Serial.println (c);
    if (c != 10 && c != 13) { //nettoyage de la chaine
      chaine += c; //on ajoute le caractère
    }
  }
  //test de la saisie
  while (chaine == "1") { 
    Serial.println("Marche");
    digitalWrite(b,HIGH);
    return;
  }
  while (chaine == "2") { 
    Serial.println("Arrêt");
    digitalWrite(b,LOW);
    return;
  }
   while (chaine == "3") { 
   Serial.println("Clignote");
   digitalWrite(b,LOW);
   delay(200); 
   digitalWrite(b,HIGH);
   delay(200); 
   return;
   }
}
}

Ici, je peut basculer indéfiniment d'un état à l'autre, mais ma diofde ne clignote q'une seule fois!

Si je modifie comme ceci (suppression de return) :

 while (chaine == "3") { 
   Serial.println("Clignote");
   digitalWrite(b,LOW);
   delay(200); 
   digitalWrite(b,HIGH);
   delay(200); 
   //return;
   }

Alors, ma diode clignote mais je ne peut plus changer d'état!

J'ai essayer avec break, pas mieux.

J'ai tenter de supprimer les delay() par des fonctions "Blink without delay" comme décrit ici :
http://www.mon-club-elec.fr/pmwiki_reference_arduino/pmwiki.php?n=Main.ExempleBlinkWithoutDelay
ou là :

Mais sans succès!

Un peu d'aide et/ou d'explication sont les bienvenues!

J'ai apporter deux modification.

Avec ton code, le fonction n'étaient executées seulement si le un nouveaucarractère arrivait sur le port série.
Avec la modification,
Tour à tour, on vérifie la présence d'un caractère et on modifie la valeur de "chaine" si présence.
et execute l'une de boucle while en fonction de la valeur de "chaine".

int b=13; 
const unsigned long BLINK_INTERVAL1 = 500;
const unsigned long BLINK_INTERVAL2 = 1000;
void setup() {

pinMode(13,OUTPUT); // MOC3041 negatif
digitalWrite(b,LOW);
Serial.begin(9600); //débute la communication avec le moniteur série
Serial.println("*********\nListe des ordres\n*********");
}

void loop() {
  if (Serial.available()) { //teste s'il y a une saisie en attente
  String chaine = ""; // création d'un String vide
  //lecture de la saisie
  while (Serial.available()) { //tant que caractères en attente.
    delay(10); //petit délai de lecture
    char c = Serial.read(); //on lit le message
    Serial.println (c);
    if (c != 10 && c != 13) { //nettoyage de la chaine
      chaine += c; //on ajoute le caractère
    }
  }
  //test de la saisie
  while (chaine == "1") { 
    Serial.println("Marche");
    digitalWrite(b,HIGH);
    return;
  }

} // modification leptro : ajouter l'accolade ici
  while (chaine == "2") { 
    Serial.println("Arrêt");
    digitalWrite(b,LOW);
    return;
  }
   while (chaine == "3") { 
   Serial.println("Clignote");
   digitalWrite(b,LOW);
   delay(200); 
   digitalWrite(b,HIGH);
   delay(200); 
   return;
   }
// }     // modification leptro :supprimer cette accolade
}

Salut Leptro!

Je viens de coller ton code, et il me donne des erreurs :

boucle2:33: error: 'chaine' was not declared in this scope

while (chaine == "2") {

^

boucle2:38: error: 'chaine' was not declared in this scope

while (chaine == "3") {

^

exit status 1
'chaine' was not declared in this scope

j'ai l'impression que ta 1ère accolade ferme à présent mon if derrière mon 1er while ! ??

Commencez par sortir votre variable "chaine" de la fonction loop() pour la placer en haut de votre application, avant le setup(). Ainsi, elle ne sera pas réinitialisée à chaque passage dans la loop().

Après, enlevez tous les while() et remplacez-les par des if()

La variable chaine étant mémorisée, il n'y a qu'un changement fait dans la console série qui viendra changer sa valeur par un test if().

Cordialement.

Pierre

Bonjour Pierre,

Alors j'ai remplacé mais while par if, cela me permet de changer d'état à chaque comande, mais ma diode ne clignote pas en état 3.

int b=13;
const unsigned long BLINK_INTERVAL1 = 500;
const unsigned long BLINK_INTERVAL2 = 1000;


void setup() {
pinMode(13,OUTPUT); // MOC3041 negatif
digitalWrite(b,LOW);
Serial.begin(9600); //débute la communication avec le moniteur série
Serial.println("*********\nListe des ordres\n*********");
}

void loop() {
  String chaine = ""; // création d'un String vide
  if (Serial.available()) { //teste s'il y a une saisie en attente
    //lecture de la saisie
  while (Serial.available()) { //tant que caractères en attente.
    delay(10); //petit délai de lecture
    char c = Serial.read(); //on lit le message
    Serial.println (c);
    if (c != 10 && c != 13) { //nettoyage de la chaine
      chaine += c; //on ajoute le caractère
    }
  }
  //test de la saisie
  if (chaine == "1") {
    Serial.println("Marche");
    digitalWrite(b,HIGH);
    }
  if (chaine == "2") {
    Serial.println("Arrêt");
    digitalWrite(b,LOW);
    }
   if (chaine == "3") {
   Serial.println("Clignote");
   digitalWrite(b,LOW);
   delay(200);
   digitalWrite(b,HIGH);
   delay(200);
   }
}  
}

Commencez par sortir votre variable "chaine" de la fonction loop() pour la placer en haut de votre application, avant le setup(). Ainsi, elle ne sera pas réinitialisée à chaque passage dans la loop().

j'ai placé " String chaine = ""; // création d'un String vide" tout en haut de mon code avec le "int b=13"

Là, mon 1er ordre est reconnu et plus les autres!

Il faut que vous sortiez les 3 cas d'allumage des accolades englobantes de votre :

if (Serial.available()) {} // Les 3 cas doivent être placés après cette accolade

Cordialement.

Pierre

Bonsoir,
Désolé pour la réponse un peu rapide (aux vues des fautes de frappes et d'orthographes)

En appliquant ma remarque et celle de ChPr, ça devrait compiler comme il se doit.

Je te laisse tester en vraie ce que ça donne.

int b=13; 
const unsigned long BLINK_INTERVAL1 = 500;
const unsigned long BLINK_INTERVAL2 = 1000;
String chaine = ""; // création d'un String vide
void setup() {

pinMode(13,OUTPUT); // MOC3041 negatif
digitalWrite(b,LOW);
Serial.begin(9600); //débute la communication avec le moniteur série
Serial.println("*********\nListe des ordres\n*********");

}

void loop() {
  if (Serial.available()) { //teste s'il y a une saisie en attente
  //String chaine = ""; // création d'un String vide
  //lecture de la saisie
  while (Serial.available()) { //tant que caractères en attente.
    delay(10); //petit délai de lecture
    char c = Serial.read(); //on lit le message
    Serial.println (c);
    if (c != 10 && c != 13) { //nettoyage de la chaine
      chaine += c; //on ajoute le caractère
    }
  }
  }
  //test de la saisie
 if (chaine == "1") { 
    Serial.println("Marche");
    digitalWrite(b,HIGH);
   // return;
  }
  if (chaine == "2") { 
    Serial.println("Arrêt");
    digitalWrite(b,LOW);
   // return;
  }
   if (chaine == "3") { 
   Serial.println("Clignote");
   digitalWrite(b,LOW);
   delay(200); 
   digitalWrite(b,HIGH);
   delay(200); 
   //return;
   }
//}
}

Par ailleurs, je pense que vous pouvez avantageusement remplacer :

 if (Serial.available()) { //teste s'il y a une saisie en attente
    //String chaine = ""; // création d'un String vide
    //lecture de la saisie
    while (Serial.available()) { //tant que caractères en attente.
      delay(10); //petit délai de lecture
      char c = Serial.read(); //on lit le message
      Serial.println (c);
      if (c != 10 && c != 13) { //nettoyage de la chaine
        chaine += c; //on ajoute le caractère
      }
    }
  }

par :

 if (Serial.available()) { //teste s'il y a une saisie en attente
    //lecture de la saisie
    chaine = Serial.readString();

L'instruction readString() faisant automatiquement tout ce que vous faites.

Cordialement.

Pierre

Bonsoir Messieurs,

Je viens de tester, ça ne fonctionne pas.

Mon meilleur code est :

int b=13;

void setup() {

pinMode(13,OUTPUT); // MOC3041 negatif
digitalWrite(b,LOW);
Serial.begin(9600); //débute la communication avec le moniteur série
Serial.println("*********\nListe des ordres\n*********");

}

void loop() {
  String chaine = ""; // création d'un String vide
  if (Serial.available()) { //teste s'il y a une saisie en attente
    while (Serial.available()) { //tant que caractères en attente.  
    delay(10); //petit délai de lecture
    char c = Serial.read(); //on lit le message
    Serial.println (c);
    if (c != 10 && c != 13) { //nettoyage de la chaine
      chaine += c; //on ajoute le caractère
    }
  }
  }
  //test de la saisie
 if (chaine == "1") {
    Serial.println("Marche");
    digitalWrite(b,HIGH);
  }
  if (chaine == "2") {
    Serial.println("Arrêt");
    digitalWrite(b,LOW);
  }
   if (chaine == "3") {
   Serial.println("Clignote");
   digitalWrite(b,LOW);
   delay(200);
   digitalWrite(b,HIGH);
   delay(200);
   }
}

je peut changer autant de fois d'état!

Le seul soucis, c'est que ma diode ne clignote qu'une fois, alors que je voudrais qu'elle continu jusqu'au changement d'état suivant!

j'envisage presque de piloter un NE555 via une autre sortie.

Votre meilleur code ne fait pas clignoter la LED.

Celui que je vous ai suggéré fait les trois fonctions. Le voici :

int b = 13;
String chaine = ""; // création d'un String vide

void setup() {

  pinMode(13, OUTPUT); // MOC3041 negatif
  digitalWrite(b, LOW);
  Serial.begin(9600); //débute la communication avec le moniteur série
  Serial.setTimeout(50); // Pou diminuer le temps de prise en compte de la chaîne venant du moniteur série : non indispensable
  Serial.println("*********\nListe des ordres\n*********");

}

void loop() {
  if (Serial.available()) { //teste s'il y a une saisie en attente
    chaine = Serial.readString();
  }
  //test de la saisie
  if (chaine == "1") {
    Serial.println("Marche");
    digitalWrite(b, HIGH);
  }
  if (chaine == "2") {
    Serial.println("Arrêt");
    digitalWrite(b, LOW);
  }
  if (chaine == "3") {
    Serial.println("Clignote");
    digitalWrite(b, LOW);
    delay(200);
    digitalWrite(b, HIGH);
    delay(200);
  }
}

Mais ce code est perfectible en remplaçant les delay() par des millis() ...

Cordialement.

Pierre

Genial Pierre cela fonctionne!

A moi de décortiquer tout ça et de mieux apprendre!

Damien35:
... A moi de décortiquer tout ça et de mieux apprendre!

Regardez avec intérêt les différences entre variables locales et globales.

Quand vous avez utilisé "chaine" dans la fonction "loop()", elle l'était en tant que variable locale et était réinitialisée à chaque passage.

L'ayant mise avant le setup() et donc hors d'une fonction, moi, je l'ai déclarée en tant que variable globale, elle est vue de partout et n'est pas automatiquement réinitialisée par une fonction qui l'utilise. C'est pourquoi le test sur la variable "chaine" reste consistant, alors même qu'il n'y a rien à lire sur la console série.

Mais chacun de ces types de variable présente des avantages et des inconvénients.

Cordialement.

Pierre