无法使用 SIM800L+ESP32 发送大小超过 1449 个字符的 HTTP POST 负载

问题描述 投票:0回答:3

因此,我在 ESP32+SIM800L 设置上通过 HTTP POST 将数据发送到托管在 000WebHost 上的 php 脚本。 我以 800Hz 记录传感器数据并将其存储在字符数组中,例如:a[]=3&a[]=5&a[]=8...,这将成为 POST 请求的有效负载数组。

出于某种原因,我只能发送 161 个值,内容长度约为 1449。

代码有点长,所以我在这里减少了它: 我正在使用 TinyGSM 库

//Start GSM:
 SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
 SerialMon.println("Initializing modem...");


modem.init();
  SerialMon.print(F("Connecting to "));
   SerialMon.print(apn);
   if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
      SerialMon.println(" fail");
      delay(10000);
      return;
    }
   SerialMon.println(" success");

   if (modem.isGprsConnected()) {
      SerialMon.println("GPRS connected");
  }

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


// Record Sensor values for one second
//Send the character array to the httpPost function:
if (client.connect(server,port)) {
  Serial.println("connected");
  client.println("POST /upload.php? HTTP/1.1");
  client.println("Host:  epiblastic-reactor.000webhostapp.com");
  client.println("User-Agent: TTGO-TCALL/1.0");
  client.println("Content-Type: application/x-www-form-urlencoded;");
  client.print("Content-Length: ");
  client.println(String(acceldata).length());
  client.println();
  client.println(acceldata);
  

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

如果我发送超过 161 个值,串行监视器将打印:

#Available: 0 on 1

持续不断。

出了什么问题? 有人可以帮我吗?

php http-post esp32 arduino-ide sim800l
3个回答
2
投票

以太网的MTU通常为1500,但对于SIM800,我相信它设置为1460字节(您可以使用

AT+CIPSEND?
检查该值)。 TinyGSM 使用的 TCP/HTTP 客户端似乎不会将长度超过 1 MTU 的数据分成块,因此用户有责任这样做。

这里是如何以多个块发送数据的示例。

代码已从初始输入更新

#define ONE_CHUNK 1024  //you can change it as long as it is <= MTU

int payload_length = acceldata.length(); //assuming your data is already a String object
client.print("Content-Length: ");
client.println(payload_length);
client.println();

if (payload_length < ONE_CHUNK) {  //less than ONE_CHUNK, send it
  client.println(acceldata);
}
else {  // more than ONE_CHUNK, break it into number of chunks
  int chunks = payload_length / ONE_CHUNK;
  for(int i = 0; i < chunks; i++){
    client.print(acceldata.substring(i*ONE_CHUNK, (i*ONE_CHUNK)+ONE_CHUNK));
  }
  int last_chunk = payload_length - chunks * ONE_CHUNK;
  if (last_chunk) {
    client.println(acceldata.substring(payload_length-last_chunk, payload_length - 1)); 
  } 
}

0
投票

没有什么明显的,您可能需要检查您的 TinyGSM 配置,并可能启用该库的调试输出。

无论如何。总是有常见的嫌疑人:

首先,您没有在 ESP32 和调制解调器之间的串行链路上使用流量控制。这意味着,如果您向调制解调器发送的数据多于调制解调器可以发送到互联网的数据,调制解调器的串行缓冲区可能会溢出。好的解决方案是在两侧启用串行流控制(硬件最好,软件可以解决问题)。一个糟糕的解决方案是更慢地发送数据,例如每几秒 1400 字节。

其次检查服务器端是否有任何异常情况,即服务器关闭连接。

然后您可以检查 - 无论对象

client
是什么(您的代码不会显示它的创建位置) - 它实际上允许您使用大量数据调用
println()

就数据量而言,通过 HTTP 请求发送 6-7 KiB 数据并没有什么不寻常的。仅当您想通过吞吐量较低的链路每秒发送这么多数据时,才会出现问题 - 显然它没有能力做到这一点。 GPRS 上传


0
投票

我有同样的问题,我无法发送6ko的大数据,但使用esp32+sim7600。 我已经尝试了建议的解决方案,但我仍然无法得到它。有人有什么想法吗?谢谢你

© www.soinside.com 2019 - 2024. All rights reserved.