Go Down

Topic: SIM800L + Arduino code problem (Read 337 times) previous topic - next topic

mva93000

Jul 24, 2017, 12:45 pm Last Edit: Jul 24, 2017, 04:15 pm by mva93000
Bonjour à vous,

Voici mon problème. Actuellement je suis en train de comprendre le protocole GSM.
J'ai aujourd'hui réussit à envoyer un texto à un numéro et le faire de manière interactive.
Le but de mon projet est de lire des SMS et de les interprétées.

J'ai bien le code pour lire les SMS et qui lis mon SMS en 1ere position pour le supprimer derrière.
Le problème que j'ai aujourd'hui et que par exemple lorsqu'il reçois un SMS je veut qu'il regarde si le SMS == valeur.
J'ai le code pour faire un Grep du SMS mais je n'arrive pas à le mettre dans mon code de lecture de SMS et je comprend pas pourquoi.

Pouvez-vous m'aidez à comprendre svp ?

Voici mon code

Code: [Select]
// If you have a pin code please put that code before setup :
// String SIM_PIN_CODE = String( "XXXX" );
// And put that code on setup :
// sim800l.print("AT+CPIN=");
// sim800l.println( SIM_PIN_CODE );
// Import of library.
#include <SoftwareSerial.h>
SoftwareSerial sim800l(7, 8); // RX, TX
 String text;     // to storage the text of the sms
 char inchar;
 
void setup() {          // Start of setup.
 Serial.begin(9600);    // Start of modem.
 sim800l.begin(9600);   // Initialisation of serie communication.
 sim800l.print("AT+CMGF=1\r");
 delay(500);
 text=sim800l.print("AT+CMGL=ALL\r");    
 Serial.println(text);//do nothing
}

void loop() {
 if (sim800l.available())
 Serial.write(sim800l.read());

 if (Serial.available()) {
 while(Serial.available()){
 sim800l.write(Serial.read());
 }
 sim800l.println();
 }
  // put your main code here, to run repeatedly:
  String ledOn = "Result command of AT+CMGR=1"; HERE IS MY PROBLEM
  Serial.println(ledOn);

  // substring(index) looks for the substring from the index position to the end:
  if (ledOn.substring(100,102) == "on") {
    Serial.println("You did it");
  }
  // you can also look for a substring in the middle of a string:
  if (ledOn.substring(100, 103) == "off") {
    Serial.println("You did it");
  }

}


J'ai fait le test en mettant du texte dans la string ledOn et fait le grep dans un autre sketch cela fonctionne sans problème. Mais avec la lecture du SMS impossible.
Savez-vous pourquoi ?

J'ai tenté de mettre à String ledOn = simm800l.println("AT+CMGR=1\r"); mais cela ne compile pas.

Cela fait 3 mois que je cherche comment grep le SMS pour ensuite allumer une LED.

PS : Avec ce code en sortie sur le COM5 j'ai juste la lecture du SMS qui se fait.
Comme ce sont des tests je met la plupart du code en setup pour l'exécuter une seul fois. J'ai souvent mis en erreur le module SMS :/
J'ai tenté aussi plusieurs code pour SMS, tenté de prendre des bouts par ci et par là. Je pense que je dois me tromper dans la compréhension du code.

Si une âme gentil pourrais m'expliquer sa serais sympas :)

Ici un exemple du retour que j'ai dans la console.



Merci pour votre aide.


hameau

Salut,
Tu utilises une librairie pour gérer le module GSM, c'est lequel exactement ?.

Cdt
 

aligote

Bonjour,

Moi je tenterais un affichage intermédiaire dans le genre :

    Serial.println(ledOn.substring(100,102));

Pour voir si le pB n'est pas une position de "off" incorrete dans ledOn.

--------------------------------
 text=sim800l.print("AT+CMGL=ALL\r");    
 Serial.println(text);

Semble donner des réponses satisfaisantes.
------------------------------------------
Il faudrait mettre entre balises la réponse à :

  String ledOn = "Result command of AT+CMGR=1"; HERE IS MY PROBLEM
  Serial.println(ledOn);

Pour voir le résusltat.

Serge .D

mva93000

Salut,
Tu utilises une librairie pour gérer le module GSM, c'est lequel exactement ?.

Cdt
 
Bonjour oui j'utilise la librairy permettant la création d'une communication en série (RX, TX) avec mon SIM800L.

mva93000

Bonjour,

Moi je tenterais un affichage intermédiaire dans le genre :

    Serial.println(ledOn.substring(100,102));

Pour voir si le pB n'est pas une position de "off" incorrete dans ledOn.

--------------------------------
 text=sim800l.print("AT+CMGL=ALL\r");     
 Serial.println(text);

Semble donner des réponses satisfaisantes.
------------------------------------------
Il faudrait mettre entre balises la réponse à :

  String ledOn = "Result command of AT+CMGR=1"; HERE IS MY PROBLEM
  Serial.println(ledOn);

Pour voir le résusltat.

Serge .D
Bonjour Serge,

En faite dans le code ou j'écrit "Result command of..." je ne sais pas quoi mettre ici.
Dans le COM5 les réponse que j'ai du module sont en ASCII, j'aimerais faire un grep de la réponse de la commande AT+CMGL="ALL" dans le port serie de la sim.

J'aurais aimer de l'aide de quelqu'un de plus professionnel que moi en C++.

Ou sinon j'aimerai lire le texto et le stocker quelque part avec quoi je pourrais faire des actions.
J'avoue qu'en me relisant j'étais pas très compréhensible.

hameau

Salut,

Tu utilises quel module SIM800 L ?

Perso j'ai celui-ci :

Pour la Lib : https://github.com/jefflab/GSMSHIELD

Voici le code qui me permet de commander une LED en SMS .
Code: [Select]

#include "SIM900.h"
#include <SoftwareSerial.h>
//#include "inetGSM.h"

//If you want to use the Arduino functions to manage SMS, uncomment the lines below.
#include "sms.h"
SMSGSM sms;

int numdata;
boolean started=false;
char smsbuffer[20];
char n[20];


void setup()
{
  //Serial connection.
  pinMode(13, OUTPUT);
  Serial.begin(9600);
  gsm.SimpleWriteln("AT+CMGD=1,4");
  Serial.println("GSM Shield testing.");
  //Start configuration of shield with baudrate.
  //For http uses is raccomanded to use 4800 or slower.
  if (gsm.begin(2400)){
    Serial.println("\nstatus=READY");
    started=true;  
  }
  else Serial.println("\nstatus=IDLE");
  
  if(started)
  {
    //Enable this two lines if you want to send an SMS.
    if (sms.SendSMS("+336.......", "Arduino SMS"))
      Serial.println("\nSMS sent OK");
  }

}

void loop()
{
  if(started)
  {
    String message="";
    //Read if there are messages on SIM card and print them.
    if(gsm.readSMS(smsbuffer, 20, n, 20))
    {
      
      Serial.println(n);
      Serial.println(smsbuffer);
      int lg = strlen(smsbuffer);
      Serial.println(lg);
      for (int a=0; a <= lg-2; a++)
        {
        message=message+(smsbuffer[a]);
        }
     }
    
      //String code = String (smsbuffer[0]);
      if (message=="Open" || message=="Open ")
      {
      digitalWrite(13, HIGH);
      delay(1000);
      digitalWrite(13, LOW);
      (sms.SendSMS("+336........", "Portail Ouvert"));
      gsm.SimpleWriteln("AT+CMGD=1,4");
      }
      if (message=="Close" || message=="Close ")
      {
      digitalWrite(13, HIGH);
      delay(1000);
      digitalWrite(13, LOW);
      (sms.SendSMS("+336..........", "Portail Ferme"));
      gsm.SimpleWriteln("AT+CMGD=1,4");
      }
     if (message=="Help")
      {
      (sms.SendSMS("+336............", "Open / Close"));
      }
      
    }
    
    delay(1000);
  }






aligote

Beaucoup de choses obscures ....

Ce genre d'exercice suppose une connaissance minimum de la signification des commandes AT ainsi que les fonctions de manipulation de chaines de caractères.

Revenons au début ( post #1 Réponses affichées dans l'image jointe)

 AT+CMGF=all

------------ A mon avis cette ligne signifie que le modem répond a la commande "AT+CMGF=all"

Et cette commande est une requête pour afficher la liste de  tous les SMS reçus par la carte Sim

----------- La réponse du modem vers la console est affichée à la suite

+CMGL: 1 ....etc  ...
..........

+CMGL: 2 ....etc  ...
..........

Cela signifie que 2 SMS sont reçus, ils n'ont pas encore étés lus.

Le OK qui suit envoyé par le modem signifie que tout s'est bien passé.

Petite remarque au passage, il serait bon de masquer le n° de Tel avant de publier .....

Pour lire le SMS n°1 il faudrait envoyer une commande AT du genre :

-  sim800l.print("AT+CMGR=1\r");

Ensuite extraire de la réponse le texte "utile" du SMS par une fonction d'extraction de chaine du genre

ledOn.substring(100,102) En supposant que 100 et 102 sont les positions de début et de fin du texte à extraire de la chaine ledOn.

Pour que l'on puisse analyser plus facilement à distance  toutes les réponses du modem il faudrait les publier (en masquant les n° de Tel) entre des balises codes comme le code du programme. On pourrait ainsi faire défiler le texte et obtenir la totalité des réponses.


La difficulté est principalement due au fait que pour un SMS reçu, le texte transmis par le modem contient beaucoup d'informations :
- n° du SMS dans la liste, SMS lu ou non lu, n° de Tel, date heure et texte du SMS ....


Voila une fonction que je suis occupé à finaliser, cette fonction permet la lecture de SMS, l'extraction du n° de Tel en remplaçant le +33 pour l'affichage. La clef permet de filtrer les messages utiles avec un mot de passe.
Il est fait appel à la fonction MESSAGE qui retourne vrai si le texte passé en paramètre est trouvé dans le délai en ms passé lui aussi en paramètre.
La fonction SMS_FAIT exécute l'ordre prévu en fonction du texte attendu passé en paramètre.

Code: [Select]

void LIRE_SMS(String Clef)
  { int pos=0;int longueur=0;int i;String Texte_SMS; 
    gsm.println("AT+CMGF=1");//mode texte
    MESSAGE("OK",2000);delay(1000);
    Serial.println("Lecture des SMS");
    for (i=0;i<Smax;i++)
      {gsm.print("AT+CMGR=");gsm.println(char(48+i));
       if (MESSAGE("+CMGR:",1000))
          { BUZZER(10);delay(200);BUZZER(100);
            Serial.print("SMS n:");Serial.println(i);
            Serial.println(reponse);
            pos=reponse.indexOf("+33");
            lcd.setCursor(0,1);lcd.print("n:");lcd.print(i);lcd.print(":0");
            lcd.print(reponse.substring(pos+3,pos+12));
            pos=reponse.indexOf(Clef);longueur=reponse.length();
            EFFACE_LIGNE(0);Texte_SMS=reponse.substring(pos,pos+5);
            lcd.setCursor(0,0);lcd.print("SMS:"+Texte_SMS); 
            SMS_FAIT(Texte_SMS);     
            delay(10000);     
          }
       else
          {Serial.print("SMS vide n:");Serial.println(i);
          EFFACE_LIGNE(1);BUZZER(100);
          lcd.setCursor(0,1);lcd.print("SMS Vide n:");lcd.print(i); //ajout
          delay(2000);
          }
      }
    Serial.println("Effacer tous les SMS");
    gsm.println("AT+CMGD=1,4");
    MESSAGE("OK",2000);
    Serial.println(reponse);
  }





mva93000

Salut,

Tu utilises quel module SIM800 L ?

Perso j'ai celui-ci :

Pour la Lib : https://github.com/jefflab/GSMSHIELD

Voici le code qui me permet de commander une LED en SMS .
Code: [Select]

#include "SIM900.h"
#include <SoftwareSerial.h>
//#include "inetGSM.h"

//If you want to use the Arduino functions to manage SMS, uncomment the lines below.
#include "sms.h"
SMSGSM sms;

int numdata;
boolean started=false;
char smsbuffer[20];
char n[20];


void setup()
{
  //Serial connection.
  pinMode(13, OUTPUT);
  Serial.begin(9600);
  gsm.SimpleWriteln("AT+CMGD=1,4");
  Serial.println("GSM Shield testing.");
  //Start configuration of shield with baudrate.
  //For http uses is raccomanded to use 4800 or slower.
  if (gsm.begin(2400)){
    Serial.println("\nstatus=READY");
    started=true; 
  }
  else Serial.println("\nstatus=IDLE");
 
  if(started)
  {
    //Enable this two lines if you want to send an SMS.
    if (sms.SendSMS("+336.......", "Arduino SMS"))
      Serial.println("\nSMS sent OK");
  }

}

void loop()
{
  if(started)
  {
    String message="";
    //Read if there are messages on SIM card and print them.
    if(gsm.readSMS(smsbuffer, 20, n, 20))
    {
     
      Serial.println(n);
      Serial.println(smsbuffer);
      int lg = strlen(smsbuffer);
      Serial.println(lg);
      for (int a=0; a <= lg-2; a++)
        {
        message=message+(smsbuffer[a]);
        }
     }
     
      //String code = String (smsbuffer[0]);
      if (message=="Open" || message=="Open ")
      {
      digitalWrite(13, HIGH);
      delay(1000);
      digitalWrite(13, LOW);
      (sms.SendSMS("+336........", "Portail Ouvert"));
      gsm.SimpleWriteln("AT+CMGD=1,4");
      }
      if (message=="Close" || message=="Close ")
      {
      digitalWrite(13, HIGH);
      delay(1000);
      digitalWrite(13, LOW);
      (sms.SendSMS("+336..........", "Portail Ferme"));
      gsm.SimpleWriteln("AT+CMGD=1,4");
      }
     if (message=="Help")
      {
      (sms.SendSMS("+336............", "Open / Close"));
      }
     
    }
   
    delay(1000);
  }






Salut Hameau,
Merci pour ta réponse personnellement j'utilise ce module ci :



Mais je vais regardé ton code j'avais aussi dans le temps pris la lib mais j'ai pas réussit donc j'ai repris de la base.

Je te tiens au courant dès que j'ai des résultats :)

mva93000

#9
Jul 26, 2017, 10:02 pm Last Edit: Jul 27, 2017, 01:22 am by mva93000
Beaucoup de choses obscures ....

Ce genre d'exercice suppose une connaissance minimum de la signification des commandes AT ainsi que les fonctions de manipulation de chaines de caractères.

Revenons au début ( post #1 Réponses affichées dans l'image jointe)

 AT+CMGF=all

------------ A mon avis cette ligne signifie que le modem répond a la commande "AT+CMGF=all"

Et cette commande est une requête pour afficher la liste de  tous les SMS reçus par la carte Sim

----------- La réponse du modem vers la console est affichée à la suite

+CMGL: 1 ....etc  ...
..........

+CMGL: 2 ....etc  ...
..........

Cela signifie que 2 SMS sont reçus, ils n'ont pas encore étés lus.

Le OK qui suit envoyé par le modem signifie que tout s'est bien passé.

Petite remarque au passage, il serait bon de masquer le n° de Tel avant de publier .....

Pour lire le SMS n°1 il faudrait envoyer une commande AT du genre :

-  sim800l.print("AT+CMGR=1\r");

Ensuite extraire de la réponse le texte "utile" du SMS par une fonction d'extraction de chaine du genre

ledOn.substring(100,102) En supposant que 100 et 102 sont les positions de début et de fin du texte à extraire de la chaine ledOn.

Pour que l'on puisse analyser plus facilement à distance  toutes les réponses du modem il faudrait les publier (en masquant les n° de Tel) entre des balises codes comme le code du programme. On pourrait ainsi faire défiler le texte et obtenir la totalité des réponses.


La difficulté est principalement due au fait que pour un SMS reçu, le texte transmis par le modem contient beaucoup d'informations :
- n° du SMS dans la liste, SMS lu ou non lu, n° de Tel, date heure et texte du SMS ....


Voila une fonction que je suis occupé à finaliser, cette fonction permet la lecture de SMS, l'extraction du n° de Tel en remplaçant le +33 pour l'affichage. La clef permet de filtrer les messages utiles avec un mot de passe.
Il est fait appel à la fonction MESSAGE qui retourne vrai si le texte passé en paramètre est trouvé dans le délai en ms passé lui aussi en paramètre.
La fonction SMS_FAIT exécute l'ordre prévu en fonction du texte attendu passé en paramètre.

Code: [Select]

void LIRE_SMS(String Clef)
  { int pos=0;int longueur=0;int i;String Texte_SMS; 
    gsm.println("AT+CMGF=1");//mode texte
    MESSAGE("OK",2000);delay(1000);
    Serial.println("Lecture des SMS");
    for (i=0;i<Smax;i++)
      {gsm.print("AT+CMGR=");gsm.println(char(48+i));
       if (MESSAGE("+CMGR:",1000))
          { BUZZER(10);delay(200);BUZZER(100);
            Serial.print("SMS n:");Serial.println(i);
            Serial.println(reponse);
            pos=reponse.indexOf("+33");
            lcd.setCursor(0,1);lcd.print("n:");lcd.print(i);lcd.print(":0");
            lcd.print(reponse.substring(pos+3,pos+12));
            pos=reponse.indexOf(Clef);longueur=reponse.length();
            EFFACE_LIGNE(0);Texte_SMS=reponse.substring(pos,pos+5);
            lcd.setCursor(0,0);lcd.print("SMS:"+Texte_SMS); 
            SMS_FAIT(Texte_SMS);     
            delay(10000);     
          }
       else
          {Serial.print("SMS vide n:");Serial.println(i);
          EFFACE_LIGNE(1);BUZZER(100);
          lcd.setCursor(0,1);lcd.print("SMS Vide n:");lcd.print(i); //ajout
          delay(2000);
          }
      }
    Serial.println("Effacer tous les SMS");
    gsm.println("AT+CMGD=1,4");
    MESSAGE("OK",2000);
    Serial.println(reponse);
  }





Salut Aligote,

Merci aussi pour ta réponse très bien détailler et effectivement la demande a été très bien comprise dans le détail. Je vais testé aussi ton code et te ferais un retour.

Merci pour votre temps de réponse à vous tous.

PS : Le numéro et l'image n'est pas de moi :D (i'm not crazy :))

Loucrup

Salut,

Tu utilises quel module SIM800 L ?

Perso j'ai celui-ci :

Pour la Lib : https://github.com/jefflab/GSMSHIELD

Voici le code qui me permet de commander une LED en SMS .
Code: [Select]

#include "SIM900.h"
#include <SoftwareSerial.h>
//#include "inetGSM.h"

//If you want to use the Arduino functions to manage SMS, uncomment the lines below.
#include "sms.h"
SMSGSM sms;

int numdata;
boolean started=false;
char smsbuffer[20];
char n[20];


void setup()
{
  //Serial connection.
  pinMode(13, OUTPUT);
  Serial.begin(9600);
  gsm.SimpleWriteln("AT+CMGD=1,4");
  Serial.println("GSM Shield testing.");
  //Start configuration of shield with baudrate.
  //For http uses is raccomanded to use 4800 or slower.
  if (gsm.begin(2400)){
    Serial.println("\nstatus=READY");
    started=true; 
  }
  else Serial.println("\nstatus=IDLE");
 
  if(started)
  {
    //Enable this two lines if you want to send an SMS.
    if (sms.SendSMS("+336.......", "Arduino SMS"))
      Serial.println("\nSMS sent OK");
  }

}

void loop()
{
  if(started)
  {
    String message="";
    //Read if there are messages on SIM card and print them.
    if(gsm.readSMS(smsbuffer, 20, n, 20))
    {
     
      Serial.println(n);
      Serial.println(smsbuffer);
      int lg = strlen(smsbuffer);
      Serial.println(lg);
      for (int a=0; a <= lg-2; a++)
        {
        message=message+(smsbuffer[a]);
        }
     }
     
      //String code = String (smsbuffer[0]);
      if (message=="Open" || message=="Open ")
      {
      digitalWrite(13, HIGH);
      delay(1000);
      digitalWrite(13, LOW);
      (sms.SendSMS("+336........", "Portail Ouvert"));
      gsm.SimpleWriteln("AT+CMGD=1,4");
      }
      if (message=="Close" || message=="Close ")
      {
      digitalWrite(13, HIGH);
      delay(1000);
      digitalWrite(13, LOW);
      (sms.SendSMS("+336..........", "Portail Ferme"));
      gsm.SimpleWriteln("AT+CMGD=1,4");
      }
     if (message=="Help")
      {
      (sms.SendSMS("+336............", "Open / Close"));
      }
     
    }
   
    delay(1000);
  }



Bonjour à tous,
J'utilise aussi ce module SIM800L j'arrive ni à envoyer ni recevoir de texto.
J'ai enlevé le code sim de ma carte
je n'ai pas d'erreur avec le code ci-dessus
Par contre je ne sais pas trop comment je dois le câbler... (j'ai essayé plusieurs combinaisons en vain)
Est ce que quelqu'un aurait réussi et aurait la gentillesse de m'aider SVP ?
Merci d'avance
Etienne

hameau

Salut,

Pour le câblage :

#define _GSM_TXPIN_ 2
#define _GSM_RXPIN_ 3

Regarde le fichier GSM.cpp et va voir la config des deux lignes ci-dessus , et réalise le cablage comme indiqué

Dans le setup, la ligne :
Code: [Select]
if (sms.SendSMS("+336.......", "Arduino SMS"))


Tu a bien mis ton numéro de téléphone pour recevoir un SMS quand la carte arduino via s'initialiser ?
@+


Loucrup

Merci hameau pour ta réponse rapide :)
Et pour ce qui est des autre broches ?

SIM800L 5V    ->  5V (directement le 5V de l'arduino ?)
SIM800L GND  ->  GND
SIM800L VDD  ->  ?
SIM800L TXD  ->  D2
SIM800L RXD  ->  D3
SIM800L GND  ->  GND
SIM800L RST  ->  ?

Merci d'avance pour ta future réponse ;)

aligote

#13
Aug 13, 2017, 10:05 am Last Edit: Aug 13, 2017, 10:43 am by aligote
Merci hameau pour ta réponse rapide :)
Et pour ce qui est des autre broches ?

SIM800L 5V    -> 5V (directement le 5V de l'arduino ?)

Surtout pas !

Serge .D


hameau

Salut,

Il est trés recommandé d'alimenter 5VIN à partir d'une source 5V externe qui puisse fournir 2 A durant les phases de com.
pour le reste GND au GND alimentation  Externe, VDD rien, Tx et Tx arduino, GND arduino, RST rien.

@+
 

Go Up