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

不断地。

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

4

2 回答 2

1

以太网的MTU通常为 1500,但对于 SIM800,我相信它设置为 1460 字节(您可以使用 来检查该值AT+CIPSEND?)。TinyGSM 使用的 TCP/HTTP 客户端似乎不会将超过一个 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)); 
  } 
}
于 2021-04-30T15:34:21.610 回答
0

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

反正。总是有通常的嫌疑人:

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

其次检查服务器端没有异常发生,即服务器关闭连接。

然后你可以检查一下——无论对象client是什么(你的代码没有显示它是在哪里创建的)——它实际上允许你调用println()大量数据。

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

于 2021-04-29T17:33:21.607 回答