Arduino(ESP8266)未收到所有字符

时间:2019-03-21 21:01:23

标签: arduino-ide arduino-esp8266

我有一个18164字节的文件,我试图从ESP8266(4m)下载,但是我只收到文件的一部分(大约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() {
}

1 个答案:

答案 0 :(得分:0)

您可能会耗尽ESP8266中的可用内存。开始没有很多。

您的4m ESP8266具有4Mbits的闪存(512KB),但是您正在将下载的文件累积在RAM中,这更加稀缺。 ESP8266具有80KB的RAM。其中一些RAM已被Arduino Core和网络堆栈使用。

我在连接了WiFi客户端的ESP8266上加载了一个最小程序,并看到51KB的可用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相比,最好将文件一次读入String数组中,或者一次将其保存到SPIFFS块中(块大小为512)更好。 / p>