vthh94 / gsm-shield-arduino

Automatically exported from code.google.com/p/gsm-shield-arduino
0 stars 0 forks source link

Couldn't get SMS; SIM900; #43

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Connect to GSM Shield with SIM900 via SoftwareSerial
2. Call sms.GetSMS (or sms.IsSMSPresent)
3. Nothing happens.

What is the expected output? What do you see instead?

Should get number and text.

Please provide any additional information below.

I can connect to the SIM900 and I manage to send an sms, but I can't get any :(
I used the debug in IsStringReceived method, GSM.cpp, and got answer from 
SoftwareSerial with SMS data, but the parsing is somewhere wrong... I've tryed 
to understand a bit more, but i noticed that there are 2 methods to read SMS, 
one in SIM900.cpp ( SIMCOM900::readSMS(char* msg, int msglength, char* number, 
int nlength) ) and another in sms.cpp ( char SMSGSM::GetSMS(byte position, char 
*phone_number, char *SMS_text, byte max_SMS_len) ), none work. Studying the 
code and debugging a bit more I managed to destroy my achievements and now I 
can't get SMS neither from SoftwareSerial.read() ... Definetively stuck.

Original issue reported on code.google.com by Manuel.L...@gmail.com on 12 Sep 2012 at 2:49

GoogleCodeExporter commented 8 years ago
UPDATE: I managed to get again response from SoftwareSerial, really simple: I 
loaded GSM_GPRSLibrary_SMS example with #DEBUG_ON. Got answer and visualized 
with IsStringReceived debug, but parsing is still wrong (I think), because if I 
toggle the debug nothing is written on HWSerial.

Original comment by Manuel.L...@gmail.com on 12 Sep 2012 at 3:01

GoogleCodeExporter commented 8 years ago
Can you post the Arduino's code that you used?

Original comment by martines...@gmail.com on 12 Sep 2012 at 6:39

GoogleCodeExporter commented 8 years ago
Hi Marco, re-reading what I posted I noticed that I haven't written anything 
about what I'm using, my bad.
I'm using Arduino UNO R3 with GSM GPRS SHIELD V2 from Futura Electronics and a 
SIM 900 GSM module. I've downloaded GSM_GPRS_IDE100_v309 and I'm using 
GSM_GPRSLibrary_SMS example at this very moment, which code is as follows:

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

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

//To change pins for Software Serial, use the two lines in GSM.cpp.

//GSM Shield for Arduino
//www.open-electronics.org
//this code is based on the example of Arduino Labs.

//Simple sketch to send and receive SMS.

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

void setup() 
{
  //Serial connection.
  Serial.begin(9600);
  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("3471234567", "Arduino SMS"))
      //Serial.println("\nSMS sent OK");
  }

};

void loop() 
{
  if(started){
    //Read if there are messages on SIM card and print them.
    if(gsm.readSMS(smsbuffer, 160, n, 20))
    {
      Serial.println(n);
      Serial.println(smsbuffer);
    }
    delay(1000);
  }
};

I'm running this with thge #DEBUG_ON tag uncommented and my output is like my 
previous post, written from the method IsStringReceived:

byte GSM::IsStringReceived(char const *compare_string)
{
  char *ch;
  byte ret_val = 0;

  if(comm_buf_len) {

 /* ... */

    #ifdef DEBUG_ON
        Serial.print("ATT: ");
        Serial.println(compare_string);
        Serial.print("RIC: ");
        Serial.println((char *)comm_buf);
    #endif
    ch = strstr((char *)comm_buf, compare_string);
    if (ch != NULL) {
      ret_val = 1;
      /* ... */
    }
    else
    {
          /* ... */
    }
  }

  return (ret_val);
}

If I comment #DEBUG_ON again I get nothing in output. :(

Keep the good work and thanks for answer! :)

Manuel

PS: è frustrante dover scrivere in inglese... speriamo almeno serva a qualcun 
altro con il mio stesso problema (se ne esistono :P )!

Original comment by Manuel.L...@gmail.com on 13 Sep 2012 at 6:31

GoogleCodeExporter commented 8 years ago
Mmmmmmh...
<CODE>

boolean SIMCOM900::readSMS(char* msg, int msglength, char* number, int nlength)
{
  long index;
  /*
  if (getStatus()==IDLE)
    return false;
  */
  //_tf.setTimeout(_GSM_DATA_TOUT_);
  //_cell.flush();
  SimpleWriteln(F("AT+CMGL=\"REC UNREAD\",1"));
  if(gsm.WaitResp(5000, 50, "+CMGL")!=RX_FINISHED_STR_RECV)
  //if(_tf.find("+CMGL: "))
  {
    //index=_tf.getValue();
        index=_cell.read();
        #ifdef UNO
                _tf.getString("\"+", "\"", number, nlength);
        #endif
        #ifdef MEGA
                _cell.getString("\"+", "\"", number, nlength);
        #endif
        #ifdef UNO
                _tf.getString("\n", "\nOK", msg, msglength);
        #endif
        #ifdef MEGA
                _cell.getString("\n", "\nOK", msg, msglength);
        #endif
    SimpleWrite(F("AT+CMGD="));
        SimpleWriteln(index);
    gsm.WaitResp(5000, 50, "OK");
    return true;
  };
  return false;
};

</CODE>

if(gsm.WaitResp(5000, 50, "+CMGL")!=RX_FINISHED_STR_RECV): is this right? 
Shouldn't it be == not != ? It should mean 'if response is arrived and the 
string +CMGL is in it then...' but with != is the reverse

Original comment by Manuel.L...@gmail.com on 13 Sep 2012 at 8:03

GoogleCodeExporter commented 8 years ago
Tested and it still doesn't work, but this time I can get into the IF; proof is 
that I get an ERROR response when I try to execute the 
SimpleWrite(F("AT+CMGD=")) on index. I also debugged the return result of 
readSMS and it's TRUE, here is my output:

/*Execute gsm.WaitResp(5000, 50, "+CMGL") */
ATT: +CMGL

RIC: 

+CMGL: 3,"REC UNREAD","+39347268XXXX","","12/09/12,16:56:38+08"

Test

OK

/*Execute gsm.WaitResp(5000, 50, "OK") inside IF */
ATT: OK

RIC: 

ERROR

true  //My debug...

Now, I can't understand this instruction: index=_cell.read();
Isn't the _cell buffer already empty because of WaitResp? When I call a 
Serial.println(index) I get a -1, meaning there's nothing in the buffer...

I'm very puzzled :S

Original comment by Manuel.L...@gmail.com on 13 Sep 2012 at 8:31

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
Just for curiosity I've tried the other method, sms.GetSMS, knowing that for 
sure i have a "REC UNREAD" SMS at position 3 in the SIM900 memory. So my code 
was:

char smsCHARbuffer[160];
char n[20];

sms.GetSMS(3, n, smsCHARbuffer, 160);

Serial.println("DEBUG SMS phone number: ");
Serial.println(n);
Serial.println("SMS text: ");
Serial.println(smsCHARbuffer);

And result:

    44 45 42 55 47 20 53 4D 53 20 70 68 6F 6E 65   -DEBUG SMS phone
 20 6E 75 6D 62 65 72 3A 20 0D 0A 0D 0A 53 4D 53    number: ....SMS
 20 74 65 78 74 3A 20 0D 0A 0D 0A 44 45 42 55 47    text: ....

Data received:

DEBUG<Space>SMS<Space>phone<Space>number:<Space><CR><LF><CR><LF>SMS<Space>text:<
Space><CR><LF><CR><LF>

Original comment by Manuel.L...@gmail.com on 13 Sep 2012 at 8:54

GoogleCodeExporter commented 8 years ago
EUREKA!!!

I found which was the problem!! If I tell, you are going to insult me... a lot.

Let's see.

When you told me to post my code I partially lied. When I was using the example 
is ok, but for the sms.GetSMS(3, n, smsCHARbuffer, 160) I didn't paste anything.
Real code is:

#include "SIM900.h"
#include <SoftwareSerial.h>
#include "sms.h"

int numdata;
boolean started=false;
char smsCHARbuffer[160];
char n[20];
int i;

int LAMPEGGIO[10] = {2,49,87,48,53,44,48,50,182,3};
int AUTOMATICO[10] = {2,49,87,48,53,44,48,48,184,3};

SoftwareSerial mySerial(5, 4); // RX, TX
SMSGSM sms;

void setup()  
{   

  // Open serial communications and wait for port to open:
  Serial.begin(9600);

  if (gsm.begin(2400)){
    Serial.println("\nstatus=READY");
    started=true;  
  }
  else Serial.println("\nstatus=IDLE");

  mySerial.begin(9600);

}

void loop() // run over and over
{
  if(started){
    //Read if there are messages on SIM card and print them.

     gsm.listen(); // IMPORTANT!!!!

     /* 
      if(gsm.readSMS(smsCHARbuffer, 160, n, 20))
    {
      Serial.println(n);
      Serial.println(smsCHARbuffer);
      Serial.println("true");
    }

          */
          sms.GetSMS(3, n, smsCHARbuffer, 160);

          Serial.println("DEBUG SMS phone number: ");
          Serial.println(n);
          Serial.println("SMS text: ");
          Serial.println(smsCHARbuffer);
/*
          for (i = 0; i < 10; i = i + 1) {
            delay(1);
            //Serial.print(LAMPEGGIO[i]);
            mySerial.write(LAMPEGGIO[i]);
          }

          sms.DeleteSMS(3);

      }
    */

    delay(1000);    
  }
   mySerial.listen();
  while(mySerial.available()){
      Serial.write(mySerial.read());
      delay(1);
    } 

  while(Serial.available()){
    mySerial.write(Serial.read()); 
    delay(1);  

  }
}

As you can see I have TWO SoftwareSerial ports, one is _cell for GSM 
communication istantiated inside GSM Library and the other is mySerial 
istantiated in my code. I need mySerial to communicate with a device which I 
must control with SMS, but i didn't used hardware Serial to communicate with it 
because I wanted a "man in the middle" debug. The problem is that Arduino can 
listen one port at a time and mySerial is istantieted AFTER _cell, making it 
the default port, as stated in TwoPortReceive Arduino Example... So the problem 
was that i wasn't listening to GSM port but to mySerial. I added a method in 
GSM.cpp (which i suggest you to also add) like this:

void GSM::listen(void)
{
     _cell.listen();
}

With this method I tell Arduino to listen to GSM port. That's it! In the code 
above you can see when I call gsm.listen() to listen the port.

Hope this could be useful to someone! Sorry for the issue report and thanks for 
everything!

Manuel

PS: I suggest to sign SIMCOM900::readSMS method as deprecated!

Original comment by Manuel.L...@gmail.com on 13 Sep 2012 at 9:58

GoogleCodeExporter commented 8 years ago
Ok, happy that you solved by yourself and helped us by posting your
solution.
However thanks for your trick, this can be very helpful. :)

Marco

Original comment by martines...@gmail.com on 13 Sep 2012 at 10:15

GoogleCodeExporter commented 8 years ago
Non ho capito dove mettere il metodo _cell.listen in quale file e quale parte  
del file grazie guida molto interessante

Original comment by dottorco...@mondodentale.it on 18 Oct 2012 at 2:02

GoogleCodeExporter commented 8 years ago
Ciao!
Devi aggiungere:

void GSM::listen(void)
{
    _cell.listen();
}

al file GSM.ccp, in fondo al file va benissimo.

Non dimenticarti di inserirlo anche nel file GSM.h:

void listen();

Io l'ho inserito esattamente dopo void Echo(byte state); È abbastanza 
arbitrario comunque :)

Ogni volta che vuoi rimanere in ascolto della porta GSM al posto di una 
SoftwareSerial da te creata dovrai semplicemente chiamare il metodo 
gsm.listen(); come da mio codice sopra.

Questa non è una guida, è il mio delirio con tanto di testate sul muro per 
far funzionare tutto! ;)

Original comment by Manuel.L...@gmail.com on 18 Oct 2012 at 6:26

GoogleCodeExporter commented 8 years ago
Sei un grande, sono una settimana che cerco di risolvere il problema avere due 
seriali con la libreria gsm mi ha fatto dare anche a me tante testate al muro 
ieri sera ho fatto le quattro ho letto la tua dritta (gsm.listen) ho detto ci 
siamo stamattina ho controllato il post non pensavo che mi rispondevi 
subito.......
Testato tutto ok .........

Original comment by dottorco...@mondodentale.it on 18 Oct 2012 at 10:08

GoogleCodeExporter commented 8 years ago
Sono contento che il mio metodo ti abbia aiutato! :)

Non l'ho scritto ma vien da se: se vuoi ascoltare la seriale creata da te 
dovrai chiamare il metodo mySerial.listen(); dove mySerial è il nome della tua 
seriale. Insomma, prima di leggere da una seriale bisogna sempre chiamare il 
suo metodo listen().

Original comment by Manuel.L...@gmail.com on 18 Oct 2012 at 10:31

GoogleCodeExporter commented 8 years ago
ok già collaudato grazie

Original comment by dottorco...@mondodentale.it on 18 Oct 2012 at 11:02

GoogleCodeExporter commented 8 years ago
Piccolo ma grande problema: dopo aver aggiunto gsm.listen nel mio progetto mi 
si è rallentato tutto mi spiego meglio: faccio una chiamata myserial.listen  
per ricevere stringa da un altro arduino la elaboro e invio sms con gsm.send 
ecc sempre dopo aver chiamato il gsm.listen e fin. qui tutto funziona; appena 
ricevo l sms invio sms dal cellulare che ha ricevuto al mio progetto che non 
elabora affatto la stringa con gsm.readsms utilizzando il gsm.listen prima del 
gsm.readsms.
Forse ram? Il gsm.listen che ho aggiunto è la goccia che ha fatto traboccare 
la mia sram di arduino o ho fatto troppe chiamate gsm.listen ?domando posso 
usare il myserial.end o non avrebbe senso vi prego aiutatemiiiiiiii la testa al 
muro non la sbatto più perché il muro non c'è più l'ho finito...

Original comment by dottorco...@mondodentale.it on 19 Oct 2012 at 6:04

GoogleCodeExporter commented 8 years ago
Non ho progetto sotto mano esemplifico di seguito:
voi loop
Myserial.listen
Leggo stringa ricevuta
Gsm.listen(se non lo metto non invia sms)
Invio stringa ricevuta con gsm.sendsms
Gsm.listen
Gsm.readsms(non mi arriva sms si impalla)

Original comment by dottorco...@mondodentale.it on 19 Oct 2012 at 6:49

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
Riesci a postare il codice che usi? Sei già riuscito a leggere messaggi prima?
Il metodo readSMS è obsoleto, hai provato a usare getSMS?

Original comment by Manuel.L...@gmail.com on 19 Oct 2012 at 11:16

GoogleCodeExporter commented 8 years ago
Si riesco a leggere se se la chiamata a gsm.listen la faccio prima del 
myserial.listen..
Veramente non ho mai usato il getsms ho visto sopra che avete fatto un esempio 
ma usate il getsms sempre dopo readsms ?  Come va gestito il getsms?  Appena 
posso mando codice ...
Sto provando a espandere sram con spi nello stesso progetto usando il chip 
23k256 ma non ci sto caprendo una mazza mandò codice appena posso grazie

Original comment by dottorco...@mondodentale.it on 19 Oct 2012 at 4:19

GoogleCodeExporter commented 8 years ago
posto il progetto sembra che lavorando sul delay si arriverà alla soluzione in 
sostanza se tolgo dal loop invio() tutto ok se levo ricevo tutto ok ma se metto 
entrambi nel loop funziona solo ricevo bo!!

Original comment by dottorco...@mondodentale.it on 19 Oct 2012 at 10:06

Attachments:

GoogleCodeExporter commented 8 years ago
invio

Original comment by dottorco...@mondodentale.it on 19 Oct 2012 at 10:06

Attachments:

GoogleCodeExporter commented 8 years ago

Original comment by dottorco...@mondodentale.it on 19 Oct 2012 at 10:06

Attachments:

GoogleCodeExporter commented 8 years ago
Ciao, scusa se rispondo solo ora, ho avuto da fare durante il weekend...
Torniamo a noi. Alucne considerazioni da fare:

1 - Il pin 3 che usi per il buzzer è usato dalla seriale del GSM, guarda il 
file GSM.cpp righe 27-28. Quei pin corrispondono a tx e rx della seriale del 
GSM.

2 - Prima di leggere l'sms prova a inserire questo codice:

pos = sms.IsSMSPresent(SMS_UNREAD);

        if (pos) {

          sms.GetSMS(pos, n, buffer, 50);
          Serial.println("DEBUG SMS phone number: ");
          Serial.println(n);
          Serial.println("SMS text: ");
          Serial.println(buffer);
          .
          .
          .

In questo modo controlli se sono presenti dei messaggi non letti e in che 
posizione, in modo da leggere dalla seriale del GSM solo se esistono messaggi.

3 - Piuttosto di inserire l'istruzione gsm.listen(); nel metodo 
SendTextMessage() mettilo prima della chiamata al metodo, solo nel caso in cui 
non stai attualmente ascoltando la porta GSM. Il concetto è che devi passare 
da ascoltare una porta ad ascoltarne un'altra. Una volta chiamata tale funzione 
(gsm.listen();) rimani in ascolto della porta finchè non chiami la listen() di 
un'altra porta. Nel metodo ricevo() c'è la possibilità di chiamare 
gsm.listen() due volte di fila, nel caso in cui buffer sia 'a'.

4 - Hai davvero bisogno di 50 caratteri per l'SMS?
5 - Usa la Serial per fare dei debug. Dici che inserendo entrambi i metodi 
funziona solo ricevo(), sei sicuro? Prova a mettere Serial.println("Debug: 
metodo invio()") all'interno del metodo invio(), così riusciamo a capire se il 
problema è in ricevo() o in invio().

Manuel

Original comment by Manuel.L...@gmail.com on 22 Oct 2012 at 12:22

GoogleCodeExporter commented 8 years ago
Un'altra cosa che potresti fare è invertire ricevo() e invio() nel loop. Fai 
una prova e dimmi cosa succede.

Original comment by Manuel.L...@gmail.com on 22 Oct 2012 at 12:35

GoogleCodeExporter commented 8 years ago
Prova a vedere cosa succede con questo sketch:

#include "SIM900.h"
#include <SoftwareSerial.h>
SoftwareSerial gsmserial(5, 6);

#include "sms.h"
SMSGSM sms;

/*
SRAM Arduino
1 CS 10(CS)
2 SO 12(MISO)
3 - -
4 Vss GND
5 SI 11(MOSI)
6 SCK 13(SCK)
7 HOLD <-- 100k ohm -- 3.3V
8 Vcc 3.3V
*/

boolean started=false;

int addr;
String smstesto;
char n[20];
char myRAM[50];
int buz = 3;
int siren = 4;
boolean messagComplete = false;
boolean sirena = false;
char buffer[50];
char pos;
char *cmp;

void setup()
{
    powerUpOrDown();
    pinMode(buz,OUTPUT);
    pinMode(siren,OUTPUT);

    Serial.begin(9600);

    if (gsm.begin(9600)){
        started=true;
    }

    if(started){
        //Enable this two lines if you want to send an SMS.
        sms.SendSMS("3316181847", "Centralina Accesa!!");
        gsm.SimpleWrite("AT+CMGD=1,4\r");
    }
    gsmserial.begin(9600);
};

void loop()
{
    if(started)
    {
        ricevo();
        invio();
    }
};

void ricevo()
{
    //Read if there are messages on SIM card and print them.
    gsm.listen(); // IMPORTANT!!!!
    delay(200);

    pos = sms.IsSMSPresent(SMS_UNREAD);

        if (pos) 
        {
            sms.GetSMS(pos, n, buffer, 50);
            Serial.println("DEBUG SMS phone number: ");
            Serial.println(n);
            Serial.println("SMS text: ");
            Serial.println(buffer);
            if (strcmp(buffer,"a")==0)
            {
                buzer();
                SendTextMessage();
            }
            sms.DeleteSMS(pos);
            clearbuffer();
        }

    delay(1000);
}

void invio()
{
    gsmserial.listen();
    delay(200);
    //Se c'è qualcosa sulla seriale...
    if(gsmserial.available()>0){
        addr = 0;
        //...leggi.
        while (gsmserial.available()>0)
        {
            buffer[addr]=gsmserial.read();
            delay(1);
            addr++;
            /* 
            Qui non capisco: il secondo arduino continua incessantemente a inviare informazioni al primo? 
            Non è più semplice leggere tutto dal buffer seriale e controllare se c'è un asterisco al suo interno?    

            if (buffer[addr]=='*')
            {
                messagComplete=true;
                sirena=true;
                addr=0;
            }

            if (buffer[addr]=='\r')
            {
                messagComplete=true;
                addr=0;
            }

            if (messagComplete==false)
            {
                addr++;
            }
            */
        }
        //Se nel messaggio c'è un asterisco attiva la sirena.
        cmp = strstr((char *) buffer, "*");

        if(cmp!=NULL) sir();

        buzer();
        buzer();
        Serial.println(buffer);
        gsm.listen();
        SendTextMessage();  
    }
}

void SendTextMessage()
{
    if(started){
        //Enable this two lines if you want to send an SMS.
        sms.SendSMS("3316181847", buffer);
        //svuoto buffer
        clearbuffer();
    }
}

void clearbuffer()
{
    for (int i=0;i<50;i++)
    {
        buffer[i]=0;
    }
}

void buzer()
{
    digitalWrite(buz,HIGH);
    delay(1000);
    digitalWrite(buz,LOW);
    delay(1000);
}

void sir()
{
    digitalWrite(siren,HIGH);

    delay(10000);
    digitalWrite(siren,LOW);
    //sirena=false;
}

void powerUpOrDown()
{
    digitalWrite(9,HIGH);
    delay(15000);
}

Original comment by Manuel.L...@gmail.com on 22 Oct 2012 at 1:09

GoogleCodeExporter commented 8 years ago
Non funziona; il problema è dimensionare la variabile buffer[50]; che ne pensi 
è meglio che dichiaro char * buffer; o char buffer[]=""? quale delle due 
dichiarazioni occupano meno memoria? penso ormai che è un problema di memoria 
quindi devo ottimizzare grazie 

Original comment by dottorco...@mondodentale.it on 23 Oct 2012 at 2:43

GoogleCodeExporter commented 8 years ago
Prova a far girare questo:

http://www.arduino.cc/playground/Code/AvailableMemory

Original comment by Manuel.L...@gmail.com on 23 Oct 2012 at 2:48

GoogleCodeExporter commented 8 years ago
e se è la memoria? come mi consigli l'istanziamento di buffer?

Original comment by dottorco...@mondodentale.it on 23 Oct 2012 at 3:10

GoogleCodeExporter commented 8 years ago
poca memoria purtroppo , risolverò con il mega sicuramente sono in attesa di 
riceverlo ciao

Original comment by dottorco...@mondodentale.it on 24 Oct 2012 at 12:09

GoogleCodeExporter commented 8 years ago
Risolto con il mega 

Original comment by dottorco...@mondodentale.it on 27 Oct 2012 at 5:13

GoogleCodeExporter commented 8 years ago
Ottimo! Son contento tu abbia risolto :) So che si sta cercando di ridurre al 
minimo l'utilizzo della memoria della librera, magari con la prossima rev 
riuscirai a usare anche l'uno

Original comment by Manuel.L...@gmail.com on 28 Oct 2012 at 5:41

GoogleCodeExporter commented 8 years ago

Original comment by martines...@gmail.com on 11 Dec 2012 at 5:01

GoogleCodeExporter commented 8 years ago
This issue section is not longer supported.
Please check the support page www.gsmlib.org 

Original comment by martines...@gmail.com on 6 Jul 2013 at 11:27