Comment convertir un char en un ...... char!!!!

Hello,

Je me prends le chou mais trop méchament.
C'ette commande fonctionne

sendATcommand("AT+CPBW=,\"+41763334455\",145,\"\"","OK",2000,true,false,true)

Il m'enregistre bien le numéro.

Le truc c'est que le numero n'est pas fix. Voici la fonction.
Je dois récupéerer 'phone_number et l'intégrer dans la commande AT.

void dir_write(char *phone_number)
{  
   // je calcul la longuer du numéro et j'aoute la longuer de la commande 
     char cmd[strlen(phone_number)+21];
     // Je fusionne dans cmd, le tout
     snprintf(cmd,sizeof(cmd),"AT+CPBW=,\"%s\",145,\"\"",phone_number);
   // et là ca bloque
    if(sendATcommand(cmd,"OK",2000,true,false,true))
    {
      #ifdef DEBUG
      Serial.println(F("  Saved"));
      #endif
    }else{
      #ifdef DEBUG
      Serial.println(F("  Not saved"));
      #endif
    }
}

Pourquoi ca fonctionne comme ceci:

sendATcommand("AT+CPBW=,\"+41763334455\",145,\"\"","OK",2000,true,false,true)

et pas qaudn j'utilise la fonction snprintf()

C'est un truc de fou!!!! et j'en suis sure que vous aller régler ceci en un tour de main!!!!

Hello,
Alors ca c'est un point très intéressant et peut être que j'ai choisi une mausvaise manière de faire.

En effet, j'ai plusieurs fonction qui lance une commande comme exemple

boolean sms_read(int sms_pos,char *sms_from_number, char *sms_date, char *sms_time, char *sms_text)
boolean sms_send(int pos, char *sms_text)
void dir_write(char *phone_number)
void dir_read(int pos)

Toutes ces fonctions vont utiliser une commande AT+ dans lesquelles je dois include un parametre.

Donc dans toutes ces fonctions, et uniquement DANS la fonction je déclare la même varaiable

char cmd[12]

Mais j'amais je la déclare en dehor d'une fonction. A mon sens, ca doit fonctionner puisqu'un varibale qui est déclarer dans une fonction est détruite quand on quitte la fonction. Mas, en efet, il convient de se poser la question, si cette méthode de faire est cotrrect!!

L'autre truc, l'exemple la variable phone_number, est bonne. Je dois ternir compte qu'un numero suis n'a pas la même longeur qu'un numéro français ou d'un autre pays. Donc je pensais bien faire en calculant la nombre de caractere de la variable passer en paramètre, d'y ajouter les caractères de la commande utilisé, en y ajouter deux-trois place en plus, au cas ou, ceci pour éviter que la variable cmd soit surchargée.

C'est pourcela que j'ai fait comme ceci.

char cmd[strlen(phone_number)+21];
 //Serial.print("cmd:");Serial.println(sizeof(cmd));
 snprintf(cmd,sizeof(cmd),"AT+CPBW=,\"%s\",145,\"\"",phone_number);

Maintenant, ta remarque m'interpelle et je me pose la question si je fais bien de déclarer la même variable dans divers fonction?
Je pense , en effet, que ceci dois bien être fait avant de comprendre pourquoi ca

sendATcommand("AT+CPBW=,\"+41763334455\",145,\"\"","OK",2000,true,false,true)

ca passe.
Et ca

char cmd[strlen(phone_number)+21];
 //Serial.print("cmd:");Serial.println(sizeof(cmd));
 snprintf(cmd,sizeof(cmd),"AT+CPBW=,\"%s\",145,\"\"",phone_number);
sendATcommand(cmd,"OK",2000,true,false,true)

ca passe pas.

A savoir que le premier paramètre demander dans sendATcommand est un char

uint8_t sendATcommand(char* ATcommand, char* expected_answer1, unsigned int timeout, boolean ln, boolean getResponse, boolean debug_buff)
{

Oui voilà.
J'avais deja regardé ceci, et il m'affichait un truc de correct. J'ai refais le teste et voici exactement, dans l'état actuelle, ce qu'il m'affiche, selon le code que je remets, ci-dessous, pour rapelle.

Il m'affiche ceci:

AT+CPBW=,"+22334445566",145,""

Sachant que j'ai taper dans mon terminal (Serial)

dir,w,+41223344445566

Donc pour rapelle, la commande

void dir_write(char *phone_number)
{
     char cmd[33];
     snprintf(cmd,33,"AT+CPBW=,\"%s\",145,\"\"",phone_number);
     Serial.println(cmd);
    if(sendATcommand(cmd,"OK",2000,false,false,true)) // CA NE MARCHE PAS ET JE PERD MA CONNECTION USB A SE MOMENT LA
   // if(sendATcommand("AT+CPBW=,\"+41761112233\",145,\"\"","OK",2000,true,false,true)) // CA MARCHE
    {
      #ifdef DEBUG
      Serial.println(F("  Saved"));
      #endif
    }else{
      #ifdef DEBUG
      Serial.println(F("  Not saved"));
      #endif
    }
}

Il faut savoir que phone_number est déclarer avant le setup(), donc en dehor d'une command

char phone_number[15] // +33133445566 (12+1) +41762223344(12+1) (J'ai mis 15 au lieux de 13, pour assurer)

Pour rapelle encore, je lance ma commande comme ceci

loop()
{
#ifdef DEBUG
// J'écoute ce qui est tapper dans le terminal Serial.read
serialhwread()
#endif
}
#ifdef DEBUG
void serialhwread(void)
{
  int i=0;
  char inSerial[5]; //inSerial[20]
  boolean error = false;
  
  if (Serial.available() > 0){   
      
      while (Serial.available() > 0) {
        inSerial[i]=(Serial.read());
        delay(10);
        i++;      
       }
    
    inSerial[i]='\0';
   
      /* Write to dir */
// Si les 3 premiers caracteres sont 'dir'
      if(!strncmp(inSerial,"dir",3))
      {
// Je mets dans un array la ligne entrée. le delimiteur est une virgule
// La commande teste est dir,w,+41761112233, pour ecrire (w) +41761112233 dans le phonebook
        splitString(inSerial,splitedString);
//splitedString me retourne
//0.dir
//1.w
//2.+41761112233
        // Si la commande est w
        if(!strncmp(splitedString[1],"w",1))
        {
        // alors appelle la fonction et passe comme paramettre le numéro de téléphone
          
dir_write(splitedString[2]);

        }



// VOILA.
// LES RESTE FONCTION. C'EST BON, C'EST dir_write qu coince
        else if(!strncmp(splitedString[1],"d",1))
        {
          #ifdef DEBUG
            Serial.println(F("> Delete a position from dir"));
          #endif
          if(strlen(splitedString[2]) < 1)
          {
            #ifdef DEBUG
              Serial.println(F("  Could not delete"));
            #endif
          }
          else
          {
            dir_del(atoi(splitedString[2]));
          }
        }
        else if(!strncmp(splitedString[1],"r",1))
        {
          #ifdef DEBUG
            Serial.println(F("> Read dir"));
          #endif
        }
        else if(!strncmp(splitedString[1],"l",1))
        {
          dir_list(10);
        }
        else
        {
          Serial.println(F("Erreur"));
        }
        
      }
    
    // Vide inSerial
    inSerial[0]='\0';
  }
}
#endif

Je crois que j'ai trouvé ou est mon problème.
Quand he récupère un ligne de caractere qui est entré dans mon terminal, Donc en Serial, et qui sera sauver dans un char, il doit ajouter un \0.

Je ne suis as encore convaincu, mais pour le moment ca marche.

J'ai fais le teste ici
//Si je tape, dans mon terminal, d,w,+41761112233, pour sauver le numero dans la peremiere position libre de ma carte SIM
if(!

strncmp(splitedString[1],"w",1))
        {
// Je vrée un char dont sa taille prendra le nombre de caractere de +41761112233 + 1
          char phone[strlen(splitedString[2])+1];
// sprintj ajoute \0 à la fin de la chain. donc il prend la chaine et le met dasn phone ET AJOUTE \0
          sprintf(phone,"%s",splitedString[2]);
          Serial.print(F("Phone : "));Serial.println(phone);
         // Je passe le numero dans ma fonction 
         dir_write(phone);
}

ET CA MARCHE!!! Le programme ne plante plus. Après avoir passer la journée, j'étais convaincu que le problème venais d'un char.

Mais je vais encore fait des testes.

@_pepe
J'aimerais juste reboudir sur ceci

Je corrige ce que j'ai indiqué plus haut.
Le compilateur C++ est parfaitement capable de calculer la taille de la variable locale allouée sur la pile.

On est alors d'accord, que ceci est correct alors?

char phone[strlen(splitedString[2])+1];

OK, j'ai une dernier question.
he remarque que mon programme plante souvent au moment d'un Serial.print
Typiquement, il a planté en affichant ceci
Serial.println(F(">  Number must be havee 12 digits, including the + for country code."));!

Même si j'ai mis en F, es-ce qu'on est limiter dans la longeur du text a afficher?
et es-ce qu'on est limiter dans le nombre de Serial.println?

En effet, j'en utilise beaucoup!!

J'ai constaté que meme si je perds la connection USB, le Arduino continue a tourner.
C'est un peu embetant et je me demande si la perde de connection est de "ma faute".
Quoi qu'il en soit je vais faire avec et je vais diminuer mes Serial.print() ainsi que le texte de debugage a afficher.
Merci

pierrot10:
OK, j'ai une dernier question.
he remarque que mon programme plante souvent au moment d'un Serial.print
Typiquement, il a planté en affichant ceci
Serial.println(F(">  Number must be havee 12 digits, including the + for country code."));!

Même si j'ai mis en F, es-ce qu'on est limiter dans la longeur du text a afficher?
et es-ce qu'on est limiter dans le nombre de Serial.println?

F() récupérant la chaine dans la flash au lieu de la RAM, c'est bien plus lent qu'en RAM. Il faudrait voir si ce n'est pas la qu'est le piège : entre vitesse de liaison série, USB et timeout (côté PC ou Arduino).

Tu es à quelle vitesse série la ?

Hello,
je suis à 9600