projet crepp_git/crepp-projects/simplecdbot · branche main
Utils.cpp~ Voir sur GitLab
/*
 * Copyright (c) 2012 by Xavier HINAULT - support@mon-club-elec.fr
 *
 * This file is free software; you can redistribute it and/or modify
 * it under the terms of either the GNU General Public License version 3
 * or the GNU Lesser General Public License version 3, both as
 * published by the Free Software Foundation.
 */

#include "Arduino.h"
#include "Utils.h"


  Utils::Utils(){
 
  }
  

//------- fonction d'attente d'un String sur le port Série ----- 
String Utils::waitingString(boolean debugIn) {


    int octetReception=0; // variable de réception octet
    char caractereReception=0; // variable de réception caractère
    String chaineOut=""; // chaine renvoyée


  while (Serial.available()>0) { // si un caractère en réception
    
    octetReception=Serial.read(); // lit le 1er octet de la file d'attente    

    if (octetReception==10) { // si Octet reçu est le saut de ligne 
          if (debugIn)Serial.print ("Saut de ligne recu : ");          
           if (debugIn)Serial.print ("Chaine = "); // affiche la chaine recue
           if (debugIn)Serial.println (chaineOut); 
          delay(100); // pause
          break; // sort de la boucle while
    } // fin if 
    
    else { // si le caractère reçu n'est pas un saut de ligne        

          caractereReception=char(octetReception);
          chaineOut=chaineOut+caractereReception; 
          delay(1); // laisse le temps au caractères d'arriver
          
    } // fin else 

   } // fin while - fin de réception de la chaine
  
  return(chaineOut); 
}

//-- forme sans drapeau  
String Utils::waitingString() {

	return(waitingString(false)); 
}
	
//------- fonction d'attente d'une chaine donnée sur le port Série 
void Utils::waitForString(String stringForWaitIn) {
 
   while (waitingString(true)!=stringForWaitIn); // attend tant que pas reçu chaine voulue
 
} // fin waitToString

//---------------- testInstructionString() : test si instruction de la forme instruction(*****) ----------

//boolean Utils::testInstructionString (String chaineTest, String  chaineRefIn, String paramStringIn) {

//boolean Utils::testInstructionString (String chaineTest, String  chaineRefIn) {
  
String Utils::testInstructionString (String chaineTest, String  chaineRefIn, boolean debugIn) {

     int posRef=chaineTest.length();// position de référence pour analyse (xxx) 
     
    String paramString; // le String reste "null" tant que pas initialisé par =""

     //if (chaineReception.substring(0,posRef)==chaineTest) { // si reçoit l'instruction chaineTest(

     if (chaineRefIn.substring(0,posRef)==chaineTest) { // si reçoit l'instruction chaineTest(
     
         if (debugIn) Serial.print(F("Arduino va executer : ")); 

         if (debugIn) Serial.print(chaineTest); // affiche 
 
     paramString=chaineRefIn.substring(posRef,chaineRefIn.length()-1); // extrait la chaine de caractere recue en parametre 
     
     //Serial.println(chaineReception.length()); 
     if (debugIn)Serial.print(paramString); //affiche la chaine de caractere
     
     if (chaineRefIn.substring(chaineRefIn.length()-1,chaineRefIn.length())==")") { // si fermeture parenthèse = instruction valide
  
       if (debugIn) Serial.println(F(")")); // affiche
       if (debugIn) Serial.println(F("Instruction valide !")); // affiche
      return(paramString); // renvoie true si instruction valide 
      
    } // fin si fermeture parenthèse

    else { // si chaine test absente 
            
       if (debugIn) Serial.println(F("Instruction invalide !")); // affiche
      return(0); // renvoie null 
 
    } // fin else
    
     } // fin si recoit chaineTest(
     
          else { // si pas bonne chaine Test présente
     
           if (debugIn) Serial.print(F(".")); // affiche
          return(0); // renvoie null si instruction invalide
          
     } // fin else 

 
     
} // fin test instruction String

//--- forme dans debug
String Utils::testInstructionString (String chaineTest, String  chaineRefIn) {

	return(testInstructionString(chaineTest, chaineRefIn, false)); 

} // fin forme dans debug

//--------------- testInstruction2 : test si instruction de la forme instruction(xxx, xxx, xxx, xxx, xxx) ou moins ------------

//long* Utils::testInstruction2(String chaineReception, String chaineTest, int nbParam) { // reçoit chaine  et renvoie un tableau de long
boolean Utils::testInstruction2(String chaineReception, String chaineTest, int nbParam, long paramsIn[]) { // reçoit chaine  et renvoie un booléen et modifie tableau
  
  long posRef=chaineTest.length();// position de référence pour analyse (xxx) 
  int posDecal=0; // nombre de position à décaler... 
  

  //long *arrayParamsOut=new long[nbParam];
  //long *arrayParamsOut=new long(2);  // avec des parenthèses... pas des crochets
  // arrayParamsOut=0; //le pointeur est null 

  //long static arrayParamsOut[12]; // tableau statique jusqu'à 12 paramètres - c'est assez...  

  //paramsIn[0]=0; // test

  if (chaineReception==chaineTest+")") { // si reçoit l'instruction chaineTest() - on renvoie false d'emblée

     Serial.println(F("Instruction invalide !")); // affiche
      //arrayParamsOut=0;
      return(false); // renvoie 0 (équiv null en C++) si instruction invalide
 
  }
  else if (chaineReception.substring(0,posRef)==chaineTest) { // si reçoit l'instruction chaineTest(000)
  // nb substring : dernier caractere exclu

    Serial.print(F("Arduino va executer : ")); 

    Serial.print(chaineTest); // affiche 
    
    for (int i=0; i<nbParam; i++) { // défile les n paramètres
    
          
    
        if (chaineReception.substring(posRef,posRef+1)=="-") { // si signe - présent on décale de 1 position la prise en compte du nombre xxx
        
          posRef=posRef+1; // modif valeur posRef

          //-------- détermine le nombre de caractères du nombre suivant ---- 
          posDecal=0; // RAZ posDecal
          
          while (
                (chaineReception.substring(posRef+posDecal,posRef+posDecal+1)!=",") // défile les caractères suivants jusqu'à virgule
                && (chaineReception.substring(posRef+posDecal,posRef+posDecal+1)!=")") // et jusqu'à parenthèse fermée
                && (posDecal<10) // ou limite pour nombre caractères
                ){ 
            //Serial.print(chaineReception.substring(posRef+posDecal,posRef+posDecal+1)); // debug
            posDecal=posDecal+1; // ajoute un caractère de décalage 
            //Serial.println (" posDecal="+posDecal); // debug
            // delay(1000); // debug
            
          } // fin while 

          //--- extrait la valeur en tenant compte du -           
          paramsIn[i]=(-1)*stringToLong(chaineReception.substring(posRef,posRef+posDecal)); // extraction valeur n chiffres à partir caractères et * par -1
        
        } // fin if 
        
        else { // si pas de signe -         

          //-------- détermine le nombre de caractères du nombre suivant ---- 
          posDecal=0; // RAZ posDecal
          
          while (
                (chaineReception.substring(posRef+posDecal,posRef+posDecal+1)!=",") // défile les caractères suivants jusqu'à virgule
                && (chaineReception.substring(posRef+posDecal,posRef+posDecal+1)!=")") // et jusqu'à parenthèse fermée
                && (posDecal<10) // ou limite pour nombre caractères
                ){ 
            //Serial.print(chaineReception.substring(posRef+posDecal,posRef+posDecal+1)); // debug
            posDecal=posDecal+1; // ajoute un caractère de décalage 
            //Serial.println (" posDecal="+posDecal); // debug
            // delay(1000); // debug
            
          } // fin while 
    
          // extrait la valeur -- 
          // params[i]=stringToLong(chaineReception.substring(posRef,posRef+3)); // extraction valeur 3 chiffres à partir position
          paramsIn[i]=stringToLong(chaineReception.substring(posRef,posRef+posDecal)); // extraction valeur n chiffres à partir position
          
        } // fin else 
        
        Serial.print( paramsIn[i]); // affiche 
        
        //Serial.println(posDecal); // debug
        
        //Serial.println(chaineReception.substring(posRef+posDecal,posRef+posDecal+1)); // debug
        
        //if ((chaineReception.substring(posRef+3,posRef+4)==",")&& ((posRef+4)<(chaineTest.length()+(nbParam*4)-1))) { // si virgule attendue présente et si pas long maxi
        //if ((chaineReception.substring(posRef+posDecal,posRef+posDecal+1)==",") && ((posRef+posDecal+1)<(chaineTest.length()+(nbParam*4)-1))) { // si virgule attendue présente et si pas long maxi
	if ((chaineReception.substring(posRef+posDecal,posRef+posDecal+1)==",") && ((posRef+posDecal+1)<chaineReception.length()) && (i!=nbParam-1)) { // si virgule attendue présente et si pas long maxi et si pas dernier paramètre 
        
          Serial.print(","); // affiche
          posRef=posRef+posDecal+1; //décale position de référence de n+1 caractères pour prise en compte nouvelle valeur
  
        } // fin if "," 
  
	else if( (chaineReception.substring(posRef+posDecal,posRef+posDecal+1)==")") && (i!=nbParam-1) ){ // si parenthèses avant nombre de paramètres attendus = invalide

      Serial.println(F("Instruction invalide !")); // affiche

      return(false); // renvoie false si instruction invalide

	}
      
    } // fin for nbParam

   //----- une fois tous les paramètres lus 
    //if ( (chaineReception.substring(posRef+posDecal,posRef+posDecal+1)==")") && (posDecal<=1)){ // si fermeture parenthèse et si un décalage depuis dernière virgule = instruction valide
  if (chaineReception.substring(posRef+posDecal,posRef+posDecal+1)==")") { // si fermeture parenthèse et si aucun décalage depuis dernière valeur = instruction valide
  
      Serial.println(F(")")); // affiche
      Serial.println(F("Instruction valide !")); // affiche
      //return(true); // renvoie true si instruction valide 
     //return arrayParamsOut; 
     return(true); // renvoie 0 (équiv null en C++) // test debug 
      
    } // fin si fermeture parenthèse
    
    else { 
            
      Serial.println(F("Instruction invalide !")); // affiche
      //arrayParamsOut=0;
      return(false); // renvoie 0 (équiv null en C++) si instruction invalide
 
    } // fin else
     
  } // fin si reçoit l'instruction chaineTest(000)
   
 

} // fin fonction testInstruction2  

//------------------- fin test instruction2 ------------ 

//---- fonction idem avec nom plus explicite --- 
boolean Utils::testInstructionLong(String chaineReception, String chaineTest, int nbParam, long paramsIn[]) { 

	return(testInstruction2(chaineReception,chaineTest, nbParam, paramsIn[])); 

} // fin testInstructionLong


// ---------- fonction de conversion d'un String numérique en long

long Utils::stringToLong(String chaineLong) { // fonction conversion valeur numérique String en int

    long nombreLong=0; // variable locale 
    int valeurInt=0; // variable locale

    for (int i=0; i<chaineLong.length(); i++) { // défile caractères de la chaine numérique

      valeurInt=chaineLong.charAt(i); // extrait le caractère ASCII à la position voulue - index 0 est le 1er caractère 
      valeurInt=valeurInt-48; // obtient la valeur décimale à partir de la valeur ASCII  

     if (valeurInt>=0 && valeurInt<=9) { // si caractère est entre 0 et 9
       nombreLong=(nombreLong*10)+valeurInt;
     } // fin si caractère est entre 0 et 9


    } // fin for défile caractères

 return (nombreLong); // renvoie valeur numérique

} // ---------- fin stringToLong ------------