AT+CREG? freeze even with a battery connected

Hi all,

It has been mentioned at several places in this forum that MKRGSM1400 needs a 3.7 V lipo battery connected to establish gsm connection. That is because the USB power supply, or a solar power supply cannot provide enough current during the initial negotiation phase between the board and the cellular tower.

According to different messages, the battery should have a capacity > 1500 mAh.

If there is no battery connected, the board will freeze during the GSM connexion, and here is what I can see : If you instantiate the gsm object with the TRUE option, the debug console will show all AT commands

GSM gsmAccess(true);

When you call : gsmAccess.begin(PINNUMBER), at some point the SARA modem will receive several AT+CREG? command, until it picks a signal.

Without battery , or a defective batery, or a battery that cannot furnish enough current, this AT+CREG? loop just freeze, and the board is completely frozen.

If you want to use a MKRGSM1400 with a solar panel, in a remote location, and you require periodic reconnexion to GSM network, you are at risk that the battery is too low at the time of the GSM reconnexion In that case, you lose control of the board.

Yes you could check the battery voltage before reconnecting but I have noticed that this is not a correct indicator. Even a battery like 18650 1S3P 7800mlAh showing more than 4V can sometimes be too weak !

so my question is :

Can this issue be adressed programmatically, by modifying the mkrgsm library ? for example adding time outs in the AT+CREG? loop? so that the whole board does not freeze in case of not enough current being furnished by the battery ?

Or is this a hardware limitation of the board and especially the SARA modem ? In that case, I would say that the mkrgsm1400 board is useless for a remote autonomous project.

I too had the similar problem. The example code is struck at gsmAccess.begin(PINNUMBER). I tried almost all the possibilities in the forum but no luck.

Finally I tried by pushing my SIM card a little more in to the slot and surprisingly it worked. My Lipo battery is just 1000mAh. Now I could able to send SMS and make voice calls even with this 1000mah battery. 2 days got wasted and of course I learned a lot because of this failure.

It might work for you as well. All the best.

Hi Heligone,

It would appear to me that the makers of the board intended it to be used whilst recieving power via the USB port and drawing on the battery as required when doing things like a "AT+creg" type command.

My limited understanding is that you must have both power sources in place and charged/ready to go before trying to do anything such as connect to GPRS etc...

Sounds like you are trying to charge your battery from Solar while relying on it as the only power source? Maybe I'm not reading what you said properly though.

Cheers

Let me know if I am not on the right track with those previous comments, just trying to understand and help you out here.

I note the website for the mkr gsm 1400 says the following:

During cellular transmissions, the peak current required by the board will exceed 500mA. This is in excess of what can be sourced by a standard USB port, so it is MANDATORY to have a 1500 mAh or higher LiPo battery plugged all the time, the current provided by the USB port will be supplemented by the battery. When powering the board using Vin, a 5V power supply that can supply at least 2A is required.

Hopefully you're device is connected with a 5V supply via USB or the Vin port(s) and the solar charger is just hooked up to your battery. I would have a question for you if you are solar charging your battery as I believe the module includes a battery charge function which hopefully you aren't working against or anything.

I see you've tried a few different sketches, let us know how your setup is all plugged together..

Have a good one

Hi @smgs :slight_smile:

Indeed you are on the right track.

Please note that those problems with the modem appear even when I test at the worshop with a usb connection AND a battery.

I think the modem is very unstable.

Not to mention the MKRGSM library which is in my view not quite usable in the present state of affairs

Conclusion for the moment :

  • use tinyGSM library
  • restart the modem before sending any data : takes more time and energy but it seems to avoid modem freeze..
  • implement a watchdog to resart the whole board (even the modem) if it freezes nevertheless (I have not done it yet but I should :wink: )

Here is a test code which has been working for 5 Days, sending Approx. 7500 requests (1 per minute), with USB AND battery connected : that's an improvment !

I am now testing with solar panel and battery.

I am using an adafruit battery charger MCP73871 instead of the charging circuit of MKRGSM becaus I have noticed that the later has an hysteresis that might leave the battery discharge too much (3.6V) before triggering a new charge...

/**************************************************************
   This sketch connects to soracom harvest and sends data with a delay of 30 secs between eaech request
   TinyGSM Getting Started guide:
     http://tiny.cc/tiny-gsm-readme
   For more HTTP API examples, see ArduinoHttpClient library
 **************************************************************/

// Select your modem:
// define TINY_GSM_MODEM_SIM800
// #define TINY_GSM_MODEM_SIM808
// #define TINY_GSM_MODEM_SIM900
#define TINY_GSM_MODEM_UBLOX
// #define TINY_GSM_MODEM_U201
// #define TINY_GSM_MODEM_BG96
// #define TINY_GSM_MODEM_A6
// #define TINY_GSM_MODEM_A7
// #define TINY_GSM_MODEM_M590
// #define TINY_GSM_MODEM_ESP8266

// Increase RX buffer if needed
//#define TINY_GSM_RX_BUFFER 512

#include <TinyGsmClient.h>
#include <ArduinoHttpClient.h>
#include <DHT.h>

// DHT Sensor settings
#define DHTPIN            0        // Pin which is connected to the DHT sensor.
// Uncomment the type of sensor in use:
//#define DHTTYPE           DHT11     // DHT 11
#define DHTTYPE           DHT22     // DHT 22 (AM2302)
//#define DHTTYPE           DHT21     // DHT 21 (AM2301)
//Set to 1 if you would like temperature in Fahrenheit
#define FAHRENHEIT 0
// Initialise DHT Library
DHT dht(DHTPIN, DHTTYPE);

// https://github.com/alexissusset/soracom-mkrgsm1400
// Setting URL to http://harvest.soracom.io
// it also works with TCP but as we'd like to push two sensor values at the same time,
// we'll use HTTP POST method, Harvest detects number in payloads for you could post a simple
// "number" message or otherwise (as we do in this example) a JSON payload with names and values
char url[] = "harvest.soracom.io";
char path[] = "/";

// String response;
String response = "";
String okmsg = "ok";
String errormsg = "error";

// Uncomment this if you want to see all AT commands
#define DUMP_AT_COMMANDS

// Set serial for debug console (to the Serial Monitor, default speed 115200)
#define SerialMon Serial

// Use Hardware Serial on Mega, Leonardo, Micro
#define SerialAT SerialGSM

// Your GPRS credentials
// Leave empty, if missing user or pass
const char apn[]  = "soracom.io";
const char user[] = "sora";
const char pass[] = "sora";

#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, SerialMon);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif

TinyGsmClient client(modem);

void setup() {
  // Set console baud rate
  SerialMon.begin(115200);
  delay(10);

  // Set GSM module baud rate
  SerialAT.begin(57600);
  delay(3000);

}

void loop() {

  // Restart takes quite some time
  // To skip it, call init() instead of restart()
  // SerialMon.println(F("Initializing modem..."));
  // FOR THE MKR GSM 1400
  // https://github.com/vshymanskyy/TinyGSM/pull/161/commits/57170c7565846df19bc87e729ee07aa7477e0597
  // reset / powerup the modem
  pinMode(GSM_RESETN, OUTPUT);
  digitalWrite(GSM_RESETN, HIGH);
  delay(100);
  digitalWrite(GSM_RESETN, LOW);

  // Restart takes quite some time
  // To skip it, call init() instead of restart()
  SerialMon.println(F("Initializing modem..."));
  modem.restart();
  String modemInfo = modem.getModemInfo();
  SerialMon.print(F("Modem: "));
  SerialMon.println(modemInfo);
  // Unlock your SIM card with a PIN
  //modem.simUnlock("1234");

  SerialMon.print(F("Waiting for network..."));
  if (!modem.waitForNetwork()) {
    SerialMon.println(" fail");
    delay(10000);
    return;
  }
  SerialMon.println(" OK");

  SerialMon.print(F("Connecting to "));
  SerialMon.print(apn);
  if (!modem.gprsConnect(apn, user, pass)) {
    SerialMon.println(" fail");
    delay(10000);
    return;
  }
  SerialMon.println(" OK");

  // https://github.com/alexissusset/soracom-mkrgsm1400
  // Read sensor data and send to soracom Harvest
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  float t;
  if (FAHRENHEIT) {
    t = dht.readTemperature(true);
  } else {
    t = dht.readTemperature();
  }

  // If Serial is connected, display current readings
  if (Serial) Serial.print("Humidity: ");
  if (Serial) Serial.print(h);
  if (Serial) Serial.println(" %\t");
  if (Serial) Serial.print("Temperature: ");
  if (Serial) Serial.println(t);

  // Prepare post data
  String PostData = "{\"Temperature\":" + String(t) + ",\"Humidity\":" + String(h) + "}";

  // Connect to Soracom harvest
  if (Serial) Serial.print("Connecting and sending POST request to harvest.soracom.io...");
  int res_connect;

  res_connect = client.connect(url, 80);

  // If connection is successful, POST JSON data
  if (res_connect) {
    client.println("POST / HTTP/1.1");
    client.println("Host: harvest.soracom.io");
    client.println("User-Agent: Arduino/1.0");
    client.println("Connection: close");
    client.print("Content-Length: ");
    client.println(PostData.length());
    client.println();
    client.println(PostData);

    if (Serial) Serial.println(okmsg);

    unsigned long timeout = millis();
    while (client.connected() && millis() - timeout < 10000L) {
      // Print available data
      while (client.available()) {
        char c = client.read();
        Serial.print(c);
        timeout = millis();
      }
    }

    // if the server's disconnected, stop the client:
    if (!client.available() && !client.connected()) {
      Serial.println();
      Serial.println("disconnecting...");
      client.stop();
    }

  } else {
    // if we didn't get a connection to the server
    Serial.println(errormsg);
    Serial.println("No Connection to server");
  }

  // Shutdown
  modem.gprsDisconnect();
  SerialMon.println(F("GPRS disconnected"));

  delay(30000);
}

Thanks for sharing your code, much easier to get a picture of what's going on being able to look at that.

By any chance are you using those Temperature sensors with a 5V supply from your MKR GSM 1400?

If so then you should be doing Level Shifting so that the input recieved back to your MKR GSM unit is coming back in at 3.3v not 5v....

I've had some success powering my basic light sensor that I use for testing using the VCC rail instead of a 5v rail.
VCC: This pin outputs 3.3V through the on-board voltage regulator. This voltage is 3.3V if USB or VIN is used and equal to the series of the two batteries when they are used

From the Arduino site:
Warning: Unlike most Arduino & Genuino boards, the MKR GSM 1400 runs at 3.3V. The maximum voltage that the I/O pins can tolerate is 3.3V. Applying voltages higher than 3.3V to any I/O pin could damage the board. While output to 5V digital devices is possible, bidirectional communication with 5V devices needs proper level shifting.

All the libraries appear to do about the same thing so not sure why you are having more success with the Tiny GSM library than the MKR GSM 1400 libraries. I've not had any issues with the MKR ones personally but maybe I'm just lucky.

Helle smgs and thanks for your advice.

I have not encountered any problem with the voltage of the temperature and humidity sensor AM2302, but I will check the documentation you are pointing to.

About mkrgsm library, there is first a big problem : when you are connecting to gsm network using gsm.begin(), if no network is available, the code enters an inifite loop...tinygsm does not behave in this odd way.

You might not notice this problem if you are in a location with a reliable network coverage,

All the best