Commandes utilisateur

Le script suivant comporte une fonction évoluée acquisition_commandes()  permettant à l’utilisateur de passer des commandes assez complexes à l’Arduino par l’intermédiaire d’un moniteur série.

Attention : le moniteur série de l’IDE Arduino doit être en mode « Retour chariot ».

 

 

/*
Permet a la carte arduino de recuperer des consignes donnees par l'operateur par l'intermediaire du moniteur serie.
L'operateur saisit au clavier dans le moniteur serie une lettre suivi d'un nombre.
Exemples : t10, c21, z0.3 (puis touche "entree")
La lettre indique la variable que l'on souhaite modifier (ou la commande que l'on souhaite effectuer).
Le nombre indique la nouvelle valeur de la variable.

t10
  t indique que l'on souhaite modifier la variable te_ms.
  10 indique la nouvelle valeur de te_ms.
  
c21
  c indique que l'on souhaite modifier la variable xcibl.
  21 indique la nouvelle valeur de xcibl.

z0.3
  z indique que l'on souhaite modifier la variable z.
  0.3 indique la nouvelle valeur de z.

La fonction Val_ent permet de transformer la sequence de caracteres saisis au clavier en variable entiere.
La fonction Val_flt permet de transformer la sequence de caracteres saisis au clavier en variable flottante.

Pour marquer la fin de la sequence de caracteres saisis au clavier, il faut configurer le moniteur serie de maniere a ce qu'il ajoute un "Retour chariot" en fin de sequence.
  
*/
int te_ms = 0;
int xcibl = 0;
const char LF = '\n'; // caractere LineFeed (nouvelle ligne)
// const char CR = '\r'; // caractere CarriageReturn (retour chariot)
float z = 0;

void setup() {
  Serial.begin(9600);
}

void loop() {
   acquisition_commandes();
}



/*********************************************************************************************/
void acquisition_commandes() {
   byte cx, ch; int i, Val_e; float Val_f;
   if (Serial.available()){
      cx = Serial.read();

      switch (cx) {

         case 116 : // 116 : code ascii de t (periode echantillonnage)
         Val_e = Val_ent();
         if ( Val_e >= 1 && Val_e <= 16) {te_ms = Val_e;}
         Serial.print("te_ms = "); Serial.print(te_ms); Serial.println(" ms"); Serial.print(LF);
         break; // fin cas 116

         case 99 : // 99 : code ascii de c (consigne position pour echelon)
         Val_e = Val_ent();
         if ( Val_e >= -32767 && Val_e <= 34000) {xcibl = Val_e;}
         Serial.print("position cible = "); Serial.print(xcibl); Serial.println(" mm"); Serial.print(LF);
         break; // fin cas 99

         case 122 : // 122 : code ascii de z
         Val_f = Val_flt();
         if ( Val_f >= -20 && Val_f <= 20) {z = Val_f;}
         Serial.print("z = "); Serial.print(z,2); Serial.print(LF); Serial.print(LF);
         break; // fin cas 122

         default :
         long tdl = millis();
         while ((cx != 13) && (millis() - tdl < 10)) {if (Serial.available()) {cx = Serial.read();}}
         if (cx != 13) {while (Serial.available()) {Serial.read(); delay(10);} Serial.println("Lecture hors temps ou pas de CR"); Serial.print(LF);}

      } // fin switch
   } // fin si
} // fin fonction



/**********************************************************************************************/
int Val_ent(){ // (-32767 <= Val_ent <= 32767) (avec caractere de fin CR) (avec timeout)
   const byte nbc = 5; // nb de chiffre de l'entier
   byte sgn = 0, ch = 0, e_c = 1; unsigned int Val_e = 0; long tdl = millis();

   do {if (Serial.available()) {
      ch = Serial.read();  
      if (1 <= e_c && e_c <= nbc + 1) {
         if (ch == 45 || ch == 43 && sgn == 0 && e_c == 1) {sgn = ch;}// 43 et 45 : codes ascii de + et -
         else if ((ch < 48 || ch > 58) && ch != 13) {e_c = 0;} // le caractere n'est pas un chiffre (48 à 58 : codes ascii de 0 à 9)
         else if (ch != 13) {Val_e = 10 * Val_e + (ch - 48); ++e_c;}}
      }}
   while ((ch != 13) && (millis() - tdl < 10)); // fin de lecture : caractere de fin ou timeout

   if (ch != 13) {
      while (Serial.available()) {Serial.read(); delay(10);}; Serial.println("Lecture hors temps ou pas de CR");
      return -32768;}
   else {if (sgn == 0) {sgn = 43;}
      if (2 <= e_c && (e_c <= nbc + 1) && Val_e <= 32767) { return (44 - sgn) * Val_e;} else {return -32768;}}
}



/**********************************************************************************************/
float Val_flt(){ // (avec caractere de fin CR) (avec timeout)
   const byte nba = 2, nbp = 2; // nba nombre maxi de chiffres saisis du flottant avant la virgule, nbp nombre maxi de chiffres saisis apres la virgule
   byte sgn = 0, ch = 0, e_c = 1, e_p = 0; unsigned int Val_f = 0; long tdl = millis();

   do {if (Serial.available()) {
      ch = Serial.read();  
      if (1 <= e_c && e_c <= nba + nbp + 1) {
         if (ch == 45 || ch == 43 && sgn == 0 && e_c == 1) {sgn = ch;}// 43 et 45 : codes ascii de + et -
         else if (ch == 46 && e_p == 0) {e_p = e_c;}
         else if ((ch < 48 || ch > 58) && ch != 13) {e_c = 0;} // le caractere n'est pas un chiffre (48 à 58 : codes ascii de 0 à 9)
         else if (ch != 13) {Val_f = 10 * Val_f + (ch - 48); ++e_c;}}
      }}
   while ((ch != 13) && (millis() - tdl < 50)); // fin de lecture : caractere de fin ou timeout

   if (ch != 13) {
      while (Serial.available()) {Serial.read(); delay(10);}; Serial.println("Lecture hors temps ou pas de CR");
      return pow(10,nba);}
   else {if (sgn == 0) {sgn = 43;} if (e_p == 0) {e_p = e_c;}
      if (2 <= e_c && (e_c <= nba + nbp + 1) && e_c - e_p <= nbp && e_p <= nba + 1) {return (44 - sgn) * float(Val_f) * pow(10,(e_p - e_c));}
      else {return pow(10,nba);}}
}

 

Vous aimerez aussi...

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *