Arduino(ESP8266)没有接收到所有角色

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

我有一个18164字节的文件,我试图从ESP8266(4米)下载,但我只收到文件的一部分(约17000字节)。有时它会收到所有但往往不会。该文件是一个缩小的javascript文件。 5000字节的较小文件可以正常工作。如果缓冲区大小有问题,如何增加WiFiClient的缓冲区大小?

void setup()
{
  String line = "";
  ...

  while ((net.connected() || net.available()))
  {
    if (net.available())
    {
      char c = net.read();
      line += c;
    }
  }
  net.stop();

  Serial.println("Line:-" + line + "-");
}

void loop() {
}
arduino-ide arduino-esp8266
1个回答
0
投票

你可能正在耗尽ESP8266的可用内存。它没有太多开始。

你的4m ESP8266有4Mbits的闪存(512K字节),但是你正在累积你在RAM中下载的文件,这更加稀缺。 ESP8266具有80K字节的RAM。 Arduino核心和网络堆栈已经使用了部分RAM。

我在带有连接的WiFi客户端的ESP8266上加载了一个最小程序,并且可以看到51K字节的RAM。

你也经常使用StringString使用从ESP8266上的空闲内存分配的内存来存储实际的字符串。每次添加一个字符时,String将释放其先前的存储空间并分配相同的数量加上一个字节。 Arduino Core没有特别复杂的内存管理;这可能导致堆碎片到你无法分配更大内存的程度,并且你的程序会失败。

您可以通过以下调用了解可用内存的状态:

  • ESP.getFreeHeap() - 返回可用内存总量
  • ESP.getHeapFragmentation() - 返回堆碎的严重程度的指示。越大越坏 - 超过50是非常糟糕的。
  • ESP.getMaxFreeBlockSize() - 你可以分配的最大块。

为了验证,我会尝试这样的事情:

while ((net.connected() || net.available()))
  {
    if (net.available())
    {
      char c = net.read();
      line += c;
      Serial.print("line length: ");
      Serial.println(line.length());
      Serial.print("free heap: ");
      Serial.println(ESP.getFreeHeap());
      Serial.print("heap fragmentation: ");
      Serial.println(ESP.getHeapFragmentation());
      Serial.print("max block size: ");
      Serial.println(ESP.getMaxFreeBlockSize());
    }
  }
  net.stop();

如果最大块大小接近或小于line的长度,则不能再分配足够大的内存来存储line + c,并且程序将以您描述的方式失败。

您可以尝试的一件事是在创建线后在reserve()上使用String方法。就像是:

String line;

line.reserve(18500);
line = "";

最终你将文件读入char数组要好得多,或者一次将其保存到SPIFFS块(512将是一个很好的大小),而不是使用String

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