Sim7000A Max Packet Size to Server using HTTP

Hello Everyone,

I have a sim7000A module and want to send a very large packet of data similar to the following below:

x:0.02333,y:0.33321,Z:9.8123,T:4:13:30:301,x:0.01333,y:0.23321,Z:9.8523,T:4:13:30:315, x:0.05333,y:0.13321,Z:9.8113,T:4:13:30:330....

I have tried 2 methods, but it seems that the maximum size is 1500 bytes. That comes out to be around 30 packets of data. If I change my code to 31 it gives me a 400 error. Every number under 30 works, so I am not sure what the maximum is. I want to send 100 or 150 packets if possible.

Code below:

//Update V3_ 23-FEB-2023
// ADXL345 Accelerometer, and a Depth sensor
#include <esp_now.h>
#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>
#include "RTClib.h"

RTC_DS3231 rtc;

Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified();

//Pins for depth sensors (4 sensors)
#define TRIG1 13 //Module pins Depth sensor_1
#define ECHO1 12
//Depth_sensor_2
#define TRIG2 14
#define ECHO2 26
//Depth_senosr_3me
#define TRIG3 33
#define ECHO3 32
//Depth_sensor_4
#define TRIG4 25 //35 on board
#define ECHO4 27 // 34 on board

//int distance_Measure1 = 0;
float distance_Measure1 = 0.0;
float distance_Measure2 = 0.0;
float distance_Measure3 = 0.0;
float distance_Measure4 = 0.0;

bool error;

float X_avg = 0.0;
float Y_avg = 0.0;
float Z_avg = 0.0;

//Time Variables
int previous_Sec = 0;
int Millis_Time = 0;
int C_millis = 0;
int P_millis = 0;
String time_now = "";
float temperatureF = 0.0;

//variables to keep track of the timing of 1 min for diferent packets to send
unsigned long start_time = 0;
unsigned long last_time = 0;

// REPLACE WITH YOUR RECEIVER MAC Address
//uint8_t broadcastAddress[] = {0x94, 0xB9, 0x7E, 0xE9, 0xBB, 0xAC};
//sim7000A Address  = {0x4C, 0x75, 0x25, 0x67, 0x33, 0x14};
//simm7000G Address = {0x70, 0xB8, 0xF6, 0x06, 0xA5, 0xF8}

uint8_t broadcastAddress[] = {0x4C, 0x75, 0x25, 0x67, 0x33, 0x14};



// Structure to send data from ESP32 using ESPNOW
// Must match the receiver structure
typedef struct struct_message {

  char depth1[10];
  char depth2[10];
  char depth3[10];
  char depth4[10];
  char accel_x[10];
  char accel_y[10];
  char accel_z[10];
  char TTime[40];
  char Temp[10];


} struct_message;
// Create a struct_message called myData
struct_message myData;


esp_now_peer_info_t peerInfo;

// callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
 // Serial.print("\r\nLast Packet Send Status:\t");
  //Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}

void setup() {

  Serial.begin(115200);
  rtc.begin();
  //rtc.adjust(DateTime(__DATE__, __TIME__));
  //  rtc.adjust(DateTime(0, 0, 0, 16, 34, 00));  // Set the desired time here

  initWifi();  // Function to initialize WiFi

  initESPNOW();  // Funtcion to initialize ESPNOW communication between ESP32

  init_depth_Sensor(); // Initialize depth sensor
  init_Accl_Sensor(); // Initialize Accel sensor
  accel.setDataRate(ADXL345_DATARATE_3200_HZ); // Set the data rate to 3200 Hz (maximum)



}


void loop() {

  start_time = millis();
  if (start_time - last_time >= 60 * 1000) //  X * Seconds
  {
   // Serial.println("Combined: ");

    //MeasureTime(); //Measure Time
    Measure_Accleromter(); // Measure accel
    Measure_Depth(); //Measure depth
    sendEspNowData();  //function to send notification to other ESP32 (recieving ESP32)
    last_time = start_time;
  }
  else
  {
   // Serial.println("Only: ");

    Measure_Accleromter(); // Measure accel
    distance_Measure1 = 0;
    distance_Measure2 = 0;
    distance_Measure3 = 0;
    distance_Measure4 = 0;
    temperatureF = 0;
    sendEspNowData();  //function to send notification to other ESP32 (recieving ESP32)

  }


}






////////////////////////////////////////////INITILIZATION OF FUNCTIONS///////////////////////////


//Function to initialze WiFi
void initWifi() {
  // Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);
}



//Function to initilaze ESPNOW communication
void initESPNOW() {

  // Init ESP-NOW
  if (esp_now_init() != ESP_OK) {
  //  Serial.println("Error initializing ESP-NOW");
    return;
  }

  // Once ESPNow is successfully Init, we will register for Send CB to
  // get the status of Trasnmitted packet
  esp_now_register_send_cb(OnDataSent);

  // Register peer
  memcpy(peerInfo.peer_addr, broadcastAddress, 6);
  peerInfo.channel = 0;
  peerInfo.encrypt = false;

  // Add peer
  if (esp_now_add_peer(&peerInfo) != ESP_OK) {
    //Serial.println("Failed to add peer");
    return;
  }

 // Serial.println("ESPNOW initialize sucssfully");
}


// Function to initialize depth sensor
void init_depth_Sensor() {
  pinMode(TRIG1, OUTPUT); // Initializing Trigger Output
  pinMode(ECHO1, INPUT_PULLUP);
  pinMode(TRIG2, OUTPUT); // Initializing Trigger Output and Echo Input
  pinMode(ECHO2, INPUT_PULLUP);
  pinMode(TRIG3, OUTPUT); // Initializing Trigger Output and Echo Input
  pinMode(ECHO3, INPUT_PULLUP);
  pinMode(TRIG4, OUTPUT); // Initializing Trigger Output and Echo Input
  pinMode(ECHO4, INPUT_PULLUP);

}



void TCA9548A(uint8_t bus)
{
  Wire.beginTransmission(0x70); // TCA9548A address is 0x70
  Wire.write(1 << bus);         // send byte to select bus
  Wire.endTransmission();
  // Serial.print(bus);
}



// Function to initialize Accelerometer sensor
void init_Accl_Sensor(void)
{

  Wire.begin(); //start wire library for i2c
  Wire.beginTransmission(0x70);
  error = Wire.endTransmission();
  if (error == 0) {
   // Serial.print("TCA9548A found at address 0x70");
  }
  else {
    Serial.println("No TCA9548A detected. Something went wrong!");
    while (1);
  }


  //Initialize channel 1 to channel 6 if TCA9548A with ADXL345
  for (int i = 1; i < 7; I++)
  {
    TCA9548A(i);
    if (!accel.begin()) {
     // Serial.println("No ADXL345 sensor detected.");
      while (1);
    } else {
      Serial.print("ADXL345 sensor detected. : ");
      Serial.print(i);
    }
    accel.setRange(ADXL345_RANGE_2_G);
    displayRange();
    //delay(10);
  }
}


void displayRange(void)
{
  Serial.print("   Range: +/- ");

  switch (accel.getRange())
  {
    case ADXL345_RANGE_16_G:
      Serial.print("16 ");
      break;
    case ADXL345_RANGE_8_G:
      Serial.print("8 ");
      break;
    case ADXL345_RANGE_4_G:
      Serial.print("4 ");
      break;
    case ADXL345_RANGE_2_G:
      Serial.print("2 ");
      break;
    default:
      Serial.print("?? ");
      break;
  }
  Serial.println(" g");
}




/////////////////////////////////////////////////FUNCTION TO MEASURE SENSORS DATA///////////////////////////////////////

void MeasureTime() {

  DateTime now = rtc.now();
  int hr = now.hour();
  int mn = now.minute();
  int sec = now.second();
  int current_sec = now.second();



  if (current_sec == previous_Sec)
  {

    C_millis = millis();
    Millis_Time = ( C_millis - P_millis );

    if (Millis_Time >= 999)
    {
      P_millis = C_millis;
      Millis_Time = random(998, 999);
    }



  }
  else
  {
    previous_Sec = current_sec;
    Millis_Time = 14;
    P_millis = C_millis;

  }




  time_now = (String)hr + ":" + (String) mn + ":" + (String) sec + ":" + (String)Millis_Time;
  //  Serial.println("Time now: ");
  //Serial.println(time_now);

 // Serial.println();



  float temperatureC = rtc.getTemperature();
  temperatureF = (temperatureC * 9 / 5) + 32; // Convert Celsius to Fahrenheit
  //Serial.print(" ");
  // Serial.println(temperatureF);
  //Serial.println();
}

// Function to measure depth
void Measure_Depth() {

  distance_Measure1 = 0.0;
  distance_Measure2 = 0.0;
  distance_Measure3 = 0.0;
  distance_Measure4 = 0.0;
  //sensor_1 calculation
  digitalWrite(TRIG1, LOW); // Set the trigger pin to low for 2uS
  delayMicroseconds(2);
  digitalWrite(TRIG1, HIGH); // Send a 10uS high to trigger ranging
  delayMicroseconds(20);
  digitalWrite(TRIG1, LOW); // Send pin low again
  distance_Measure1 = pulseIn(ECHO1, HIGH, 26000); // Read in times pulse
  distance_Measure1 = distance_Measure1 / 52; //Convert the pulse duration to distance
  //delay(5);

  //sensor_2 calculation
  digitalWrite(TRIG2, LOW); // Set the trigger pin to low for 2uS
  delayMicroseconds(2);
  digitalWrite(TRIG2, HIGH); // Send a 10uS high to trigger ranging
  delayMicroseconds(20);
  digitalWrite(TRIG2, LOW); // Send pin low again
  distance_Measure2 = pulseIn(ECHO2, HIGH, 26000); // Read in times pulse
  distance_Measure2 = distance_Measure2 / 52; //Convert the pulse duration to distance
  //delay(50);

  //sensor_3 calculation
  digitalWrite(TRIG3, LOW); // Set the trigger pin to low for 2uS
  delayMicroseconds(2);
  digitalWrite(TRIG3, HIGH); // Send a 10uS high to trigger ranging
  delayMicroseconds(20);
  digitalWrite(TRIG3, LOW); // Send pin low again
  distance_Measure3 = pulseIn(ECHO3, HIGH, 26000); // Read in times pulse
  distance_Measure3 = distance_Measure3 / 52; //Convert the pulse duration to distance
  //delay(50);


  //sensor_4 calculation
  digitalWrite(TRIG4, LOW); // Set the trigger pin to low for 2uS
  delayMicroseconds(2);
  digitalWrite(TRIG4, HIGH); // Send a 10uS high to trigger ranging
  delayMicroseconds(20);
  digitalWrite(TRIG4, LOW); // Send pin low again
  distance_Measure4 = pulseIn(ECHO4, HIGH, 26000); // Read in times pulse
  distance_Measure4 = distance_Measure4 / 52; //Convert the pulse duration to distance
  //delay(50);

  //13.4 for Water
  //52 or 58 for air
  /*
    Serial.print("\n Distance (depth) by sensor_1:  \n");
    Serial.print(distance_Measure1);
    Serial.println("cm");
    Serial.print("\n Distance (depth) by sensor_2:  \n");
    Serial.print(distance_Measure2);
    Serial.println("cm");
    Serial.print("\n Distance (depth) by sensor_3:  \n");
    Serial.print(distance_Measure3);
    Serial.println("cm");
    Serial.print("\n Distance (depth) by sensor_4:  \n");
    Serial.print(distance_Measure4);
    Serial.println("cm");
  */
  //delay(50);
}



// Function to measure Accelerometer
void Measure_Accleromter(void)
{

  X_avg = 0.0;
  Y_avg = 0.0;
  Z_avg = 0.0;

  for (int i = 1; i < 7; i++) {
    TCA9548A(i);
    sensors_event_t event;
    accel.getEvent(&event);
    X_avg += event.acceleration.x;
    Y_avg += event.acceleration.y;
    Z_avg += event.acceleration.z;
  }
  // Need to measure time here
  MeasureTime(); //Measure Time

}




// Function to send data using ESPNOW
void sendEspNowData() {

 // Serial.println("SendESPNowData Function: ");


  float accel_x = X_avg / 6 ;
  float accel_y = Y_avg / 6 ;
  float accel_z = Z_avg / 6 ;

  //buffer for converting float into string
  char depth1_string[8];
  memset(depth1_string, 0, 8);
  char depth2_string[8];
  memset(depth2_string, 0, 8);
  char depth3_string[8];
  memset(depth3_string, 0, 8);
  char depth4_string[8];
  memset(depth4_string, 0, 8);
  char accel_x_string[10];
  memset(accel_x_string, 0, 10);
  char accel_y_string[10];
  memset(accel_y_string, 0, 10);
  char accel_z_string[10];
  memset(accel_z_string, 0, 10);
  char temp_string[10];
  memset(temp_string, 0, 10);

  //Convert float into string
  dtostrf(distance_Measure1, 6, 2, depth1_string);
  dtostrf(distance_Measure2, 6, 2, depth2_string);
  dtostrf(distance_Measure3, 6, 2, depth3_string);
  dtostrf(distance_Measure4, 6, 2, depth4_string);
  dtostrf(accel_x, 6, 5, accel_x_string);
  dtostrf(accel_y, 6, 5, accel_y_string);
  dtostrf(accel_z, 6, 5, accel_z_string);
  dtostrf(temperatureF, 6, 2, temp_string);

  char time_NOW[40];
  time_now.toCharArray(time_NOW, 40);
  // sprintf(time_NOW, "%c", time_now);

  // Serial.println("time_NOW___");
  // Serial.println(time_NOW);


  strcpy(myData.depth1, depth1_string);
  strcpy(myData.depth2, depth2_string);
  strcpy(myData.depth3, depth3_string);
  strcpy(myData.depth4, depth4_string);
  strcpy(myData.accel_x, accel_x_string);
  strcpy(myData.accel_y, accel_y_string);
  strcpy(myData.accel_z, accel_z_string);
  strcpy(myData.TTime, time_NOW);
  strcpy(myData.Temp, temp_string);


 // Serial.println("\n myData.depth_1 is: ");
 // Serial.println(myData.depth1);
  // Serial.println("\n myData.depth_2 is: ");
  //Serial.println(myData.depth2);
  // Serial.println("\n myData.depth_3 is: ");
  // Serial.println(myData.depth3);
  // Serial.println("\n myData.depth_4 is: ");
  // Serial.println(myData.depth4);
 // Serial.println("\n myData.accel_x is: ");
  Serial.println(myData.accel_x);
  //Serial.println("\n myData.accel_y is: ");
  Serial.println(myData.accel_y);
  //Serial.println("\n myData.accel_z is: ");
  Serial.println(myData.accel_z);
  //Serial.println("\n myData.TTime is: ");
  Serial.println(myData.TTime);
 // Serial.println("\n myData.Temp is: ");
  //Serial.println(myData.Temp);



  // Send message via ESP-NOW
  esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));

  if (result == ESP_OK) {
  //  Serial.println("Sent with success");
  }
  else {
    Serial.println("Error sending the data");
  }
  //delay(50);
}

This is not a Sim7000 limitation, it is a general standard for the TCP protocols - depending on the implementation, the maximum transfer unit (MTU) size for the Ethermet is from 1450 to 1530 bytes.

This can't be a limitation for your network transmission - all existing clients and servers on the Internet transmit data by breaking them to a small packets.

Another option - change the format of your data, so that their length is less.
As far I see, you transmit numeric data in ASCII form, which is not an efficient solution. Pass your points x y z as three floats - and each set will take 12 bytes instead of 30 bytes, as you have.

So while it is sending this information there is no way to not lose the incoming information from the transmitter? Also, my code is posted so you can see the format of my data

They are all floats I believe unless I missed something

No, they not a floats in your code, they are text strings. Each value in your data transmits as 10 chars string. You could reduce the size of the packet by 2.5 times if transmit data as floats.

If I transmit this data as a float: x:0.0023,y:0.03345,z:9.8652,T:14:03:02:304

How would that reduce the size by almost 3x?

Your representation is not a float itself, it is a float, converted to text string. Every string like "y:0.03345", with extra commas, needs a 9-10 bytes.

You can instead send floats as binary data, and each value will occupy 4 bytes only.

Gotcha so If I convert all to floats, but not to binary, would they not still take up only 4 bytes?

To floats, but not to binary - please show how do you plan to do that?
It seems to me you don't understand, that all data in controller are represenred in binary.
"Float, but not binary" - it is just non-existent.

Your two topics about sending data via Sim7000 looks like duplicates. I think it would be better ask to moderator to merge them

I'm going to close this topic in favor of the other one:

Feel free to continue the discussion over there.