Sim7000G not sending Data please help :(

Hello Everyone,

I have a sim7000G lilygo module by espresiff that has nothing connected. It only has power and a simcard used by hologram. It receives data via espnow from a esp32 nearby and is supposed to send to the server. About 2 months ago everything was perfect, except now I cannot post the data on the server. Server has been tested to make sure it’s running using CURL commands, etc. I am 100% sure the server is good. I checked security groups, ports (all traffic) etc. I was able to send data from my terminal to the server database so no problems there. I just keep getting an error below:

00:10:00.588 -> Setting network to automatic LTE/NB-IoT/GSM...
00:10:01.595 -> Waiting for network... ✅ Network connected
00:10:12.971 -> Connecting to APN: hologram
00:10:15.430 -> ✅ GPRS connected
00:10:15.430 -> Modem IP: 10.247.105.179
00:10:15.430 -> Network type: 2
00:10:15.467 -> Operator: T-Mobile Hologram
00:10:15.467 -> Signal quality: 20
00:10:15.539 -> ✅ ESP-NOW ready
00:11:40.728 -> 📡 ESP-NOW packet received and queued
00:11:40.728 -> Posting JSON: {"id":1,"x_avg":0.00,"y_avg":0.00,"z_avg":0.00,"temp_f":72.95,"time_str":"01:10:39"}
00:11:41.697 -> Signal quality: 99
00:11:41.697 -> Connecting to server 3.138.117.223:80
00:11:56.221 -> 📡 ESP-NOW packet received and queued
00:12:59.695 -> ❌ TCP connection failed, retrying...
00:13:02.726 -> Connecting to server 3.138.117.223:80
00:14:20.699 -> ❌ TCP connection failed, retrying...
00:14:23.713 -> Connecting to server 3.138.117.223:80
00:15:41.716 -> ❌ TCP connection failed, retrying...
00:15:44.734 -> ❌ Could not connect after 3 attempts → will try again next loop
00:15:49.737 -> Posting JSON: {"id":1,"x_avg":0.00,"y_avg":0.00,"z_avg":0.00,"temp_f":72.95,"time_str":"01:10:39"}
00:15:50.705 -> Signal quality: 99
00:15:50.705 -> Connecting to server 3.138.117.223:80

Here is the code:

#define TINY_GSM_MODEM_SIM7000
#include <TinyGsmClient.h>
#include <HardwareSerial.h>
#include <esp_now.h>
#include <WiFi.h>

// ------------------------
// SERIAL SETTINGS
// ------------------------
#define SerialMon Serial
#define SerialAT Serial1
#define UART_BAUD 115200
#define PWR_PIN 4
#define PIN_TX 27
#define PIN_RX 26

// ------------------------
// GSM SETTINGS
// ------------------------
const char apn[] = "hologram";
const char serverIP[] = "3.138.117.223";  // Your EC2 public IP
const uint16_t serverPort = 80;
const char serverResource[] = "/upload.php";  // Your PHP endpoint

// ------------------------
// GSM OBJECTS
// ------------------------
TinyGsm modem(SerialAT);
TinyGsmClient client(modem);

// ------------------------
// DATA STRUCT
// ------------------------
typedef struct {
  int id;
  float x_avg;
  float y_avg;
  float z_avg;
  float temp_f;
  char time_str[9]; // "HH:MM:SS"
} SensorData;

// Queue for storing received packets (max 10 packets in memory)
#define MAX_QUEUE 10
SensorData packetQueue[MAX_QUEUE];
volatile int queueHead = 0;
volatile int queueTail = 0;

// ------------------------
// ESP-NOW CALLBACK
// ------------------------
void OnDataRecv(const esp_now_recv_info_t *info, const uint8_t *incomingData, int len) {
  if (len == sizeof(SensorData)) {
    int nextTail = (queueTail + 1) % MAX_QUEUE;
    if (nextTail != queueHead) {  // Queue not full
      memcpy(&packetQueue[queueTail], incomingData, sizeof(SensorData));
      queueTail = nextTail;
      SerialMon.println("📡 ESP-NOW packet received and queued");
    } else {
      SerialMon.println("⚠️ Queue full, packet dropped");
    }
  }
}

// ------------------------
// SETUP
// ------------------------
void setup() {
  SerialMon.begin(115200);
  delay(100);

  // ------------------------
  // Init GSM
  // ------------------------
  pinMode(PWR_PIN, OUTPUT);
  digitalWrite(PWR_PIN, HIGH);
  delay(300);
  digitalWrite(PWR_PIN, LOW);

  SerialAT.begin(UART_BAUD, SERIAL_8N1, PIN_RX, PIN_TX);
  SerialMon.println("----- Initializing GSM -----");
  if (!modem.init()) {
    SerialMon.println("❌ Modem init failed!");
    while (true);
  }
  SerialMon.println("✅ Modem initialized");

  // ------------------------
  // Automatic network selection
  // ------------------------
  SerialMon.println("Setting network to automatic LTE/NB-IoT/GSM...");
  modem.sendAT("+CNMP=2");  // Automatic network mode (GSM/LTE auto)
  modem.sendAT("+CMNB=2");  // Automatic NB-IoT/LTE-M selection
  delay(1000);

  SerialMon.print("Waiting for network...");
  if (!modem.waitForNetwork()) {
    SerialMon.println(" ❌ Failed to connect to network");
    while (true);
  }
  SerialMon.println(" ✅ Network connected");

  SerialMon.print("Connecting to APN: "); SerialMon.println(apn);
  if (!modem.gprsConnect(apn, "", "")) {
    SerialMon.println("❌ GPRS connection failed");
    while (true);
  }
  SerialMon.println("✅ GPRS connected");

  SerialMon.print("Modem IP: "); SerialMon.println(modem.getLocalIP());

  // Show current network info
  SerialMon.print("Network type: "); SerialMon.println(modem.getNetworkMode());
  SerialMon.print("Operator: "); SerialMon.println(modem.getOperator());
  SerialMon.print("Signal quality: "); SerialMon.println(modem.getSignalQuality());

  // ------------------------
  // Init ESP-NOW
  // ------------------------
  WiFi.mode(WIFI_STA);
  if (esp_now_init() != ESP_OK) {
    SerialMon.println("❌ ESP-NOW init failed!");
    while (true);
  }
  esp_now_register_recv_cb(OnDataRecv);
  SerialMon.println("✅ ESP-NOW ready");
}

// ------------------------
// LOOP
// ------------------------
void loop() {
  // Check if there are queued packets
  if (queueHead != queueTail) {
    SensorData data = packetQueue[queueHead];
    queueHead = (queueHead + 1) % MAX_QUEUE;

    // Build JSON string
    String json = "{";
    json += "\"id\":" + String(data.id) + ",";
    json += "\"x_avg\":" + String(data.x_avg, 2) + ",";
    json += "\"y_avg\":" + String(data.y_avg, 2) + ",";
    json += "\"z_avg\":" + String(data.z_avg, 2) + ",";
    json += "\"temp_f\":" + String(data.temp_f, 2) + ",";
    json += "\"time_str\":\"" + String(data.time_str) + "\"";
    json += "}";

    SerialMon.println("Posting JSON: " + json);

    // Check signal quality first
    int rssi = modem.getSignalQuality();
    SerialMon.print("Signal quality: "); SerialMon.println(rssi);
    if (rssi < 10) {
      SerialMon.println("❌ Weak signal, will retry later");
      // Put packet back in queue
      queueHead = (queueHead - 1 + MAX_QUEUE) % MAX_QUEUE;
      delay(5000);
      return;
    }

    // Connect to server with retry (3 attempts)
    bool connected = false;
    for (int i = 0; i < 3; i++) {
      SerialMon.print("Connecting to server "); SerialMon.print(serverIP); SerialMon.print(":"); SerialMon.println(serverPort);
      if (client.connect(serverIP, serverPort)) {
        connected = true;
        break;
      }
      SerialMon.println("❌ TCP connection failed, retrying...");
      delay(3000);
    }
    if (!connected) {
      SerialMon.println("❌ Could not connect after 3 attempts → will try again next loop");
      queueHead = (queueHead - 1 + MAX_QUEUE) % MAX_QUEUE;
      delay(5000);
      return;
    }
    SerialMon.println("✅ TCP connection established");

    // Build HTTP POST request
    String httpRequest = String("POST ") + serverResource + " HTTP/1.1\r\n";
    httpRequest += "Host: " + String(serverIP) + "\r\n";
    httpRequest += "Content-Type: application/json\r\n";
    httpRequest += "Content-Length: " + String(json.length()) + "\r\n";
    httpRequest += "Connection: close\r\n\r\n";
    httpRequest += json;

    // Send HTTP POST
    client.print(httpRequest);
    SerialMon.println("HTTP POST sent. Waiting for response...");

    // Wait for server response (30s timeout)
    long timeout = millis() + 30000;
    bool received = false;
    while (client.connected() && millis() < timeout) {
      while (client.available()) {
        char c = client.read();
        SerialMon.print(c); // Prints raw server response
        received = true;
      }
    }
    if (!received) {
      SerialMon.println("\n❌ No response received → check server/firewall");
      queueHead = (queueHead - 1 + MAX_QUEUE) % MAX_QUEUE;
      delay(5000);
    } else {
      SerialMon.println("\n✅ Response received → server got the request");
    }

    client.stop();
    SerialMon.println("TCP connection closed\n");
  }
}

Any suggestions would be great. The code that worked perfectly before with ATT is below, but even it started producing a watchdog error as soon as it received the data and tried to send it out:

#include <esp_now.h>
#include <WiFi.h>
#include <SD.h>
#include <SPI.h>
#include <esp_task_wdt.h>
#include <Preferences.h>

#define TINY_GSM_MODEM_SIM7000
#define SerialMon Serial
#define SerialAT Serial1
#define TINY_GSM_RX_BUFFER 1024
#define DUMP_AT_COMMANDS
#define TINY_GSM_DEBUG SerialMon
#define GSM_AUTOBAUD_MIN 9600
#define GSM_AUTOBAUD_MAX 115200
#define TINY_GSM_USE_GPRS true
#define TINY_GSM_USE_WIFI false
#define GSM_PIN ""

// SD card pins
#define SD_MISO 2
#define SD_MOSI 15
#define SD_SCLK 14
#define SD_CS   13

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

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

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

TinyGsmClient client(modem);
HttpClient http(client, "3.148.106.137", 80); // Replace with your server IP or domain

// --- Customize these ---
const char apn[] = "hologram";
//213x.m2m.com.attz
//hologram




const char gprsUser[] = "";
const char gprsPass[] = "";
const char serverResource[] = "/upload.php";

// Struct to match transmitter
typedef struct {
  int id;
  float x_avg;
  float y_avg;
  float z_avg;
  float temp_f;
  char time_str[9]; // "HH:MM:SS"
} SensorData;

File dataFile;

// Function declarations
void initGSM();
void connectAPN();
bool sendDataToServer(SensorData data);
void savePacket(const SensorData &data, const char* status);
void setupSD();
void initESPNow();

// ESP-NOW Receive Callback
void OnDataRecv(const esp_now_recv_info_t *info, const uint8_t *incomingData, int len) {
  SensorData data;
  memcpy(&data, incomingData, sizeof(data));

  Serial.println("📡 Received Data:");
  Serial.printf("Node ID: %d\n", data.id);
  Serial.printf("Time: %s\n", data.time_str);
  Serial.printf("X Peak Freq: %.2f Hz\n", data.x_avg);
  Serial.printf("Y Peak Freq: %.2f Hz\n", data.y_avg);
  Serial.printf("Z Peak Freq: %.2f Hz\n", data.z_avg);
  Serial.printf("Temp (°F): %.2f\n", data.temp_f);
  Serial.println("------------------------");

  if (sendDataToServer(data)) {
    Serial.println("✅ Data sent successfully!");
    savePacket(data, "SENT");
  } else {
    Serial.println("❌ Sending failed.");
    savePacket(data, "FAILED");
  }
}

void setup() {
  SerialMon.begin(115200);
  delay(100);

  initGSM();
  connectAPN();
  setupSD();
  initESPNow();
}

void loop() {
  // Optional: Retry sending failed data from SD card here
}

// ------------------------
// GSM Setup
// ------------------------
void initGSM() {
  Serial.println("📶 Initializing GSM...");

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

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

  if (!modem.init()) {
    Serial.println("❌ Modem init failed!");
    ESP.restart();
  }

  Serial.println("✅ Modem ready.");
  Serial.println("Modem Name: " + modem.getModemName());
  Serial.println("Modem Info: " + modem.getModemInfo());

  if (GSM_PIN && modem.getSimStatus() != 3) {
    modem.simUnlock(GSM_PIN);
  }

  modem.sendAT("+CFUN=1");
  modem.waitResponse();

  if (!modem.setNetworkMode(2)) {
    Serial.println("❌ Failed to set network mode.");
  }
  if (!modem.setPreferredMode(3)) {
    Serial.println("❌ Failed to set preferred mode.");
  }

  Serial.println("📱 GSM module ready.");
}

void connectAPN() {
  Serial.print("🌐 Connecting to APN: ");
  Serial.println(apn);

  if (!modem.waitForNetwork()) {
    Serial.println("❌ No network.");
    ESP.restart();
  }

  if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
    Serial.println("❌ GPRS connection failed.");
    ESP.restart();
  }

  Serial.println("✅ Connected to cellular network.");
}

// ------------------------
// HTTP Upload
// ------------------------
bool sendDataToServer(SensorData data) {
  String json = "{";
  json += "\"id\":" + String(data.id) + ",";
  json += "\"x_avg\":" + String(data.x_avg, 2) + ",";
  json += "\"y_avg\":" + String(data.y_avg, 2) + ",";
  json += "\"z_avg\":" + String(data.z_avg, 2) + ",";
  json += "\"temp_f\":" + String(data.temp_f, 2) + ",";
  json += "\"time_str\":\"" + String(data.time_str) + "\"";
  json += "}";

  Serial.println("🌐 Posting data: " + json);

  http.beginRequest();
  http.post(serverResource);
  http.sendHeader("Content-Type", "application/json");
  http.sendHeader("Content-Length", json.length());
  http.beginBody();
  http.print(json);
  http.endRequest();

  int statusCode = http.responseStatusCode();
  String response = http.responseBody();

  Serial.print("📡 Status code: ");
  Serial.println(statusCode);
  Serial.print("Response: ");
  Serial.println(response);

  return (statusCode == 200);
}

// ------------------------
// SD Card Handling
// ------------------------
void setupSD() {
  SPI.begin(SD_SCLK, SD_MISO, SD_MOSI, SD_CS);

  if (!SD.begin(SD_CS)) {
    Serial.println("❌ SD card init failed.");
  } else {
    Serial.println("✅ SD card ready.");
  }
}

void savePacket(const SensorData &data, const char* status) {
  dataFile = SD.open("/data.txt", FILE_APPEND);
  if (dataFile) {
    dataFile.print(data.id);
    dataFile.print(",");
    dataFile.print(data.time_str);
    dataFile.print(",");
    dataFile.print(data.x_avg, 2);
    dataFile.print(",");
    dataFile.print(data.y_avg, 2);
    dataFile.print(",");
    dataFile.print(data.z_avg, 2);
    dataFile.print(",");
    dataFile.print(data.temp_f, 2);
    dataFile.print(",");
    dataFile.println(status);
    dataFile.close();
    Serial.printf("💾 Data saved to SD with status: %s\n", status);
  } else {
    Serial.println("❌ Failed to write to SD card.");
  }
}

// ------------------------
// ESP-NOW Setup
// ------------------------
void initESPNow() {
  WiFi.mode(WIFI_STA);

  if (esp_now_init() != ESP_OK) {
    Serial.println("❌ ESP-NOW init failed!");
    ESP.restart();
  }

  Serial.println("✅ ESP-NOW ready.");
  esp_now_register_recv_cb(OnDataRecv);
}

Any help would be 1000000000% helpful please

It could be a bad soldering, a bad contact in a breadbord, broken wire…

Please post a photo of the build.

What power supply are you using for the module?

I'm assuming the sketch you showed is running on the ESP32?

My first suspect would then be that an ESP32 core update has happened sometime in the past 2 months and has broken something. If you've compiled and uploaded your sketch between "was working" and "isn't working", and you hadn't changed anything in the sketch, rolling back the ESP32 core a few versions and recompiling/reuploading could be useful.

Using this service https://dnschecker.org/ping-ipv4.php I can ping your server 3.138.117.223.

The address which your sim7000G lilygo module gets from your mobile provider 10.247.105.179 is not routeable because it is in a 10.x.x.x network. That doesn't mean it won't work in this situation but you won't be able to initiate a communication from the Internet to your lilygo module. For that you would need to know its public IP address. Again, that may be what you expect.

Anyway, also plausible, apart from the already suggested ESP32 software change, is a mobile service change, say adding firewall rules etc. Can you connect to any external IP address from the lilygo, say Google.com ?

Hello! there is nothing soldered and no breadboard. Just a sim7000G lilygo module with a simcard inside. It receives data from another esp32 that is just sending random xyz data to test espnow and sending to the server

USB C to power it

Hello! No the esp32 just sends xyz and time data to the sim7000g esp32 lilygo module. All the code shown in this post was uploaded to the sim7000G esp32 lilygo

Hmmmm this sounds interesting actually. I ordered some ATT SIM cards to try since those worked before, but I thought hologram would work even if my amazon ec2 aws has all traffic allowed to it (for short term testing inbound)