Getting Started with LILYGO T-SIM7000G ESP32 (LTE, GPRS, and GPS)

Get started with the ESP32 and the SIM7000G LTE/GPS/GPRS module. Throughout this tutorial, we’ll use the LILYGO T-SIM7000G ESP32 board that combines the ESP32 chip, the SIM7000G module, microSD card slot, battery holder, and charger on the same board. Besides Wi-Fi and Bluetooth, you can communicate with this ESP32 board using SMS. You can also connect it to the internet using your SIM card data plan and get GPS location.

Getting Started with LILYGO T-SIM7000G ESP32 LTE GPRS GPS

Compatibility

This board supports 2G, LTE CAT-M1, and NB-IoT protocols. You can go to the following links to check if any of these protocols are supported in your country:

Check network protocols supported in your country;

Check NB-IoT providers in your country.

Introducing the LILYGO T-SIM7000G ESP32

The LILYGO T-SIM7000G is an ESP32 development board with a SIM7000G chip. This adds GPS, GPRS, LTE CAT-M1, and NB-IoT protocols to your board. This means that with this board you can send SMS, get location and time using GPS, and connect it to the internet using a SIM card data plan. This board doesn’t support phone calls.

LILYGO T-SIM7000G ESP32

Besides the SIM7000G module, the board also comes with some interesting features like a battery holder for an 18650 battery, a battery charging circuit where you can connect solar panels to recharge the battery, and a microSD card slot that can be useful for data logging projects or to save configuration settings.

Here’s a summary of the LILYGO T-SIM7000G ESP32 board features:

  • Supply voltage: 3.3V DC or 5V DC
  • ESP32 chip (WROVER-B Module) (240MHz dual-core processor)
  • Flash memory: 4MB
  • PSRAM: 8MB
  • SRAM: 520KB
  • Built-in Wi-Fi
  • Built-in Bluetooth
  • USB to serial converter: CP2104 or CH9102 (drivers)
  • Built-in SIM7000G module
  • Built-in nano SIM card slot
  • Built-in SIM antenna slot
  • Built-in GPS antenna slot
  • Built-in Li-ion/Li-Po battery charging circuit:
    • DW01A battery protection IC
    • CN3065 solar energy charging interface for 4.4-6.8V solar panel
    • Built-in 1x 18650 battery holder
    • Built-in solar panel connector 2p JST-PH
  • Built-in Micro SD card slot
  • Built-in on/off switch

To use the capabilities of this board you need to have a nano SIM card with a data plan and a USB-C cable to upload code to the board.

The package includes an external antenna for LTE and another antenna for GPS.

ESP32 SIM7000G GPS antenna and SIM antenna

There are two versions of this board (Version 20191227 and Version 20200415). The picture below shows the two versions. Visually, they mainly differ on the position of the nano SIM card holder.

LILYGO ESP32 SIM7000G OLD VS NEW MODEL

The first version had some design issues, so it is recommended to get the latest version. Aditionally, the latest version comes with some improvements taking into account users’ feedback. I got my board a long time ago, I’ve got the first version and that’s the one we’ll use throughout this tutorial. However, this is also compatible with the latest board.

Here’s a list of the improvements on the latest version (check the documentation):

  • Added active GPS antenna power control, when the module GPIO 4 is not turned on, the antenna consumes only the static current of the LDO;
  • Replaced TP4056 with CN3065 for solar charge input management;
  • Added reverse battery protection;
  • Added battery overcharge protection;
  • Added battery over-discharge protection.

You can check the schematic diagrams for each version on the following links:

Where to buy LILYGO T-SIM7000G ESP32?

Check the following link:

All stores in the previous link should sell the latest version but double-check the product page, just in case the seller changes something.

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

LILYGO T-SIM7000G ESP32 Pinout

The following pictures show the pinout of the T-SIM7000G ESP32 board.

This is the pinout for version V1.0.

And this is the pinout for the improved board V1.1.

The following table shows the connections between the ESP32 and the SIM7000G chip:

SIM7000GESP32
TXGPIO 26
RXGPIO 27
POWERGPIO 4

To communicate with the microSD card, you need SPI communication protocol. These are the GPIOs used:

MicroSD Card (TF card)ESP32
MOSIGPIO 15
SCLKGPIO 14
CSGPIO 13
MISOGPIO 2

SIM Card

This board only supports nano SIM cards. You need a SIM card for LTE and GPRS. However, if you only want to use GPS data, you don’t need a SIM card.

LILYGO T-SIM7000G ESP32 nano SIM card

To use LTE and GPRS you need a SIM card with some data plan. This can be expensive in some countries, so it might be cost-prohibitive depending on how much you can get a data plan for in your country.

Compatibility

This board supports 2G, LTE CAT-M1, and NB-IoT protocols. You can go to the following links to check if any of these protocols are supported in your country:

Check network protocols supported in your country;

Check NB-IoT providers in your country.

Where we live (Portugal), we can get a SIM card with data plan, calls, and SMS (enough for ESP32 projects) for approximately $12. We recommend using a SIM card with a prepaid or monthly plan, so that you know exactly how much you’ll spend. There are also companies specialized in SIM cards for IoT projects.

APN Details

To connect your SIM card to the internet, you need to have your phone plan provider’s APN details. You need the domain name, username, and password.

In my case, I’m using Vodafone Portugal. If you search for GPRS APN settings followed by your phone plan provider name, (in my case its: “GPRS APN Vodafone Portugal”), you can usually find in a forum or in their website all the information that you need.

It might be a bit tricky to find the details if you don’t use a well-known provider. So, you might need to contact them directly.

AT Commands

AT commands are used to control MODEMs, as is the case of the SIM7000G. In the case of the ESP32, you send the AT commands via serial communication protocol. Then, the modem responds back also via serial communication.

There are four types of AT commands: test; read; set; execution. You can find the complete list of AT commands for the SIM7000G on the following link:

Here are some of the most common AT commands:

  • check communication with the module: AT
  • check if SIM card is ready: AT+CPIN?
  • check the registration status of the device: AT+CGREG?
  • send SMS to a number: AT+CMGS=PHONE_NUMBER(in international format)

Libraries

As we explained previously, the ESP32 communicates with the SIM7000G chip by sending AT commands via serial communication. You don’t need a library, you can simply establish a serial communication with the module and start sending AT commands.

However, it might be more practical to use a library. For example, the TinyGSM library knows which commands to send, and how to handle AT responses, and wraps that into the standard Arduino Client interface—that’s the library we’ll use in this tutorial.

Installing the TinyGSM Library

Open your Arduino IDE and go to Sketch Include Library > Manage Libraries. The Library Manager should open. Search for TinyGSM. Select the TinyGSM library by Volodymyr Shymanskyy.

Arduino IDE 2 Install TinyGSM Library using Libraries Manager

You also need to install the StreamDebugger library. Go to Sketch Include Library > Manage Libraries, search for StreamDebugger, and install it.

Arduino IDE 2 Install StreamDebugger Library using Libraries Manager

Preparing the LILYGO T-SIM7000G ESP32 Board

Before testing your board, you need to follow the next steps:

1) Insert a nano SIM card;

Nano SIM card vodafone

2) Connect the Full Band LTE antenna (SIM);

3) Connect the GPS antenna.

ESP32 T-SIM7000G antennas

If you want to test the microSD card features, you should only connect a microSD card, after uploading the code.

LILYGO T-SIM7000G ESP32 Network Test

The first sketch you should run on your board is the Network Test. This will tell you the network selection settings you should use—this depends on the SIM card, modem(SIM7000G), and the mobile network operator it uses.

  1. Copy the following code to your Arduino IDE (the code was adapted from this example).
/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/lilygo-t-sim7000g-esp32-lte-gprs-gps/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

// Original code: https://github.com/Xinyuan-LilyGO/LilyGO-T-SIM7000G/blob/master/examples/Arduino_NetworkTest/Arduino_NetworkTest.ino

#define TINY_GSM_MODEM_SIM7000
#define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb

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

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

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

// Your GPRS credentials, if any
const char apn[]  = "";     //SET TO YOUR APN
const char gprsUser[] = "";
const char gprsPass[] = "";

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

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

// LilyGO T-SIM7000G Pinout
#define UART_BAUD           115200
#define PIN_DTR             25
#define PIN_TX              27
#define PIN_RX              26
#define PWR_PIN             4

#define SD_MISO             2
#define SD_MOSI             15
#define SD_SCLK             14
#define SD_CS               13
#define LED_PIN             12


void modemPowerOn(){
  pinMode(PWR_PIN, OUTPUT);
  digitalWrite(PWR_PIN, LOW);
  delay(1000);
  digitalWrite(PWR_PIN, HIGH);
}

void modemPowerOff(){
  pinMode(PWR_PIN, OUTPUT);
  digitalWrite(PWR_PIN, LOW);
  delay(1500);
  digitalWrite(PWR_PIN, HIGH);
}


void modemRestart(){
  modemPowerOff();
  delay(1000);
  modemPowerOn();
}

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

  delay(10);

  // Set LED OFF
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);

  modemPowerOn();

  Serial.println("========SDCard Detect.======");
  SPI.begin(SD_SCLK, SD_MISO, SD_MOSI);
  if (!SD.begin(SD_CS)) {
      Serial.println("SDCard MOUNT FAIL");
  } else {
    uint32_t cardSize = SD.cardSize() / (1024 * 1024);
    String str = "SDCard Size: " + String(cardSize) + "MB";
    Serial.println(str);
  }
  Serial.println("===========================");

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


  Serial.println("/**********************************************************/");
  Serial.println("To initialize the network test, please make sure your LTE ");
  Serial.println("antenna has been connected to the SIM interface on the board.");
  Serial.println("/**********************************************************/\n\n");

  delay(10000);
}

void loop(){
  String res;

  Serial.println("========INIT========");

  if (!modem.init()) {
    modemRestart();
    delay(2000);
    Serial.println("Failed to restart modem, attempting to continue without restarting");
    return;
  }

  Serial.println("========SIMCOMATI======");
  modem.sendAT("+SIMCOMATI");
  modem.waitResponse(1000L, res);
  res.replace(GSM_NL "OK" GSM_NL, "");
  Serial.println(res);
  res = "";
  Serial.println("=======================");

  Serial.println("=====Preferred mode selection=====");
  modem.sendAT("+CNMP?");
  if (modem.waitResponse(1000L, res) == 1) {
    res.replace(GSM_NL "OK" GSM_NL, "");
    Serial.println(res);
  }
  res = "";
  Serial.println("=======================");


  Serial.println("=====Preferred selection between CAT-M and NB-IoT=====");
  modem.sendAT("+CMNB?");
  if (modem.waitResponse(1000L, res) == 1) {
    res.replace(GSM_NL "OK" GSM_NL, "");
    Serial.println(res);
  }
  res = "";
  Serial.println("=======================");


  String name = modem.getModemName();
  Serial.println("Modem Name: " + name);

  String modemInfo = modem.getModemInfo();
  Serial.println("Modem Info: " + modemInfo);

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

  for (int i = 0; i <= 4; i++) {
    uint8_t network[] = {
        2,  /*Automatic*/
        13, /*GSM only*/
        38, /*LTE only*/
        51  /*GSM and LTE only*/
    };
    Serial.printf("Try %d method\n", network[i]);
    modem.setNetworkMode(network[i]);
    delay(3000);
    bool isConnected = false;
    int tryCount = 60;
    while (tryCount--) {
      int16_t signal =  modem.getSignalQuality();
      Serial.print("Signal: ");
      Serial.print(signal);
      Serial.print(" ");
      Serial.print("isNetworkConnected: ");
      isConnected = modem.isNetworkConnected();
      Serial.println( isConnected ? "CONNECT" : "NO CONNECT");
      if (isConnected) {
        break;
      }
      delay(1000);
      digitalWrite(LED_PIN, !digitalRead(LED_PIN));
    }
    if (isConnected) {
        break;
    }
  }
  digitalWrite(LED_PIN, HIGH);

  Serial.println();
  Serial.println("Device is connected .");
  Serial.println();

  Serial.println("=====Inquiring UE system information=====");
  modem.sendAT("+CPSI?");
  if (modem.waitResponse(1000L, res) == 1) {
    res.replace(GSM_NL "OK" GSM_NL, "");
    Serial.println(res);
  }

  Serial.println("/**********************************************************/");
  Serial.println("After the network test is complete, please enter the  ");
  Serial.println("AT command in the serial terminal.");
  Serial.println("/**********************************************************/\n\n");

  while (1) {
    while (SerialAT.available()) {
      SerialMon.write(SerialAT.read());
    }
    while (SerialMon.available()) {
      SerialAT.write(SerialMon.read());
    }
  }
}

View raw code

  1. Insert your SIM card pin, if you have it. In my case, I disabled the pin.
#define GSM_PIN ""
  1. Insert your apn details on the following lines:
const char apn[]  = "";     //SET TO YOUR APN
const char gprsUser[] = "";
const char gprsPass[] = "";

For example, in my case:

const char apn[]  = "net2.vodafone.pt";     //SET TO YOUR APN
const char gprsUser[] = "vodafone";
const char gprsPass[] = "vodafone";
  1. Go to Tools > Board and select ESP32 Dev Module.
  1. Finally, upload the code to your board.
Arduino 2.0 Upload Button

Now, you can insert a microSD card, if you want to test the microSD card features.

ESP32 T-SIM7000G microSD card

Then, open the Serial Monitor at a baud rate of 115200. Press the on-board RST button to restart the board.

Wait some time until the board connects to the network (in my case, it may take up to 2 minutes).

You should get something similar in the Serial Monitor.

ESP32 SIM7000G Network Test Serial Monitor

You can see that it identifies the microSD card and connects to the network successfully.

Check the preferred mode selection and the preferred selection between CAT-M and NB-IoT. You’ll need those parameters later, and they differ depending on your SIM card and provider.

LILYGO T-SIM7000G ESP32: Connect to the Internet, Send SMS, and Get GPS Data

If everything went as expected, now you’re ready to test other functions like connecting to the internet, sending SMS, and getting GPS data.

Copy the following code to your Arduino IDE. This code was adapted from this example.

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/lilygo-t-sim7000g-esp32-lte-gprs-gps/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

// Based on the following example: https://github.com/Xinyuan-LilyGO/LilyGO-T-SIM7000G/blob/master/examples/Arduino_TinyGSM/AllFunctions/AllFunctions.ino

#define TINY_GSM_MODEM_SIM7000
#define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb
#define SerialAT Serial1

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

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

// Your GPRS credentials, if any
const char apn[]  = "";     //SET TO YOUR APN
const char gprsUser[] = "";
const char gprsPass[] = "";

// Set phone number, if you want to test SMS
// Set a recipient phone number to test sending SMS (it must be in international format including the "+" sign)
#define SMS_TARGET  ""

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

#ifdef DUMP_AT_COMMANDS  // if enabled it requires the streamDebugger lib
  #include <StreamDebugger.h>
  StreamDebugger debugger(SerialAT, Serial);
  TinyGsm modem(debugger);
#else
  TinyGsm modem(SerialAT);
#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 UART_BAUD   115200
#define PIN_DTR     25
#define PIN_TX      27
#define PIN_RX      26
#define PWR_PIN     4

#define SD_MISO     2
#define SD_MOSI     15
#define SD_SCLK     14
#define SD_CS       13
#define LED_PIN     12

int counter, lastIndex, numberOfPieces = 24;
String pieces[24], input;

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

  // Set LED OFF
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);

  pinMode(PWR_PIN, OUTPUT);
  digitalWrite(PWR_PIN, HIGH);
  delay(300);
  digitalWrite(PWR_PIN, LOW);

  SPI.begin(SD_SCLK, SD_MISO, SD_MOSI, SD_CS);
  if (!SD.begin(SD_CS)) {
    Serial.println("SDCard MOUNT FAIL");
  } else {
    uint32_t cardSize = SD.cardSize() / (1024 * 1024);
    String str = "SDCard Size: " + String(cardSize) + "MB";
    Serial.println(str);
  }

  Serial.println("\nWait...");

  delay(1000);

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

  // Restart takes quite some time
  // To skip it, call init() instead of restart()
  Serial.println("Initializing modem...");
  if (!modem.restart()) {
    Serial.println("Failed to restart modem, attempting to continue without restarting");
  }
}

void loop(){
  // Restart takes quite some time
  // To skip it, call init() instead of restart()
  Serial.println("Initializing modem...");
  if (!modem.init()) {
    Serial.println("Failed to restart modem, attempting to continue without restarting");
  }

  String name = modem.getModemName();
  delay(500);
  Serial.println("Modem Name: " + name);

  String modemInfo = modem.getModemInfo();
  delay(500);
  Serial.println("Modem Info: " + modemInfo);
  

  // Unlock your SIM card with a PIN if needed
  if ( GSM_PIN && modem.getSimStatus() != 3 ) {
      modem.simUnlock(GSM_PIN);
  }
  modem.sendAT("+CFUN=0 ");
  if (modem.waitResponse(10000L) != 1) {
    DBG(" +CFUN=0  false ");
  }
  delay(200);

  /*
    2 Automatic
    13 GSM only
    38 LTE only
    51 GSM and LTE only
  * * * */
  String res;
  // CHANGE NETWORK MODE, IF NEEDED
  res = modem.setNetworkMode(2);
  if (res != "1") {
    DBG("setNetworkMode  false ");
    return ;
  }
  delay(200);

  /*
    1 CAT-M
    2 NB-Iot
    3 CAT-M and NB-IoT
  * * */
  // CHANGE PREFERRED MODE, IF NEEDED
  res = modem.setPreferredMode(1);
  if (res != "1") {
    DBG("setPreferredMode  false ");
    return ;
  }
  delay(200);

  /*AT+CBANDCFG=<mode>,<band>[,<band>…]
   * <mode> "CAT-M"   "NB-IOT"
   * <band>  The value of <band> must is in the band list of getting from  AT+CBANDCFG=?
   * For example, my SIM card carrier "NB-iot" supports B8.  I will configure +CBANDCFG= "Nb-iot ",8
   */
  /* modem.sendAT("+CBANDCFG=\"NB-IOT\",8 ");*/
  
  /* if (modem.waitResponse(10000L) != 1) {
       DBG(" +CBANDCFG=\"NB-IOT\" ");
   }*/
   delay(200);

  modem.sendAT("+CFUN=1 ");
  if (modem.waitResponse(10000L) != 1) {
    DBG(" +CFUN=1  false ");
  }
  delay(200);

  SerialAT.println("AT+CGDCONT?");
  delay(500);
  if (SerialAT.available()) {
    input = SerialAT.readString();
    for (int i = 0; i < input.length(); i++) {
      if (input.substring(i, i + 1) == "\n") {
        pieces[counter] = input.substring(lastIndex, i);
        lastIndex = i + 1;
        counter++;
       }
        if (i == input.length() - 1) {
          pieces[counter] = input.substring(lastIndex, i);
        }
      }
      // Reset for reuse
      input = "";
      counter = 0;
      lastIndex = 0;

      for ( int y = 0; y < numberOfPieces; y++) {
        for ( int x = 0; x < pieces[y].length(); x++) {
          char c = pieces[y][x];  //gets one byte from buffer
          if (c == ',') {
            if (input.indexOf(": ") >= 0) {
              String data = input.substring((input.indexOf(": ") + 1));
              if ( data.toInt() > 0 && data.toInt() < 25) {
                modem.sendAT("+CGDCONT=" + String(data.toInt()) + ",\"IP\",\"" + String(apn) + "\",\"0.0.0.0\",0,0,0,0");
              }
              input = "";
              break;
            }
          // Reset for reuse
          input = "";
         } else {
          input += c;
         }
      }
    }
  } else {
    Serial.println("Failed to get PDP!");
  }

  Serial.println("\n\n\nWaiting for network...");
  if (!modem.waitForNetwork()) {
    delay(10000);
    return;
  }

  if (modem.isNetworkConnected()) {
    Serial.println("Network connected");
  }
  
  // --------TESTING GPRS--------
  Serial.println("\n---Starting GPRS TEST---\n");
  Serial.println("Connecting to: " + String(apn));
  if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
    delay(10000);
    return;
  }

  Serial.print("GPRS status: ");
  if (modem.isGprsConnected()) {
    Serial.println("connected");
  } else {
    Serial.println("not connected");
  }

  String ccid = modem.getSimCCID();
  Serial.println("CCID: " + ccid);

  String imei = modem.getIMEI();
  Serial.println("IMEI: " + imei);

  String cop = modem.getOperator();
  Serial.println("Operator: " + cop);

  IPAddress local = modem.localIP();
  Serial.println("Local IP: " + String(local));

  int csq = modem.getSignalQuality();
  Serial.println("Signal quality: " + String(csq));

  SerialAT.println("AT+CPSI?");     //Get connection type and band
  delay(500);
  if (SerialAT.available()) {
    String r = SerialAT.readString();
    Serial.println(r);
  }

  Serial.println("\n---End of GPRS TEST---\n");

  modem.gprsDisconnect();
  if (!modem.isGprsConnected()) {
    Serial.println("GPRS disconnected");
  } else {
    Serial.println("GPRS disconnect: Failed.");
  }

  // --------TESTING GPS--------
  
  Serial.println("\n---Starting GPS TEST---\n");
  // Set SIM7000G GPIO4 HIGH ,turn on GPS power
  // CMD:AT+SGPIO=0,4,1,1
  // Only in version 20200415 is there a function to control GPS power
  modem.sendAT("+SGPIO=0,4,1,1");
  if (modem.waitResponse(10000L) != 1) {
    DBG(" SGPIO=0,4,1,1 false ");
  }
  modem.enableGPS();
  float lat,  lon;
  while (1) {
    if (modem.getGPS(&lat, &lon)) {
      Serial.printf("lat:%f lon:%f\n", lat, lon);
      break;
    } else {
      Serial.print("getGPS ");
      Serial.println(millis());
    }
    delay(2000);
  }
  modem.disableGPS();

  // Set SIM7000G GPIO4 LOW ,turn off GPS power
  // CMD:AT+SGPIO=0,4,1,0
  // Only in version 20200415 is there a function to control GPS power
  modem.sendAT("+SGPIO=0,4,1,0");
  if (modem.waitResponse(10000L) != 1) {
    DBG(" SGPIO=0,4,1,0 false ");
  }
  Serial.println("\n---End of GPRS TEST---\n");


  // --------TESTING SENDING SMS--------
  res = modem.sendSMS(SMS_TARGET, String("Hello from ") + imei);
  DBG("SMS:", res ? "OK" : "fail");


  // --------TESTING POWER DONW--------

  // Try to power-off (modem may decide to restart automatically)
  // To turn off modem completely, please use Reset/Enable pins
  modem.sendAT("+CPOWD=1");
  if (modem.waitResponse(10000L) != 1) {
    DBG("+CPOWD=1");
  }
  // The following command does the same as the previous lines
  modem.poweroff();
  Serial.println("Poweroff.");

  // GO TO SLEEP
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  delay(200);
  esp_deep_sleep_start();

  // Do nothing forevermore
  while (true) {
      modem.maintain();
  }
}

View raw code

Insert your SIM card pin on the following line:

#define GSM_PIN ""

Fill your APN details:

const char apn[]  = "net2.vodafone.pt";     //SET TO YOUR APN
const char gprsUser[] = "vodafone";
const char gprsPass[] = "vodafone";

Set a recipient phone number to test sending SMS (it must be in international format including the “+” sign):

// Set phone number, if you want to test SMS
#define SMS_TARGET  "+XXXXXXXXXXXXXXXX"

Set the network mode with the value you got from the previous example.

/*
  2 Automatic
  13 GSM only
  38 LTE only
  51 GSM and LTE only
* * * */
String res;
// CHANGE NETWORK MODE, IF NEEDED
res = modem.setNetworkMode(2);
if (res != "1") {
  DBG("setNetworkMode  false ");
  return ;
}
delay(200);

Change the preferred mode with the value you got from the previous example.

/*
  1 CAT-M
  2 NB-Iot
  3 CAT-M and NB-IoT
* * */
// CHANGE PREFERRED MODE, IF NEEDED
res = modem.setPreferredMode(1);
if (res != "1") {
  DBG("setPreferredMode  false ");
  return ;
}
delay(200);

After that, you can upload the code to your board. Don’t forget to select ESP32 Dev Module in Tools > Board. You also need to remove the microSD card every time you want to upload a new sketch.

After uploading, you can insert the microSD card. Open the Serial Monitor at a baud rate of 115200, and press the on-board RST button to restart it.

The board may take some time to get GPS data for the first time. Your board needs to be placed outside to be able to get a satellite signal. I placed mine next to the window and it was able to accurately get the GPS position.

You should get something similar.

Wait...
Initializing modem...
ATE0
AT+CFUN=0
Failed to restart modem, attempting to continue without restarting
Initializing modem...
AT
AT
AT
OK
ATE0
ATE0
OK
AT+CMEE=0

OK
AT+CLTS=1

OK
AT+CBATCHK=1

OK
AT+CPIN?

+CPIN: READY

OK
AT+GMM

SIMCOM_SIM7000G

OK
Modem Name: SIMCOM SIM7000G
ATI

SIM7000G R1529

OK
Modem Info: SIM7000G R1529
AT+SGPIO=0,4,1,0

OK
AT+CPIN?

+CPIN: READY

OK
AT+CFUN=0 

+CPIN: NOT READY

OK
AT+CNMP=2

OK
AT+CMNB=1

OK
AT+CFUN=1 

OK
AT+CGDCONT=1,"IP","net2.vodafone.pt","0.0.0.0",0,0,0,0
AT+CGDCONT=13,"IP","net2.vodafone.pt","0.0.0.0",0,0,0,0



Waiting for network...
AT+CEREG?

OK
AT+CGREG?

+CGREG: 0,2

OK
AT+CEREG?

+CEREG: 0,0

OK
AT+CGREG?

+CGREG: 0,2

OK
AT+CEREG?

+CEREG: 0,0

OK
AT+CGREG?

+CGREG: 0,2

OK
AT+CEREG?

+CEREG: 0,0

OK
AT+CGREG?

+CGREG: 0,2

OK
AT+CEREG?

+CEREG: 0,0

OK
AT+CGREG?

+CGREG: 0,2

OK
AT+CEREG?

+CEREG: 0,0

OK
AT+CGREG?

+CGREG: 0,2

OK
AT+CEREG?

DST: 1

*PSUTTZ: 22/08/07,13:45:17","+04",1

+CEREG: 0,0

OK
AT+CGREG?

+CGREG: 0,1

OK
AT+CEREG?

+CEREG: 0,0

OK
AT+CGREG?

+CGREG: 0,1

OK
Network connected

---Starting GPRS TEST---

Connecting to: net2.vodafone.pt
AT+CIPSHUT

SHUT OK
AT+CGATT=0

OK
AT+SAPBR=3,1,"Contype","GPRS"

OK
AT+SAPBR=3,1,"APN","net2.vodafone.pt"

OK
AT+SAPBR=3,1,"USER","vodafone"

OK
AT+SAPBR=3,1,"PWD","vodafone"

OK
AT+CGDCONT=1,"IP","net2.vodafone.pt"

OK
AT+CGATT=1

OK
AT+CGACT=1,1

DST: 1

*PSUTTZ: 22/08/07,13:45:19","+04",1

OK
AT+SAPBR=1,1

OK
AT+SAPBR=2,1

+SAPBR: 1,1,"10.196.118.208"

OK
AT+CIPMUX=1

OK
AT+CIPQSEND=1

OK
AT+CIPRXGET=1

OK
AT+CSTT="net2.vodafone.pt","vodafone","vodafone"

OK
AT+CIICR

OK
AT+CIFSR;E0

10.196.118.208

OK
GPRS status: AT+CGATT?

+CGATT: 1

OK
AT+CIFSR;E0

10.196.118.208

OK
connected
AT+CCID

8935101211825295132f

OK
CCID: 8935101211825295132f
AT+GSN

869951031125929

OK
IMEI: 869951031125929
AT+COPS?

+COPS: 0,0,"vodafone P",3

OK
Operator: vodafone P
AT+CIFSR;E0

10.196.118.208

OK
Local IP: 3497444362
AT+CSQ

+CSQ: 22,0

OK
Signal quality: 22

+CPSI: GSM,Online,268-01,0x000e,63308,15 EGSM 900,-73,0,38-38

OK


---End of GPRS TEST---

AT+CIPSHUT

SHUT OK
AT+CGATT=0

+SAPBR 1: DEACT

OK
AT+CGATT?

+CGATT: 0

OK
GPRS disconnected

---Starting GPS TEST---

AT+SGPIO=0,4,1,1

OK
AT+CGNSPWR=1

OK
AT+CGNSINF

+CGNSINF: 0,,,,,,,,,,,,,,,,,,,,

OK
getGPS 26839
AT+CGNSINF

+CGNSINF: 1,0,,,,,,,0,,,,,,12,,,,50,,

OK
getGPS 28844
AT+CGNSINF

+CGNSINF: 1,0,,,,,,,0,,,,,,12,,,,51,,

OK
getGPS 30850
AT+CGNSINF

+CGNSINF: 1,0,,,,,,,0,,,,,,13,,,,51,,

OK
getGPS 32856
AT+CGNSINF

+CGNSINF: 1,0,,,,,,,0,,,,,,12,,,,51,,

OK
getGPS 34862
AT+CGNSINF

+CGNSINF: 1,0,,,,,,,0,,,,,,12,,,,51,,

OK
getGPS 36868
AT+CGNSINF

+CGNSINF: 1,1,20220807134533.000,41.12XXXX,-8.530XXXX,116.200,0.00,0.0,1,,4.2,,,,13,4,,,51,,

OK
lat:41.12XXXX lon:-8.530XXXX
AT+CGNSPWR=0

OK
AT+SGPIO=0,4,1,0

OK

---End of GPRS TEST---

AT+CMGF=1

OK
AT+CSCS="GSM"

OK
AT+CMGS="+351916XXXXXXXX"

>Hello from 86995103XXXXXXXXX 
+CMGS: 228

OK
AT+CPOWD=1

NORMAL POWER DOWN
AT+CPOWD=1
Poweroff.

How the Code Works

Let’s take a quick look at the relevant parts of code.

First, you need to define the module you’re using. The library is compatible with many different modules. To use the SIM7000G, include the following line:

#define TINY_GSM_MODEM_SIM7000

Insert the SIM card pin, APN details, and SMS recipient:

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

// Your GPRS credentials, if any
const char apn[]  = "net2.vodafone.pt";     //SET TO YOUR APN
const char gprsUser[] = "vodafone";
const char gprsPass[] = "vodafone";

// Set phone numbers, if you want to test SMS
#define SMS_TARGET  "+351------------"

Include the TinyGSM and SPI libraries. You also need to include the SD library if you want to use the microSD card.

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

Create a TinyGsmClient instance:

#ifdef DUMP_AT_COMMANDS  // if enabled it requires the streamDebugger lib
  #include <StreamDebugger.h>
  StreamDebugger debugger(SerialAT, Serial);
  TinyGsm modem(debugger);
#else
  TinyGsm modem(SerialAT);
#endif

SIM7000G pinout

The following lines set the module baud rate and pinout:

#define UART_BAUD   115200
#define PIN_DTR     25
#define PIN_TX      27
#define PIN_RX      26
#define PWR_PIN     4

#define SD_MISO     2
#define SD_MOSI     15
#define SD_SCLK     14
#define SD_CS       13
#define LED_PIN     12

Power the modem

In the setup(), you always need to include the following instructions to turn on the modem:

pinMode(PWR_PIN, OUTPUT);
digitalWrite(PWR_PIN, HIGH);
delay(300);
digitalWrite(PWR_PIN, LOW);

Initialize microSD Card

The following lines initialize the microSD card on the pins we defined earlier.

SPI.begin(SD_SCLK, SD_MISO, SD_MOSI, SD_CS);
if (!SD.begin(SD_CS)) {
  Serial.println("SDCard MOUNT FAIL");
} else {
  uint32_t cardSize = SD.cardSize() / (1024 * 1024);
  String str = "SDCard Size: " + String(cardSize) + "MB";
  Serial.println(str);
}

To learn more about using the microSD card with the ESP32, you can read the following guide: ESP32: Guide for MicroSD Card Module using Arduino IDE.

Start Serial Communication

Start a serial communication with the modem:

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

Restart and Initialize the Modem

Call the following lines to restart the modem:

// Restart takes quite some time
// To skip it, call init() instead of restart()
Serial.println("Initializing modem...");
if (!modem.restart()) {
  Serial.println("Failed to restart modem, attempting to continue without restarting");
}

Or the following lines to initialize:

// To skip it, call init() instead of restart()
Serial.println("Initializing modem...");
if (!modem.init()) {
  Serial.println("Failed to restart modem, attempting to continue without restarting");
}

Difference between restart() and init() according to documentation: ” restart() generally takes longer than init() but ensures the module doesn’t have lingering connections”.

Get Modem Name and Info

You can use the getModemName() and getModemInfo() to get information about the modem.

String name = modem.getModemName();
delay(500);
Serial.println("Modem Name: " + name);

String modemInfo = modem.getModemInfo();
delay(500);
Serial.println("Modem Info: " + modemInfo);

Connect GPRS

To connect GPRS using the APN details:

if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
  delay(10000);
  return;
}

To check if it is connected, you can use the isGprsConnected() method:

if (modem.isGprsConnected()) {
  Serial.println("connected");
} else {
  Serial.println("not connected");
}

Start GPS and Get Location

As mentioned previously, there are two versions of the LILYGO SIM7000G ESP32 board. The latest comes with active GPS antenna power control—when the module GPIO 4 is not turned on the antenna consumes only the static current of the LDO. This means we need to turn GPIO 4 on before getting GPS data to power the antenna. That’s what the next lines do:

// Set SIM7000G GPIO4 HIGH ,turn on GPS power
// CMD:AT+SGPIO=0,4,1,1
// Only in version 20200415 is there a function to control GPS power
modem.sendAT("+SGPIO=0,4,1,1");
if (modem.waitResponse(10000L) != 1) {
  DBG(" SGPIO=0,4,1,1 false ");
}

If you have the oldest version, you don’t need those lines of code.

You can start GPS using the enableGPS() method.

modem.enableGPS();

Get latitude and longitude using the getGPS() method.

float lat,  lon;
while (1) {
  if (modem.getGPS(&lat, &lon)) {
    Serial.printf("lat:%f lon:%f\n", lat, lon);
    break;
  } else {
    Serial.print("getGPS ");
    Serial.println(millis());
  }
  delay(2000);
}

When you’re done using GPS, you can turn it off using the disableGPS() method:

modem.disableGPS();

And finally, turn off the power to the antenna by turning GPIO 4 off:

// Set SIM7000G GPIO4 LOW ,turn off GPS power
// CMD:AT+SGPIO=0,4,1,0
// Only in version 20200415 is there a function to control GPS power
modem.sendAT("+SGPIO=0,4,1,0");
if (modem.waitResponse(10000L) != 1) {
  DBG(" SGPIO=0,4,1,0 false ");
}

Sending SMS

To send an SMS, you can simply use the sendSMS() method and pass as arguments the recipient number and the message.

res = modem.sendSMS(SMS_TARGET, String("Hello from ") + imei);
DBG("SMS:", res ? "OK" : "fail");

Powering Down the Module

The LILYGO is supposed to work on a 18650 battery and solar panel, so we must cut power whenever it’s not needed. So, it’s useful to have a function to turn off the modem completely. You can use the poweroff() method or send the +CPOWD=1 AT command.

modem.sendAT("+CPOWD=1");
if (modem.waitResponse(10000L) != 1) {
  DBG("+CPOWD=1");
}
// The following command does the same as the previous lines
modem.poweroff();
Serial.println("Poweroff.");

And that’s it for the most relevant parts of code.

Wrapping Up

In this tutorial, you learned how to use the LILYGO T-SIM7000G ESP32 board. This tutorial can also be applied if you’re using a “regular” ESP32 connected to an external SIM7000G module. This module supports GPS, GPRS, LTE CAT-M1, and NB-IoT protocols, which can be very useful for IoT and Home Automation projects.

You learned how to connect GPRS, how to send SMS messages and how to get GPS data. The idea is to include the snippets of code you need in your own projects.

The LILYGO T-SIM7000G ESP32 board also comes with a microSD card slot that can be useful for datalogging projects or to save configuration settings. Furthermore, it comes with a battery holder and a battery charging circuit to use with solar panels. So, it’s suitable to use in remote locations. However, I haven’t experimented with the battery circuit yet.

For more examples, you can explore the TinyGSM library repository or the official LILYGO T-SIM7000G Github page.

Do you have one of these boards? What do you think? Let us know in the comments below.

You may also like the following tutorials (that with minor changes can be used with the SIM7000G board):

Learn more about the ESP32 with our resources:

Thanks for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Enjoyed this project? Stay updated by subscribing our newsletter!

132 thoughts on “Getting Started with LILYGO T-SIM7000G ESP32 (LTE, GPRS, and GPS)”

  1. Rui and Sara,
    There are many Random Nerd fans in the U.S.
    Could you please help identify a low cost sim-card/data-plan for the U.S, ?
    Thanks,
    Curt

    Reply
    • If you Google IoT sim plan, something like 1nce oder ThingsMobile would come up.
      I’ve used both for projects in the past and you can start with 15 bucks one time payment.

      good luck with your projects

      Reply
    • I am using Hologram. Works well, and is inexpensive, been using it with an IOT project for a while using. SIM7000A. I bought one of these card with the SIM7000G and it is working well thus far.

      Reply
    • I just got a Mint sim card installed and running using the above tutorial. Its $15/month, need to tell them its a physical card and that you will need a new phone number. The APN is “Mint”, gprsUser and gprsPassword blank, modem.setNetworkMode(2), modem.setPreferredMode(3);
      Thanks Santos !

      Reply
      • You can monitor usage and recharge the data plan if needed.
        However for IoT devices that use very little data month to month it is not practical to pay a monthly or annual fee to keep it operational. This has been a challenge for me with projects in the past, and I really hope 1nce can remain solvent at that price point.

        Reply
  2. Excellent article Rui, Sara.
    Thanks to permanently keep us updated of new devices from the practical point of view. Not just the devices themselves, but the configuration and Sw related tips and issues. I’m a fan of your site since a couple of years when I bought your book about ESP8266. Excellent by the way, same of all your publications

    Reply
  3. Hi Rui and Sara,

    Thank for great tuto I bought feew books from you and they are great.

    Did you or can you make tuto on geofencing.

    Best regards

    Reply
  4. Hi Sara and Rui… greetings from Brazil.

    I noted, in the first sketch, the function modemPowerOn() is almos identical to modemPowerOff(). The only difference is the time out (delay command). Is that correct?

    Thank you for all these great tutorials.

    Reply
    • Hi.
      I think it is.
      Most modems are turned on or off by pressing the same button in a different way (with different delay times).
      Regards,
      Sara

      Reply
    • Hi.
      All ESP32 boards can be programmed using MicroPython.
      You’ll need to search for a specific micropython-compatible library to use the SIM7000G features.
      Regards,
      Sara

      Reply
  5. Hi,
    Imperesive article,
    you didn’t test it with battery !,
    Please let me know the current consumption for using this/ver 1.1 board for 4G network.
    And what battery will give long lasting time with same operation and how much longer.
    Regards
    Tapan

    Reply
  6. Perfect timing, my friends! Thank you!

    I’m about to use this beauty in combination with a SPI TFT Display (1,77 inch ST7735 / 128×160 Pixels).
    Probably it needs to be connected to VSPI-port and driven by the “TFT_eSPI” by Bodmer. This library needs some manual edits but it’s unclear to me what and how exactly.
    Your experienced thoughts/investigations would be very helpfull!

    Reply
    • Hi Mark,
      I’ve been used an ILI9341 TFT display (2.8″) with ESP32 and Bodmer’s TFT_eSPI. Indeed, you must change some lines in userSetup.h library. You must uncomment line #46, which points to ILI7735. Then you must change the SPI and controls pins you will use to conect the display (below line #199). Finally, you can change the fonts you want to use in section 3 (below line #293). Then is just compile and run! It works fine.

      Reply
  7. Hello.

    Thanks a lot for all your valued articles.

    About the he LILYGO T-SIM7000G ESP32 I have some doubts. I my Country we have service provider of LTE in B3(1800), B7(2600). We also have 2G provider in B3(1800). Actually I use LilyGo T-sim800l it’s work very well with GSM and GRPS. However Sim800l have some limitations. I want to purchse an LilyGo with LTE, it could be the T-SIM7000G.

    If T-SIM7000G do not property work with my local LTE service provider, It may still work fine on G2 (gsm and grps) local providers? The same service I currently use with Sim800L?
    Can I use the same micro sim 2G I already in LiliGo t-call v.1?

    Best regards.

    Reply
  8. In the US, I am having good luck with a SIM card from Hologram. Also users should make sure that their Arduino ESP32 boards are up to date! I installed the latest, things seem to be working well.
    A great tutorial for sure!

    Reply
  9. Another great tutorial from the guru!
    Please, I am using the new version of the lilygo sim7000g. The first Arduino sketch worked as intended but the second sketch simply refused to OK “AT+CPIN”, I have tried all I could, including changing SIMs as well as using all types of APN settings I could lay my hands on, but the result is the same!
    Please, is there anything I could change?

    Reply
    • Hi.
      In the first example you should get your SIM preferred mode selections like in this: https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2022/08/SIM7000-network-test-ESP32-Serial-Monitor.png
      Did you change on the second code the preferred mode selections?
      /*
      2 Automatic
      13 GSM only
      38 LTE only
      51 GSM and LTE only
      * * * */
      String res;
      // CHANGE NETWORK MODE, IF NEEDED
      res = modem.setNetworkMode(2);
      if (res != “1”) {
      DBG(“setNetworkMode false “);
      return ;
      }
      delay(200);

      /*
      1 CAT-M
      2 NB-Iot
      3 CAT-M and NB-IoT
      * * */
      // CHANGE PREFERRED MODE, IF NEEDED
      res = modem.setPreferredMode(1);
      if (res != “1”) {
      DBG(“setPreferredMode false “);
      return ;
      }

      Regards,
      Sara

      Reply
      • Thanks, for your response, I really appreciate it.
        On running the first sketch, I got:
        ======Preferred mode selection=======
        +CNMP: 2
        ====Preferred selection between CAT-M and NB-IoT=====

        +CMNB: 3

        Therefore, I set:

        /*
        2 Automatic
        13 GSM only
        38 LTE only
        51 GSM and LTE only
        * * * */
        String res;
        // CHANGE NETWORK MODE, IF NEEDED
        res = modem.setNetworkMode(2);
        if (res != “1”) {
        DBG(“setNetworkMode false “);
        return ;
        }
        delay(200);

        /*
        1 CAT-M
        2 NB-Iot
        3 CAT-M and NB-IoT
        * * */
        // CHANGE PREFERRED MODE, IF NEEDED
        res = modem.setPreferredMode(3);
        if (res != “1”) {
        DBG(“setPreferredMode false “);
        return ;

        }

        I do not know if I did my settings correctly!

        Reply
          • I noticed that the blue LEd stopped flashing and go-out after a connection on the first sketch and also on the second sketch, even though the second sketch seems to have problem! Therefore, I am assuming that the board connected to the network.
            My aim of using this board is to construct a standalone remote weather station with the data available to download from anywhere. Perhaps Bob could help in this case.
            Thanks, once again

  10. Hi,
    nice to see that RandomNerd is dealing with this board. I´m interesting in an example of receiving data from an URL (e.g. weather forecast wttr.in)

    Best regards
    Chris

    Reply
  11. Hi Sara, – you asked if anyone has used one of these.
    I wanted a self powered device located away from Wifi access to send temperature readings.
    I bought version 1.1 together with battery and solar panel. Although in total a bit costly it has worked without any problems for a couple of months sending reading using HTTP GET to a mysql database.
    I’m in the UK using a ‘pay as you go’ sim card. No set up costs and £0.10 per mbyte data charge. Each transmission uses about 2k of data so lets me send 500 readings for just £0.10. I am sending every 5 minutes so my weekly costs are less than £0.50.
    Solar panels must not exceed 6 volts so using any phone charging solar panel is ideal. Their outputs appear to be limited to 5 volts. The one I use cost me about £10 and is low power so am using ESP32 deep sleep mode and battery power stays mostly above 4 volts. In two months it hasn’t failed.
    The TinyGSM examples are very comprehensive but I found confusing. There are many functions and tests that I dont think I need but haven’t removed them in case I miss something vital. So my first task was to check if you had a tutorial – but couldn’t find one at that time. I will now revisit my IDE based on your article and tidy up the coding. Many thanks for this tutorial. As usual, really well explained.
    I did find some issues looking for spare GPIO pins for connecting sensors so it would help to know if those used for the sd card can be used freely, and are there any restrictions like ADC2.
    Again – many thanks

    Reply
    • Hi Bob.
      Thank you so much for sharing your experience with this board.
      I’m happy that it runs smoothly with your project.
      I didn’t investigate the GPIOs in detail. Maybe a closer look at the schematic diagram of the board might help.
      I would prefer to use other GPIOs first.
      Thanks once again.
      Regards,
      Sara

      Reply
    • Hi Bob,
      I am happy that you got this board working, I have been trying to get it working, but currently running into some problems that are mainly related to the pin configuration of the board!

      Please, can you throw more light on how to equate this SIM7000 pin configuration:

      #define UART_BAUD 115200
      #define PIN_DTR 25
      #define PIN_TX 27
      #define PIN_RX 26
      #define PWR_PIN 4

      #define SD_MISO 2
      #define SD_MOSI 15
      #define SD_SCLK 14
      #define SD_CS 13

      #define LED_PIN 12

      with the SIM800 pin configuration

      #define MODEM_RST 5
      #define MODEM_PWKEY 4
      #define MODEM_POWER_ON 23
      #define MODEM_TX 27
      #define MODEM_RX 26
      #define I2C_SDA 21
      #define I2C_SCL 22
      // BME280 pins
      #define I2C_SDA_2 18

      #define I2C_SCL_2 19

      or better still, if you could share your working code with us here.

      Thanks

      Reply
      • Hi Oladiran
        I am collecting temperature from a DS18B20 and more info from an SHT31 i2C sensor. This data is then sent using HTTP to mysql table. Also showing readings on epaper display.
        Not using SD card or GPS. Therefore the only pins I am using are as follows
        #define UART_BAUD 115200
        #define PIN_TX 27
        #define PIN_RX 26
        #define PWR_PIN 4

        GPIO21 SDA (default)
        GPIO22 SCL (default)
        GPIO12 used for DS18B20 data input – not LED
        GPIO pins 5, 18, 19, 23, 32, 33 for epaper display

        You appear to have included pin definitions for SIM800 some of which have already been declared.
        In addition you have set up a second i2c for your BME280. Why not use the default pins 21 & 22.
        What are you trying to achieve?
        Regards,
        Bob

        Reply
    • Hi Bob:
      I’m also in the UK.
      Can you give information on suitable SIM cards?
      Which “pay as you go” SIM are you using?
      I’m in a rural area with good Three (APN: three.co.uk) 4G coverage on my iPhone.
      Thx, Robin

      Reply
  12. Hi Sara,
    Thanks for another great tutorial. I have learned alot from you. I have been using this device for about 6 months now as a remote monitor for temp/humidity, motion, flood, light, and door/window. I use the Hologram SIM card (in the US). I have played with battery operation with an 18650 Li-ion battery, but currently us it plugged into the wall. The software coding is available on Github at https://github.com/Bobbo117/Cellular-IoT-Monitor . The documentation isn’t the best, but I’ll work on that in the next couple of months.

    Reply
  13. Hi everyone,
    Very nice article but I doubt that the SIM7000G will work with LTE, because the necessary chip needs to be the SIM7600G which is going to be more expensive.
    At least thats what the manufacturer says oin the aliexpress website refered here in the links.
    Am I right?

    Regards Dom

    Reply
  14. hi,

    great tutorial. Do you know if it is possible to get status of the battery (to send low battery warning for example) and status of solar charging?

    thanks, Gos

    Reply
  15. I made the mistake of installing TinyGSM before I encountered the recommendation to install the latest Arduino IDE before proceeding. I uninstalled version 1.8 and installed 2.0.0. Now when I search the libraries and find TinyGSM it doesn’t say “Installed”, but also doesn’t have an “Install” button. When I try to compile, it says “Compilation error: TinyGsmClient.h: No such file or directory”.

    When I search I can find that file. I uninstalled IDE 2.0 and deleted TinyGsmClient.h and reinstalled, but have the same issue–upon compiling it says “no such file”, and after finding it in the Library Manager it doesn’t have an “install” button. Clicking on it, double-clicking on it, and right-clicking on it all reveal nothing about being able to install it.

    I’ve uninstalled IDE 2.0 and reinstalled twice. Any ideas about what I need to do, other than use a different PC?

    Reply
      • You didn’t mention IDE 2.0, but did say to use “Installing the ESP32 Board in Arduino IDE” to enable ESP32, and that said to delete your old IDE and install newest using a link which included IDE 2.0.

        I’ll try again with 1.8.

        Reply
        • Ok. You’re right, we created that tutorial before arduino 2.0 existed.
          Arudino 2.0 is known to have some issues. So, I recommend Arduino IDE 1.8.
          Regards,
          Sara

          Reply
          • I successfully installed 1.8 and compiled and loaded program #1. It ran through a lot of stuff (on the serial monitor), including showing my SMS message–but the message did not appear on my phone (I’m not certain that my t-mobile SIM info is set up right).
            When I tried to run program #2, after compiling and linking, it said “A fatal error occurred: Failed to connect to ESP32: Wrong boot mode detected (0xb)! The chip needs to be in download mode.”
            How do I put it in download mode?

          • Hi.
            It should be automatically in download mode…
            Do you have any peripherals connected to the board?
            Does your board have a RST or BOOT button? Try to press them while trying to upload the code.
            Regards,
            Sara

  16. Hello again,

    while working with your code I added the GPS Data to the SMS. But for some reasons it cut´s off after 2 digits. I tried several commands for passing more digits without success.
    The following code only submits two digits after the point.

    String(“https://maps.google.com/maps/place/”) +(lat) +”, ” +(lon));

    Any ideas what to add?

    Regards Dom

    Reply
      • Hello Bob,

        Thanks for your help. This is just a typo error. I managed to get the right code by using two variables and converting these as string. But now the SMS is always openend by the Google maps app which can’t read the coordinates. If you open the link in any browser it’s working. Any suggestions on this issue? Greetings Dom

        Reply
  17. Anybody had any luck getting the Lilygo to work on their Mac?
    A fatal error occurred: Failed to write to target RAM (result was 01070000)
    🙁

    Reply
    • Me too !. No joy getting samplecode but the Adafuit_FONA outlines an approach – request events from the modem using AT commands and parse the response. Might be a nice addition to the TInyGSM library ?

      Reply
      • Some progress, can get individual messages using the below (insert just before the send message test) – hant been able to get the list :

        for (int i=0; i<19; i++){
        Serial.println(“+CMGR=”+String(i));
        modem.sendAT(“+CMGR=”+String(i)); // +CMGL=\”ALL\”
        delay(100);
        Serial.println(SerialAT.readString());
        }

        Reply
          • Yes it retrieves specific numbered messages.
            Im hoping to get the list of available messages, see the cmgl command in the comment, but for some reason I only see the first 256 chars of its response. May be my coding or a sim7000 buffer configuration issue?

          • Still not an expert but I have enough to do what I want (find out how many messages havnt been read). Looks like the SIM7000g only has 1 type of message area. When sending this :
            AT+CPMS=”SM”,”SM”,”SM”
            It returns : +CPMS: 25,30,25,30,25,30 telling us it currently has 25 messages of a max of 30 it can hold. Reading (CMGR) and then deleting (CMGD) these one at a time can reset it to 0,30.

  18. Hello, Sara.
    Great tutorial, thanks!
    Do you have any suggestions how send MMS with AT-commands?
    I have read vendors’s manual, but I still can’t find anything about MMS

    Reply
  19. Hi

    Amazing tutorial 😉 i tried, but i have one problem… if i dont have GPRS, i want to store the coordinates, but i found that the board cannot lock GPS when at some time connected to GPRS.. i tried not using GPRS, and i can lock GPS, but if i connect GPRS, and then lost conection, the GPS always return false.

    Anyone can help?

    Reply
      • Hi ,

        Thanks for the fast reply, yes i followed the examples from here, lilygo github and TinyGsm library, actually my code its using some modifications to TinyGsm to avoid some locks in the code connecting GPRS.

        My problem is that im sending from time to time coordinates to a server, but when loosing GPRS, im trying to store the cordinates and send after in a json block.

        In the spot i dont have GPRS, i have GPS, but in the code, since im activated the GPRS, i cant get GPS, you can try it for example using the code above, without sim card.

        Reply
  20. Hello all.
    I am looking for a Receiving code for my ESP project.
    Can someone help me please?

    unfortunately, TinyGSM library have only sending code in his library.

    Thanx,
    Elad

    Reply
  21. Hello,

    Thank you for a great tutorial. I got it working using a hologram sim card (US).
    I was able to install the sketch with only minor difficulties. After successfully running the sketch several times. I noticed the blue led was not working correctly. I checked the schematic and
    Didn’t see anything unusual. The blue led lights when you take pin 12 low, and goes
    Out when you take pin 12 high. Has anyone else experienced this? Is their a solution?
    Thank you
    Larry

    Reply
  22. After looking at the schematic again, it looks like it is reversed from the usual way the blue led performs
    on esp32 boards. I adjusted my sketch for this and noted it about the reversal.

    Reply
  23. Slt Sara, vraiment grand merci pour ce tutoriel, ça m’a beaucoup édifiés. Mais ce pendant j’ai quelques préoccupations.
    Je suis au Cameroun, je voudrais Concevoir un appareil qui lis les données capteur (température et pression) Et renvoie à l’utilisateur sur une très grande distance(plus de 1500km). L’utilisateur recevra les données grâce à une plateforme web ,
    1- est-il possible de le réaliser mon projet avec cette carte ?
    2-Dans mon pays nous avons 3 réseau, Orange, MTN et Camtel , c’est carte sera t-il compatible avec la puce pour la transmission des données ?
    3- svp ceux qui ont déjà utilisé Hologramme, cette sim peut -il fonctionne dans tout les pays du monde a l’instar de mon pays le Cameroun ?
    En résumé j’ai réalisé un projet d’IOT avec l’esp32 en utilisant le wifi pour une distance que peut couvrir le wifi , ça fonctionne bien, mtnan j’ai envie de réaliser le même projet pour une très grande distance (1500km) j’aimerais savoir si cette carte peut le faire, svp s’il quelqu’un d’autre a une solution à me proposer je serai très ravi.

    Cordialement,

    Reply
  24. Can I connect the solar panel and USB simultaneously?
    Does the onbaord MOSFET switching circuit ensure that if both solar panel an USB is connected, the power flow will not go to the other to damage it?

    Example: If I connect USB and Solar panel, the 6V from solar panel will not flow to the USB to damage my PC If I connect the USB to program the board . Or reverse current and voltage from my USB will not go to the solar panel and damage the panel?

    Reply
  25. Bonjour Sara
    Je suis un fervent utilisateur de vos conseils et vous en remercie beaucoup.

    J’ai fabriqué un système de tracking à partir d’un module SIM800L_GPS auquel j’ai ajouté un module batterie 18650 séparé . Ce système embarqué dans mon sac lors de mes sorties permet de transmettre le trajet en utilisant une connexion à un raspberry sur lequel tourne MQTT avec les topics Track et Map ) qui affichent la carte OpenStreetMap et le trajet sur un écran de télévision.
    Cela rassure ma femme (j’ai 82 ans) !!!

    J’ai acheté un module LilyGO_SIM 7000G avec batterie intégrée. Le module fonctionne très bien connecté en USB ou à une batterie externe. Le GPS fonctionne, la transmission des SMS aussi.
    Cependant je ne parviens pas à le faire fonctionner à partir de la batterie intégrée (interrupteur sur “ON”). Rien ne s’allume et le module ne transmet rien sauf en maintenant le bouton “PWR” appuyé ( auquel cas ça fonctionne normalement). Ai-je oublié quelque chose dans la programmation ? Est-ce que le module est en panne ? J’ai passé du temps à chercher sur internet sans rien trouver sur le rôle de ce bouton “PWR”. Peut être avez vous entendu parler de ce problème ? Le schéma électrique (github) montre que ce bouton permet de relier VBAT- à la masse. N’y a -t-il pas un autre moyen ?
    Je vous prie d’excuser de vous avoir écrit en français mais je vois en lisant les message que cette langue vous est connue. Vous pouvez me répondre en anglais.
    Merci encore.

    Reply
    • Hi.
      I’m not sure what might be the problem.
      There were some faulty versions of this board. Including some issues with the battery connections in the oldest versions.
      Make sure you’re using one of the latest versions.
      I haven’t tried this board with a battery, so I’m can’t give much advice here.

      I’m sorry that I can’t help much.
      Regards,
      Sara

      Reply
  26. I used a cheap Chinese module pictured here:
    mulvey.us/images/SIM7000project.jpg
    It had a couple of differences in the way the pins were labeled. I suspect the actual power and ground pins are hard wired on the LILYGO board. Mine has a pin labeled POWER which must be connected to a 5V souce, not the 5V pin on the ESP32 module. A pin labeled PWR_EN acts something like your power pin but the polarity is reversed. I ended up leaving it disconnected. Another pin labeled V_MCU needs to be connected to the 3.3V pin on the ESP32. This tells the SIM7000A module that leveling is required on the communication interface and it does so automatically. I am glad to see that the vendor has recently posted information about these pins. After all the trials with this board I ordered a LILYGO unit.

    As usual, RNT was very helpful. Thank you.

    Reply
  27. Thanks for a great tutorial, super helpful in getting up and running with GSM and ESP32. I did have one question, in your first example code, the one adapted from the Lilygo example, it is implied that we can enter our own AT commands during the final while loop of the code. However, whenever I send an AT command through the Serial Monitor terminal, I get no response from the module. I modified the code and had the serial monitor basically repeat whatever I entered into the terminal, so it appears that the while loop is working, I just can’t seem to get it to work with AT commands going to SerialAT. Maybe there is a special format or conversion that needs to be done? Any advice? Thanks!

    Reply
  28. Bonjour, Quel super travail, comme en France la 2 G va s’arrêter fin 2024 ou 2025 quitte à acheter 1 module je souhaiterais utiliser la version 7000E en 4 G quelles modification y a -t’il à faire dans votre superbe programme je crois comprendre que le GPRS ne concerne que la 2G ,
    cordialement.
    Hello, What great work, as in France the 2 G will stop at the end of 2024 or 2025 even if it means buying 1 module I would like to use the 7000E version in 4 G what modifications are there to be made in your superb program I believe understand that GPRS only concerns 2G,
    Sincerely.

    Reply
  29. Hello, I have a small problem when I send the SMS I only receive the value of lat, the value of lon is not included. res = modem.sendSMS(SMS_TARGET, String(“Hello from “) + lat + lon ); Does somebody has any idea?

    Reply
    • Hello I am getting the below error when I try running the first sketch
      “Compilation error: ‘GSM_NL’ was not declared in this scope”

      Reply
      • In TinyGSM version 0.11.1, it was defined in numerous header files thusly:

        #define GSM_NL “\r\n”

        It isn’t there in version 0.12.0.

        Reply
      • In TinyGSM version 0.11.1, it was defined in numerous header files thusly:

        #define GSM_NL “\r\n”

        It isn’t there in version 0.12.0.

        I got the code to compile by adding #define GSM_NL “\r\n” in between
        #define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb
        and
        #define SerialAT Serial1,

        not that this specific placement is important.

        Reply
      • In version 0.11.1 of the TinyGSM library, many header files included the following line:
        #define GSM_NL "\r\n"

        In version 0.12.0 of the TinyGSM library, this macro does not appear.

        I got Rui’s code to compile by including the macro near the top of the sketch.

        Reply
      • GSM_NL was defined in the TinyGSM library header files in version 0.11.1 of TinyGSM, but the definition was taken out in version 0.12.0.

        If you have the same problem as Samuel, just add the line
        #define GSM_NL "\r\n" near the top of your sketch.

        Reply
        • The reason for the multiple replies is that my replies initially showed awaiting moderation, then disappeared.

          One additional piece of info: in the TinyGSM library, #define GSM_NL... may have been replaced with #define AT_NL... somewhere between version 0.11.1 and version 0.12.0.

          Reply
  30. Hello

    We are problems with some os this board. Not possible to connect with 4G, only 2G.
    Do you similar problem?

    Att
    Jean Brancher

    Reply
  31. Thanks a lot for this great tutorial!
    Could you confirm that, if I want to put a specific GPIO (in my example GPIO 27) to 1, the AT command would be:
    AT+SGPIO=1,27
    From my mobile’s point of view, is this the exact sentence that I must type as a SMS ?

    Reply
      • Good morning
        to do 1 test in France we bought the 7000E module and it does not work because the frequencies are not good
        Bonjour
        pour faire 1 essai en France nous vons acheté le module 7000E et ça ne fonctionne pas, car les fréquences disponnibles ne sont pas bonnes
        Salutations

        Reply
  32. Hi, I bumped on your tutorials after searching to get this SIM7000G module working.
    This is my first plunge into programming an ESP device, so I’m very new at it.
    I managed to run the example above and could send a SMS.
    Then I also was able to remove the loop so it only sends 1 message.

    Now I’m a little stuck: I’m searching left and right on how to send a SMS when a GPIO is shorted, like when a switch closes, so no current will flow.
    Can you please give me some hints on how to achieve this?
    Thanks!

    Reply
    • Hello Peter, I found this tutorial recently as well. I have a fair amount of experience using there devices to both read and activate sensors and switches, and the info here is what I need to get the communication part going.

      You would need to set your input GPI as an input with a built in pullup resistor, unless you are using circuitry that has that:
      inside setup loop:
      pinMode(pinNumber, INPUT_PULLUP);

      Then in your main loop whenever you want to sense the input you’d use:
      rackDepCurr = digitalRead(pinNumber);

      If the pin is open, the input pullup will give you a logic value of 1. If you take a wire and connect it to ground, then you’ll get a logic value of 0.

      Here’s an example:
      rackDepPrev = rackDepCurr;
      rackDepCurr = digitalRead(RACK_DEPLOYED);
      if (rackDepCurr == 0) {
      deployed – do something
      } else {
      not deployed – do something else
      }

      Ultimately this will depend on what kind of switch you use.

      Best,
      Jeff

      Reply
  33. Hi,
    thank you very much for your work, it is very remarkable.
    I would like to know whether by using the
    LILYGO T-SIM7000G
    or
    LILYGO T-SIM7600G
    it might be possibile to initialize both the Wifi and the GSM modem.
    For example from
    lilygo.cc/products/t-sim7600
    I think the Sim7600 is connected via SPI TX/RX 26 and 27 pins,
    so it might be possible to connect the wifi on SPI TX/RX 19 and 23 pins.
    Then, I am curious to know whether it might be possible to add also an ethernet port.
    What do you think?

    Reply
  34. Thank you for this amazing article!

    My board doesn’t boot when it’s battery powered, but works perfectly when connected via USB. Doesn’t boot means it never reach setup() and blue led is always on (dimmed). Reset does nothing.

    Any idea what could it be?

    Reply
    • Hi.
      Maybe you’re not providing enough power through the battery? Or you’re not connecting it properly?

      Regards,
      Sara

      Reply
      • Thank you Sara so much for your quick answer! I tried several 18650 fully charged batteries, but it doesn’t make any difference. Moreover when I power LILYGO T-SIM7000G – I have one red led constantly ON and another one is blinking. And one more observation – sometimes it actually boots after toggling power on/off switch, but it happens occasionally. I wonder if it could be a hardware issue, like faulty capacitor or something?

        Reply
      • Update: Just tried another board with the same firmware, the same battery, the same sim card and the same SD card – works just perfect. Will try to check if one or several power related components are faulty.

        Reply
  35. I had used this board before and stored it. Today Nov 2024, i could not get it to upload
    Two issues im sharing for anyone else.

    #define GSM_NL “\r\n” near the top of your sketch. or it wont complile

    If on Mac OS install latest wch-ic.com/downloads/CH34XSER_MAC_ZIP.html
    Make sure you clear security con SystemPrefs, reboot, and TWO similar serial ports will show when you connect the board, mine worked using the one with a W .

    Hopefully RNT can update the post

    Reply
  36. Great article! I’m currently exploring OTA updates for ESP32-WROOM-32e and was wondering—would it be possible to perform an OTA update using the Tsim7000G module, specifically without relying on Wi-Fi?

    I’d love to hear if anyone has tried this approach or has insights into using cellular modules like Tsim7000G for OTA updates with ESP32-WROOM-32e. Thanks!

    Reply

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.