TinyGSM gprs and lte connection clarification

Hello.

My test system is a ttgo AX7670 board with a A7670E SIMCOM modem. This is my test code:

// #define TINY_GSM_MODEM_SIM7000
#define TINY_GSM_MODEM_SIM7600

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

// Set serial for AT commands (to the module)
// Use Hardware Serial on Mega, Leonardo, Micro
#define SerialAT Serial1

// See all AT commands, if wanted
// #define DUMP_AT_COMMANDS

// Define the serial console for debug prints, if needed
#define TINY_GSM_DEBUG SerialMon

/*
 * Tests enabled
 */
#define TINY_GSM_TEST_GPRS false
#define TINY_GSM_TEST_WIFI false
#define TINY_GSM_TEST_CALL false
#define TINY_GSM_TEST_SMS true
#define TINY_GSM_TEST_USSD false
#define TINY_GSM_TEST_BATTERY false
#define TINY_GSM_TEST_GPS false
#define TINY_GSM_POWERDOWN true   // powerdown modem after tests
#define TINY_GSM_TEST_WEB_SERVER true

// set GSM PIN, if any
#define GSM_PIN ""

//SMS target number
#define SMS_TARGET  "87101766"  //Poner aquí el número de teléfono para SMS

// Your GPRS credentials, if any
const char apn[]  = "kolbi3g";
const char gprsUser[] = "";
const char gprsPass[] = "";

// Web Server details
const char server[]   = "vsh.pp.ua";
const char resource[] = "/TinyGSM/logo.txt";

#include <TinyGsmClient.h>
#include <Ticker.h>

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

Ticker tick;
#ifdef USE_SSL
TinyGsmClientSecure client(modem);
const int           port = 443;
#else
TinyGsmClient  client(modem);
const int      port = 80;
#endif

#define uS_TO_S_FACTOR          1000000ULL  /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP           60          /* Time ESP32 will go to sleep (in seconds) */

#define PIN_TX                  27
#define PIN_RX                  26
#define UART_BAUD               115200
#define PWR_PIN                 4
#define LED_PIN                 12
#define POWER_PIN               25
#define IND_PIN                 36
#define PMU_IRQ                 35
#define I2C_SDA                 21
#define I2C_SCL                 22

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


    // Onboard LED light, it can be used freely
    pinMode(LED_PIN, OUTPUT);
    digitalWrite(LED_PIN, LOW);

    // POWER_PIN : This pin controls the power supply of the SIM7600
    pinMode(POWER_PIN, OUTPUT);
    digitalWrite(POWER_PIN, HIGH);

    // PWR_PIN : This Pin is the PWR-KEY of the SIM7600
    // The time of active low level impulse of PWRKEY pin to power on module , type 500 ms
    pinMode(PWR_PIN, OUTPUT);
    digitalWrite(PWR_PIN, HIGH);
    delay(500);
    digitalWrite(PWR_PIN, LOW);

    // IND_PIN: It is connected to the SIM7600 status Pin,
    // through which you can know whether the module starts normally.
    pinMode(IND_PIN, INPUT);

    attachInterrupt(IND_PIN, []() {
        detachInterrupt(IND_PIN);
        // If SIM7600 starts normally, then set the onboard LED to flash once every 1 second
        tick.attach_ms(1000, []() {
            digitalWrite(LED_PIN, !digitalRead(LED_PIN));
        });
    }, CHANGE);

    DBG("Wait...");

    delay(3000);

    SerialAT.begin(UART_BAUD, SERIAL_8N1, PIN_RX, PIN_TX);

    // Restart takes quite some time
    // To skip it, call init() instead of restart()
    DBG("Initializing modem...");
    if (!modem.init()) {
        DBG("Failed to restart modem, delaying 10s and retrying");
        return;
    }

    //Set to GSM mode, please refer to manual 5.11 AT+CNMP Preferred mode selection for more parameters
    /*
    2 Automatic
    13 GSM Only
    14 WCMDA Only
    38 LTE Only
    */
    bool result;
    result = modem.setNetworkMode(38);
    Serial.println("SetNetworkMode result: "+String(result));
    if (modem.waitResponse(10000L) != 1) {
        DBG(" setNetworkMode faill");
        //return ;
    }

    int netWorkMode = modem.getNetworkMode();
    Serial.printf("Current network mode set to: %d (2 Auto, 13 GSM, 14 WCMDA, 38 LTE): \n",netWorkMode);

#if TINY_GSM_TEST_GPS
    //https://github.com/vshymanskyy/TinyGSM/pull/405
    uint8_t mode = modem.getGNSSMode();
    Serial.print("Current GNSS Mode (1=GPS 2 BDS 3=GPS + BDS 4=GLONASS 5=GPS + GLONASS 6=BDS + GLONASS 7=GPS + BDS + GLONASS): ");
    Serial.println(mode);
    /**
     *  CGNSSMODE: <gnss_mode>,<dpo_mode>
     *  This command is used to configure GPS, GLONASS, BEIDOU and QZSS support mode.
     *  gnss_mode:
     *      0 : GLONASS  --ruso
     *      1 : BEIDOU  --chino
     *      2 : GALILEO  --europa
     *      3 : QZSS --japón
     *  dpo_mode :
     *      0 disable
     *      1 enable
     According to A7670 doc
      1 GPS
      2 BDS
      3 GPS + BDS
      4 GLONASS
      5 GPS + GLONASS
      6 BDS + GLONASS
      7 GPS + BDS + GLONASS
     */
    uint16_t gnssMode = 7;
    Serial.print("Set GNSS Mode to :"+String(gnssMode));
    String res = modem.setGNSSMode(gnssMode, 1);
    Serial.println(res);
    delay(1000);
#endif

}

void loop()
{
    // Restart takes quite some time
    // To skip it, call init() instead of restart()
  //   DBG("Initializing modem...");
  //    if (!modem.restart()) {
  //        DBG("Failed to restart modem, delaying 10s and retrying");
  //        return;
  //    }

  String name = modem.getModemName();
  DBG("Modem Name:", name);

  String modemInfo = modem.getModemInfo();
  DBG("Modem Info:", modemInfo);

#if TINY_GSM_TEST_GPRS
    // Unlock your SIM card with a PIN if needed
    if ( GSM_PIN && modem.getSimStatus() != 3 ) {
        modem.simUnlock(GSM_PIN);
    }
#endif

#if TINY_GSM_TEST_GPRS && defined TINY_GSM_MODEM_XBEE
    // The XBee must run the gprsConnect function BEFORE waiting for network!
    modem.gprsConnect(apn, gprsUser, gprsPass);
#endif

    DBG("Waiting for network...");
    if (!modem.waitForNetwork()) {
        delay(10000);
        return;
    }

    if (modem.isNetworkConnected()) {
        DBG("Network connected");
    }

  SerialAT.println("AT+CEREG?");
  delay(500);
  if (SerialAT.available()){
    String input = SerialAT.readString();
    Serial.printf("CEREG?: %s \n",input.c_str());
  }

#if TINY_GSM_TEST_GPRS
    DBG("Connecting to", apn);
    if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
        delay(10000);
        return;
    }

    bool res = modem.isGprsConnected();
    DBG("GPRS status:", res ? "connected" : "not connected");
//#endif
    String ccid = modem.getSimCCID();
    DBG("CCID:", ccid);

    String imei = modem.getIMEI();
    DBG("IMEI:", imei);

    String cop = modem.getOperator();
    DBG("Operator:", cop);

    IPAddress local = modem.localIP();
    DBG("Local IP:", local);

    int csq = modem.getSignalQuality();
    DBG("Signal quality:", csq);

#endif

#if TINY_GSM_TEST_GPS

    //Disable gnss
    modem.sendAT("+CGNSSPWR=0");
    modem.waitResponse(10000L);

    //Enable gnss
    modem.sendAT("+CGNSSPWR=1");
    modem.waitResponse(10000L);

    //Wait gnss start.
    SerialMon.print("\tWait GPS ready.");
    while (modem.waitResponse(1000UL, "+CGNSSPWR: READY!") != 1) {
        SerialMon.print(".");
    }
    SerialMon.println();

    //Set gnss mode use GPS.
    modem.sendAT("+CGNSSMODE=7");  //1 = GPS 7 = GPS, GLONAS, BEIDOU
    modem.waitResponse(10000L);

    modem.enableGPS();
    float lat,  lon, speed, alt;
    int vsat, usat;
    float accuracy;
    int year,month,day,hour,minute,second;
    while (1) {
      if (modem.getGPS(&lat, &lon, &speed, &alt, &vsat, &usat, &accuracy, &year, &month, &day, &hour, &minute, &second)) {
        Serial.printf("lat:%f lon:%f, speed:%f, alt:%f, vsat:%d, usat:%d, accu:%f, year:%d, month:%d, day:%d, hour:%d, minute:%d, second:%d\n", 
                        lat, lon, speed, alt, vsat, usat, accuracy, year, month, day, hour, minute, second);
        
        /** THIS IS ORIGINAL CODE THAT HAS ISSUES WITH INDEXES USED TO EXTRACT VALUES.  THIS EXAMPLE NEEDS THE TinyGsMcLIENTsim7600.h fix made by jbejarano to work **/
        /*modem.sendAT(GF("+CGNSSINFO"));
        Format for CGNSSINFO at https://www.manualslib.com/manual/1889278/Simcom-Sim7500-Series.html?page=391
        format: [<mode>],[<GPS-SVs>],[<GLONASS-SVs>],[<BEIDOU-SVs>],[<unknown],[<lat>]  ,[<N/S>],[<log>]   ,[<E/W>],[<date>],[<UTC-time>],[<alt>], [<speed>],[<course>],[<PDOP>],[HDOP],[VDOP]
        example:    3   ,     14    ,               ,              ,          ,9.8503294,    N  ,83.9305038,   W   ,110723  ,  202457.00 ,1446.6 ,   0.201  ,          ,  3.90  , 2.96 ,2.54,05
        */
        /*
        if (modem.waitResponse(GF(GSM_NL "+CGNSSINFO:")) == 1) {
            String res = modem.stream.readStringUntil('\n');
            Serial.println(res);
            String lat = "";
            String n_s = "";
            String lon = "";
            String e_w = "";
            res.trim();
            lat = res.substring(8, res.indexOf(',', 8));
            n_s = res.substring(19, res.indexOf(',', res.indexOf(',', 19)));
            lon = res.substring(21, res.indexOf(',', res.indexOf(',', 21)));
            e_w = res.substring(33, res.indexOf(',', res.indexOf(',', 33)));
            delay(100);
            Serial.println("****************GNSS********************");
            Serial.printf("lat:%s %s\n", lat.c_str() , n_s.c_str());
            Serial.printf("lon:%s %s\n", lon.c_str(), e_w.c_str());
            float flat = atof(lat.c_str());
            float flon = atof(lon.c_str());
            Serial.printf("flat: %f",flat);
            Serial.printf("flon: %f",flon);            
            flat = (floor(flat / 100) + fmod(flat, 100.) / 60) *
                    (n_s == "N" ? 1 : -1);
            flon = (floor(flon / 100) + fmod(flon, 100.) / 60) *
                    (e_w == "E" ? 1 : -1);
            
            Serial.print("Latitude:"); Serial.println(flat);
            Serial.print("Longitude:"); Serial.println(flon);
        }*/

        break;
      } else {
        Serial.print("Searching GPS satellites...");
        Serial.println(millis());
      }
      delay(2000);
    }
    modem.disableGPS();

    //Disable gnss
    modem.sendAT("+CGNSSPWR=0");
    modem.waitResponse(10000L);
#endif

#if TINY_GSM_TEST_SMS
  #if TINY_GSM_TEST_GPRS
  bool smsres = modem.sendSMS(SMS_TARGET, String( " imei: " + imei + 
                                          " Signal: " + String(csq)));
  DBG("SMS:", smsres ? "OK" : "fail");
  #else
  bool smsres = modem.sendSMS(SMS_TARGET, String("No GPRS mode active"));
  DBG("SMS:", smsres ? "OK" : "fail");  
  #endif 
#endif

#if TINY_GSM_TEST_WEB_SERVER

  SerialMon.print("Connecting to ");
  SerialMon.println(server);
  if (!client.connect(server, port)) {
    SerialMon.println(" fail");
    delay(10000);
    return;
  }
  SerialMon.println("Connection to endpoint successful");

// Make a HTTP GET request:
  SerialMon.println("Performing HTTP GET request...");
  client.print(String("GET ") + resource + " HTTP/1.1\r\n");
  client.print(String("Host: ") + server + "\r\n");
  client.print("Connection: close\r\n\r\n");
  client.println();

  uint32_t timeout = millis();
  while (client.connected() && millis() - timeout < 10000L) {
    // Print available data
    while (client.available()) {
      char c = client.read();
      SerialMon.print(c);
      timeout = millis();
    }
  }
  SerialMon.println();
  // Shutdown
  client.stop();
  SerialMon.println(F("Server disconnected"));
#endif

#if TINY_GSM_TEST_GPRS
    modem.gprsDisconnect();
    if (!modem.isGprsConnected()) {
        DBG("GPRS disconnected");
    } else {
        DBG("GPRS disconnect: Failed.");
    }
#endif

#if TINY_GSM_POWERDOWN
    // Try to power-off (modem may decide to restart automatically)
    // To turn off modem completely, please use Reset/Enable pins
    modem.poweroff();
    DBG("Poweroff.");
#endif

    // Test is complete Set it to sleep mode
    esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
    delay(200);
    esp_deep_sleep_start();
}

20:46:26.183 -> [525] Wait...

20:46:29.159 -> [3525] Initializing modem...

20:46:29.159 -> [3526] ### TinyGSM Version: 0.11.5

20:46:29.206 -> [3526] ### TinyGSM Compiled Module: TinyGsmClientSIM7600

20:46:36.599 -> [10926] ### Unhandled: *ISIMAID: "A0000000871004FFFFF00189000001FF"

20:46:36.958 -> [11331] ### Modem: AT

20:46:36.958 -> [11331] ### Modem: AT

20:46:37.003 -> SetNetworkMode result: 1

20:46:37.127 -> Current network mode set to: 38 (2 Auto, 13 GSM, 14 WCMDA, 38 LTE):

20:46:37.215 -> [11558] ### Modem: A7670E-FASE

20:46:37.215 -> [11558] Modem Name: A7670E-FASE

20:46:37.251 -> [11587] Modem Info: Manufacturer: INCORPORATED Model: A7670E-FASE Revision: A7670M7_V1.11.1 IMEI: 862205052863802 +GCAP: +CGSM,+FCLASS,+DS

20:46:37.251 -> [11598] Waiting for network...

20:46:41.890 -> [16222] Network connected

20:46:43.370 -> CEREG?:

20:46:43.370 -> +CEREG: 0,1

20:46:43.370 ->

20:46:43.370 -> OK

20:46:43.370 ->

20:46:46.454 -> [20792] SMS: OK

20:46:46.454 -> Connecting to vsh.pp.ua

20:46:46.454 -> fail

20:46:56.451 -> [30812] Modem Name: SIMCom SIM7600

20:46:56.491 -> [30824] Modem Info: PB DONE A7670E-FASE

20:46:56.491 -> [30824] Waiting for network...

20:46:56.491 -> [30839] Network connected

20:46:57.996 -> CEREG?:

20:46:57.996 -> +CEREG: 0,1

20:46:57.996 ->

20:46:57.996 -> OK

20:46:57.996 ->

20:46:58.891 -> [33250] SMS: OK


As shown the modem supports LTE connection so I set modem.setNetworkMode(38) so I can use LTE.   The gprs code is disabled #define TINY_GSM_TEST_GPRS false.   The connection by TCP to the endopint vsh.pp.ua FAILS.  Why if there is LTE connection?  The Network is connected as shown in the output.   Now, if I enable the gprs connection it works.   Why if the connection mode is LTE the web server connection works with GPRS enabled.  My target is to connect throug EPS connection and no any GSM (gprs connection).   Probabily I am missunderstanding concepts.  Any clarification from the team is appreciated.

Don't rely on blind delays:

The end of your post got lost in code format - so here it is legibly:

You do call modem.setNetworkMode(38) - but you don't check if that succeeds.

Does it require login ?

No it doesn't, sir. Actually when the GPRS connection is made the endpoint connection is succesful and the GET is done without any issue. Also at PC Browser level the page is displayed. At the other hand I have an update about this "issue" and looks like I found the answer to my question in the TinyGSM developer repository. Look at this statement:

If using cellular, establish the GPRS or EPS data connection after your are successfully registered on the network

  • modem.gprsConnect(apn, gprsUser, gprsPass) (or simply modem.gprsConnect(apn))
  • The same command is used for both GPRS or EPS connection

Looks like the gprsConnect method name played me a bad and I thought it was exclusively to stablish gprs connection but looks like it is also used for a EPS connection too. Now the everything makes sense at my side.

I appreciate your time to look at this topic, sir. :+1:

1 Like

I’m posting this question here because it falls under the same category of clarification of TinyGSM and LTE connections.

I’m using a LilyGO T-SIM7000G controller using a SuperSIM from Twilio to send sensor data to a MongoDB database. The TinyGsm library is the heart. I based the code on the TinyGsm examples but admittedly don’t fully understand all the library’s functions. I have successfully sent the data in daily bursts to the database for days at a time. However, I’ve experienced days of outage throughout August. Network connections fail for hours at a time but if I wait long enough, things will connect and go back to working. Looking at Twilio, AT&T and T-Mobile sites for information on outages has been challenging.
Questions:

  1. I don’t know exactly what to look for regarding the status of the LTE-M networks that I understand is the underlying communication path. Guidance? Is it just the 4G/5G network as a whole?
  2. Chats with Twilio support says there were no Twilio outages when I experienced it. I did see their site listing the SMS network having multiple maintenance windows roughly at the times I did experience outages . Twilio points out the SMS and LTE-M networks are separate. Are the TinyGSM gprsConnect(), gprsConnect(), waitForNetwok,(), or isNetworkConnected() functions still dependent on something dealing with the SMS network? The Twilio page (Guidance on using Simcom cellular modules with Twilio Super SIM | Twilio) has a much simpler procedure for connections than what I see in the TinyGSM library so I’m trying to reason it all out…any guidance?
  3. Finally… there was a mention not to rely on blind delays after AT commands. I’m assuming what was meant was to read the response and then act. Since I’m just starting to try to code the AT commands myself in an attempt to solve things, can someone provide a snippet of code with the proper way to wait and capture that response?

What are you guys trying to do?

I ditched the TinyGSM library, way to compex and heavy, for nothing. My goal was quite simple; send and revice sms, recive gps data as time, date, position, signal strength and so on. I managed to do it without any library and a minimum of code.

Before using anything, use manually AT commands. Then you can controll and test stability of the module, before writing gsm module control code. I used this simple code a a start, it let you write and recive to the gsm module, by echo data from the module. Remember that the serial buffer is 64 bytes and it wil fill up if you try to parse strings recived from the module. So for gps data parsing, I had to read a byte at a time.

This is code can be used with uno, as uno do not have any hardware serial. I would not advise using software serial in the long run, as it is slow and sometimes unstable. But for simple test with uno, it is ok.

Also, gsm and gprs is two different things. And AT+CGNSINF command do not give you NMEA data.

 #include <SoftwareSerial.h>


#define rxPin 2
#define txPin 3

SoftwareSerial mySerial(rxPin, txPin);

void setup()
{
  mySerial.begin(9600);               // GSM module baud rate
  Serial.begin(9600);                 // GSM module baud rate 
}

void loop()
{
   if (mySerial.available())
    Serial.write(mySerial.read());  // Arduino send the computer command to SIMCOM 7000
   
   if (Serial.available())
    mySerial.write(Serial.read());  //Arduino send the SIMCOM 7000 feedback to computer
}

:point_up_2: :point_up_2: :point_up_2: This!! :point_up_2: :point_up_2: :point_up_2:

:clap: :clap: :clap:

Thank you for contributing but it did not quite answer the questions. I agree manually entering AT commands is a good way to start and learn, in fact I did that originally when I started to use the controller. I now have a fully functioning coded application and the questions were geared toward understanding how the networks work in an effort to understand some of the outages I experienced. Manually entering AT commands I don't see would address that.

IF your point is to get rid of the TinyGsm library and write my own initialization and connection sequence and manually enter AT commands to start that, I can see that might come in. I suspect the TinyGsm library is a contributing factor, I'm trying understand that as well, replacing it with something simpler is welcomed.

As I try to write my own connection sequence I don't currently understand how to connect my current code to such an AT command sequence. I have manually exercised AT sequences that use some built in HTTP clients to do a HTTP GET as an example, but translating that into a connection to my code and using my current http(s) client syntax is currently beyond me. I rather not do a major rewriting of functional code to use the modem built in functions that I used with the examples. If you have a code examples to show the sequence and code connections feel free to share.

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