How can I stop gsm.begin()?

Hi, can help me?

I'm programing an aplication with GSMShield and one battery. My problem: in case gsm can't connect to accessprovider, it always try to connect, and discharges the battery, how can stop the module in this cases?

// 1: Send AT
// 2: Wait AT OK and SetPin or CGREG
// 3: Wait Pin OK and CGREG
The library make an infinit bucle in this point (waiting CGREG)
// 4: Wait CGREG and Flow SW control or CGREG
// 5: Wait IFC OK and SMS Text Mode
// 6: Wait SMS text Mode OK and Calling line identification
// 7: Wait Calling Line Id OK and Echo off
// 8: Wait for OK and COLP command for connecting line identification.
// 9: Wait for OK.

Hi!,

To stop GSM.begin() you can use asynchronous mode with a timeout.

For configurate async mode, you must replace the code line gsmAccess.begin(PINNUMBER) with gsmAccess.begin(PINNUMBER, true, false). The third parameter indicates async mode if it is false, and the second parameter indicates if modem restart at the beginning (default is true).

For example:

  unsigned long myTimeout = 3000; // YOUR LIMIT IN MILLISECONDS

  unsigned long timeConnect = millis();

  while((millis() - timeConnect) < myTimeout)
  {
    if(gsmAccess.begin(PINNUMBER, true, false)==GSM_READY)
      Serial.println("Connected");
    else
    {
      Serial.println("Not connected");
    }
  }

Greetings.

Ok, adding this line: gsmAccess.shutdown(); the module should be off, it is not?
In my case not work. Any other solution?

  unsigned long myTimeout = 3000; // YOUR LIMIT IN MILLISECONDS

  unsigned long timeConnect = millis();

  while((millis() - timeConnect) < myTimeout)
  {
    if(gsmAccess.begin(PINNUMBER, true, false)==GSM_READY)
      Serial.println("Connected");
    else
    {
      Serial.println("Not connected");
    }
  }
  gsmAccess.shutdown();  /FOR SHUTDOWN MODULE

When your code executes shutdown method, modem will switch off in a interval of 12 seconds. Then, STATUS led will turn off, but ON led always will be on.

If STATUS led never switch off, then you can download this new library version (https://dl.dropboxusercontent.com/u/9093673/GSM3.zip) and try secureShutdown function (object gsmAccess of class GSM).

I tried a variant of the code above, but it seems gsmAccess.begin(PINNUMBER,true,false) gives me a SIM PIN code error... ??? (yes, I hava a PIN code on the sim defined to 1424, so it is correct)
From the start of the debug log:

AT%13%AT+CGATT=1%13%
104 124>AT%13%AT+CGATT=1%13%%13%%10%OK%13%%10%
AT+QIFGCNT=0%13%
124 27>AT+QIFGCNT=0%13%%13%%10%+CME ERROR: 11%13%%10%
[...]

If I use gsmAccess.begin(PINNUMBER,true,true) I get a very different set of AT-commands sent to the modem, starting with the PIN unlock command.

AT%13%
0 9>AT%13%%13%%10%OK%13%%10%
AT+CPIN=1424%13%
9 44>AT+CPIN=1424%13%%13%%10%+CPIN: READY%13%%10%%13%%10%OK%13%%10%
[...]

We run into some severe problems with the sync mode hanging when the board was placed outside in the rain... so here is a solution.

First enable debug mode so we can see what is happening...

GSM gsmAccess(true); // True for debugging

Debugging makes the code behave in a very different way... I really have no clue why. Turning it off introduces other problems in my code...

Async GSM.begin() and debugging do seem to work with the following code snippet:

  Serial.println(F("GSM start"));
  
  unsigned long myTimeout = 60000; // YOUR LIMIT IN MILLISECONDS 

  gsmAccess.begin(PINNUMBER,true,false); //Use async mode and requires that GSM debug mode has been set on GSM object creation
  boolean notConnected = true;
  unsigned long timeConnect = millis();
  // connection state
  while(notConnected && (millis()-timeConnect < myTimeout)) 
  {
    int ok = 0;
    gsmAccess.ready(); //Call this if debugging is on. Otherwise we will never reach GSM_READY...?!?
    delay(1000); //might not call ready too often.??? See GSM3ShieldV1AccessProvider.cpp, GSM3ShieldV1AccessProvider::begin
    ok = gsmAccess.getStatus();
    if (ok != GSM_READY && ok != GPRS_READY){
      Serial.print(F("GSM status: "));
      Serial.println(ok);
      continue;
    }
    if(gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD)==GPRS_READY) {
      notConnected = false;
    }
  }
//Here we check the notConnected flag and retry or aborts if set. If not set, continoue with connection to server...

As the delay(1000) is really needed I suspect there can be severe problems on some network connections, i.e some AT-commands can take much more time than 1 second to respond and how will this work then?

I am experiencing an issue where once I shutdown the GSM shield and then I try to connect again, it will not do it. It gets stuck on the first AT command and it does not proceed further, timing out.

Here the simple code using the suggestions above:

#include <GSM.h>

GSM gsmAccess(true); 

void setup (){
  
  Serial.begin(9600);
  Serial.println("Testing shutdown of GSM Shield");

}

void loop(){
  
  connectToGSMNetwork();
  
  delay(5000);
  
  Serial.println("Shutting down");
  gsmAccess.shutdown();
  delay(5000); // this delay is to ensure that it is fully shutdown
  digitalWrite(3, LOW);
  
  delay(20000);
}  

void connectToGSMNetwork(){

  unsigned long myTimeout = 30000; // YOUR LIMIT IN MILLISECONDS 
  boolean notConnected = true;
  unsigned long timeConnect = millis();

  Serial.println("Trying to connect...");

  gsmAccess.begin("",true,false); //Use async mode and requires that GSM debug mode has been set on GSM object creation
  while(notConnected && (millis()-timeConnect < myTimeout)) 
  {
    int ok = 0;
    gsmAccess.ready(); //Call this if debugging is on. Otherwise we will never reach GSM_READY...?!?
    delay(1000); //might not call ready too often.??? See GSM3ShieldV1AccessProvider.cpp, GSM3ShieldV1AccessProvider::begin
    ok = gsmAccess.getStatus();
    if (ok != GSM_READY){
      Serial.print(F("GSM status: "));
      Serial.println(ok);
    } else {
      notConnected = false;
    }
  }
  
  if(notConnected)
    Serial.println("Error in connection");
  else
    Serial.println("Connected to GSM network");
}

The first time I go into the loop all works well: it connects to the GSM network and it shuts down correctly (Status led goes off). But the 2nd loop it gets stuck with the connection until it times out giving me:

Trying to connect...
AT%13%GSM status: 2
GSM status: 2
GSM status: 2
GSM status: 2
...

How is it working on your side? Is it re-connecting? Am I doing something wrong?

Thanks

I tried adding an in initial "AT" command before attempting to connect and now it works 100% of the times.

So I added this single line of code in the connectToGSMNetwork() function:

 theGSM3ShieldV1ModemCore.println("AT");

just before gsmAccess.begin("", true, false);

Problem resolved with workaround, but still something to consider in the next release of the library.

EDIT: "Almost 100% of the times". Sometimes I still get no response from the first AT command in the gsmAccess.begin

Quectel claims in some datasheets that you should at least send three "AT" commands to the module before trying to do anything else...

It might be that it tries to do autobauding, which might looks at the bit-patterns of the AT and then tries to guess the baudrate... but that is just my guess. In that case it should be possible to send the module an AT-command to set it to a fixed baudrate, and then save that setting in the module... otherwise there is another problem. I have seen some strange things when using the slow-clock mode of the modem along with the DTR signal, but that is not really related to this issues I think.