Problème de réception SMS – MODULE GSM A6

Bonjour,
J’utilise un module GSM A6 avec la carte arduino mega.
Pour assurer la communication avec le module GSM A6 j’ai utilisé le Sérial1, et le Serial avec le PC.
Après réalisation du programme et consultation de divers forums, je suis parvenu à réaliser un programme qui extrait le texte des SMS reçus, et de les transférer dans une variable de type String. Cette variable sera par la suite transférée vers le PC via la communication série.
Après plusieurs essais, j’ai remarqué que le programme affiche correctement le texte du premier SMS reçu (Exemple SMS : @CDITEXT! Avec @ : Position de début et ! : Position de fin)
Le problème que j’ai remarqué, c’est que le premier SMS est réceptionné correctement, mais lorsque j’envoie un deuxième ou un troisième SMS de mon téléphone vers le numéro du module GSM, l’arduino retourne le texte du premier SMS. Et ceci est parfait statique et parfois aléatoire.
J’ai essayé de mettre les variables à zéro, mais c’est le même problème.
S’il vous plaît est-ce que quelqu'un peut m’aider à diagnostiquer et à résoudre ce bug de programme ?

String message = ""; // message reçu du module GMS
int start = 0; //Position caractére Start
int endsend = 0; // Position caractére fin
String code_alarme = ""; //Code alarme après traitement
int index = 0;
int i=0;
String recu_1,recu_2,recu_3;
int longeur=0;
String transfert;

void setup() {

  // initialize both serial ports:

  Serial.begin(9600);

  Serial1.begin(9600); // Serial 1 Tx_18 , RX_19

  delay(5000);

  Serial1.println("AT"); // Lancement module GMS
  delay(100);
  Serial1.println("AT+CMGF=1"); // Lancement mode SMS
  delay(100);
  // Set module to send SMS data to serial out upon receipt
  Serial1.println("AT+CNMI=2,2,0,0,0"); // En attente reception
  delay(100);

}

void loop() {

  // read from port 1, send to port 0:

  if (Serial1.available()) {
  
  message = Serial1.readString(); // Lire communication série avec module GSM
  longeur=message.length(); // Lire longeur reçu
  message.setCharAt(longeur-1,'\t'); // elimination dérnière ligne
  message.trim(); // elimination des espace
  transfert=message.substring(60,longeur); //Trasfert message dans variable transfert
  Serial.println(transfert);
  index=transfert.indexOf("@"); // Détection début SMS
  Serial.println(index);
  transfert=transfert.substring(index); //Extraire text à partir de début SMS
  Serial.println(transfert);
  delay(50);

    if (index >= 0)
    {
      start = transfert.indexOf("@"); // Position Début
      endsend = transfert.indexOf("!"); // Position fin
      code_alarme = transfert.substring(start, endsend); // Copie position début jusqu'à fin (Attention ! non copier)
      Serial.println(code_alarme);// Envoie via RS232 to PC le code de l'alarme
      delay(50);
    }
    start = 0; // Reset position
    endsend = 0; // Reset position
  }
  message ="";

}

ce n'est pas une manière très propre de lire le port série. Vous vous exposez à des déboires.
vous pouvez jeter un oeil à mon petit tuto sur le sujet éventuellement. (vous pourriez regarder par exemple si c'est bien un message de type SMS que vous avez reçu sur le port Serial1)

ceci n'enlève pas la dernière ligne

    message.setCharAt(longeur - 1, '\t'); // elimination dérnière ligne

vous mettez juste une tabulation à la place du dernier caractère de ce que vous avez reçu.

vous pourriez tester si votre longueur est plus grande que 60 avant de faire ceci    transfert = message.substring(60, longeur); //Trasfert message dans variable transfert

Pour voir ce qu'il se passe lors de la réception rajoutez plus d'impression, par exemple avec cette loop

void loop() {
  if (Serial1.available()) {
    message = Serial1.readString(); // Lire communication série avec module GSM
    longeur = message.length(); // Lire longeur reçu
    Serial.print("RECU: "); Serial.println(message);
    Serial.print("LONGUEUR: "); Serial.println(longeur);

    message.setCharAt(longeur - 1, '\t'); // elimination dérnière ligne
    message.trim(); // elimination des espace
    transfert = message.substring(60, longeur); //Trasfert message dans variable transfert
    Serial.print("TRANSFERT #1: "); Serial.println(transfert);
    index = transfert.indexOf("@"); // Détection début SMS
    Serial.println(index);
    transfert = transfert.substring(index); //Extraire text à partir de début SMS
    Serial.print("TRANSFERT #2: "); Serial.println(transfert);

    if (index >= 0)
    {
      start = transfert.indexOf("@"); // Position Début
      endsend = transfert.indexOf("!"); // Position fin
      code_alarme = transfert.substring(start, endsend); // Copie position début jusqu'à fin (Attention ! non copier)
      Serial.print("CODE ALARME: "); Serial.println(code_alarme);
    }
    message = "";
  }
}

Envoyez plusieurs SMS, copiez le texte de la console série et coller le ici sur le forum.

Bonjour,

Merci pour votre réponse et pour le tutorial du port série c'est très utile et très intéressant.

Veuillez trouver ci-dessous le texte de la console série :

Sans envoie de SMS :

08:42:05.636 -> RECU: AT+CNMI=2,2,0,0,0
08:42:05.671 ->
08:42:05.671 -> OK
08:42:05.671 ->
08:42:05.671 -> LONGUEUR: 25
08:42:05.671 -> TRANSFERT #1:
08:42:05.705 -> -1
08:42:05.705 -> TRANSFERT #2:

Avec envoie SMS 1 : Texte SMS "@CDIZ1C2!"
08:45:22.717 -> +CIEV: "MESS⸮,
08:45:22.751 -> 07911296380980F4040B911296781528F500001210628084054009802131A98D0D6521
08:45:22.821 ->
08:45:22.821 -> LONGUEUR: 167
08:45:22.856 -> TRANSFERT #1: "MESS⸮,
08:45:22.890 -> -1
08:45:22.890 -> TRANSFERT #2:

Avec envoie SMS 2 : Texte SMS "@CDIZ1C1!"
08:47:46.911 -> +CIEV: "MESS⸮,
08:47:46.946 -> 07911296380980F4040B911296781528F500001210628084054009802131A98D
08:47:47.014 -> LONGUEUR: 147
08:47:47.048 -> TRANSFERT #1: "MESS⸮,
08:47:47.082 -> -1
08:47:47.082 -> TRANSFERT #2:

J'ai remarqué que après suppression des délais de blocage du programme le module GSM n'arrive plus à communiquer avec la carte Arduino. SI j'ajoute un delay de 1000 ms (Après message = Serial1.readString():wink: ça affiche comme suit :

Avec envoie SMS 1 avec delay 1 s : Texte SMS "@CDIZ1C1!"

08:53:23.593 -> +CIEV: "MESS⸮,C⸮Hi5Q "+xxxxxxxxxxxx",,"2021/01/26,08:56:53+01"
08:53:23.662 -> @CDIZ1C1!
08:53:23.662 ->
08:53:23.662 -> LONGUEUR: 142
08:53:23.696 -> TRANSFERT #1: SS⸮,C⸮Hi5Q "+xxxxxxxxxxxx",,"2021/01/26,08:56:53+01"
08:53:23.765 -> @CDIZ1C1!
08:53:23.765 ->
08:53:23.765 -> 55
08:53:23.765 -> TRANSFERT #2: @CDIZ1C1!
08:53:23.798 ->
08:53:23.798 -> CODE ALARME: @CDIZ1C1

Avec envoie SMS 2 avec delay 1 s: Texte SMS "@CDIZ1C2!"
08:59:04.270 -> +CIEV: "MESS⸮,C⸮Hi5Q "+21698751825",,"2021/01/26,09:02:34+01"
08:59:04.304 -> @CDIZ1C2!
08:59:04.339 ->
08:59:04.339 -> LONGUEUR: 143
08:59:04.374 -> TRANSFERT #1: : "MESS⸮,C⸮Hi5Q "+21698751825",,"2021/01/26,09:02:34+01"
08:59:04.443 -> @CDIZ1C2!
08:59:04.443 ->
08:53:23.765 ->
08:59:04.443 -> 60
08:59:04.443 -> TRANSFERT #2: @CDIZ1C2!
08:59:04.478 ->
08:59:04.478 -> CODE ALARME: @CDIZ1C2

Avec envoie SMS 3 avec delay 1 s: Texte SMS "@CDIZ1C243!"
09:01:21.101 -> +CIEV: "MESS⸮,C⸮Hi5Q "+21698751825",,"2021/01/26,09:02:34+01"
09:01:21.171 -> @CDIZ1C2!
09:01:21.171 ->
09:01:21.205 -> LONGUEUR: 138
09:01:21.205 -> TRANSFERT #1: : "MESS⸮,C⸮Hi5Q "+21698751825",,"2021/01/26,09:02:34+01"
09:01:21.274 -> @CDIZ1C2!
09:01:21.307 ->
09:01:21.307 -> 60
09:01:21.307 -> TRANSFERT #2: @CDIZ1C2!
09:01:21.341 ->
09:01:21.341 -> CODE ALARME: @CDIZ1C2

Oui vous avez donc un problème de timing dans la lecture du port série comme exposé dans mon tuto. Vous essayez de deviner combien de temps attendre avant de lire ce qui arrive mais le problème c’est si vous lisez trop vite (cas sans les délais) vous ne lisez pas tout et si vous lisez trop lentement vous allez avoir trop de caractères arrivés dans le petit buffer de 64 octets et vous allez donc perdre une partie de la réponse.

À mon avis le mieux est de restructurer l’écoute du port série, de scanner des lignes et détecter quand ce que vous recevez est un sms (votre module semble envoyer +CIEV pour cela suivi d’infos)

Si vous fouillez aussi dans les Tutos j’ai posté une classe qui permet d’envoyer des commandes et attendre la réponse qui sera marquée par un chaîne de fin connue. Ça pourrait vous servir

D'accord je vais suivre l'exemple pour la communication série.
En outre un problème se pose avec les SMS qui ne mettent pas à jours comme l'exemple des tests 3 et 2. Le SMS reçu dans le test 3 , ne ce met pas à jours. Et ceci est un problème aléatoire que je n'arrive pas à résoudre.

dans le code proposé il y avait

    Serial.print("RECU: "); Serial.println(message);

je ne vois pas le RECU dans vos traces ?
pouvez vous poster le code utilisé ?

String message = ""; // message reçu du module GMS
int start1 = 0; //Position caractére Start
int endsend = 0; // Position caractére fin
String code_alarme = ""; //Code alarme après traitement
int index = 0;
int i=0;
String recu_1,recu_2,recu_3;
int longeur=0;
String transfert;

void setup() {

  // initialize both serial ports:
  delay(5000);

  Serial.begin(9600);

  Serial1.begin(9600); // Serial 1 Tx_18 , RX_19


  Serial1.println("AT"); // Lancement module GMS
  Serial1.println("AT+CMGF=1"); // Lancement mode SMS
  // Set module to send SMS data to serial out upon receipt
  Serial1.println("AT+CNMI=2,2,0,0,0"); // En attente reception

}

void loop() {

  if (Serial1.available()) {
    message = Serial1.readString(); // Lire communication série avec module GSM
    delay(10);
    longeur = message.length(); // Lire longeur reçu
    Serial.print("RECU: "); Serial.println(message);
    Serial.print("LONGUEUR: "); Serial.println(longeur);
    
    message.setCharAt(longeur - 1, '\t'); // elimination dérnière ligne
    message.trim(); // elimination des espace
    transfert = message.substring(60, longeur); //Trasfert message dans variable transfert
    Serial.print("TRANSFERT #1: "); Serial.println(transfert);
    index = transfert.indexOf("@"); // Détection début SMS
    Serial.println(index);
    transfert = transfert.substring(index); //Extraire text à partir de début SMS
    Serial.print("TRANSFERT #2: "); Serial.println(transfert);

    if (index >= 0)
    {
      start1 = transfert.indexOf("@"); // Position Début
      endsend = transfert.indexOf("!"); // Position fin
      code_alarme = transfert.substring(start1, endsend); // Copie position début jusqu'à fin (Attention ! non copier)
      Serial.print("CODE ALARME: "); Serial.println(code_alarme);
    }
    message = "";
  }
}

pourquoi "RECU" n'est pas affiché dans la copie de la console que vous avez partagée?

Je l'ai ajouté après le partage du texte de mon console

pouvez vous faire un test avec le code que vous avez publié ? sinon on ne sait pas qu'est-ce qui correspond à quoi..

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.