我有一个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() {
}
你可能正在耗尽ESP8266的可用内存。它没有太多开始。
你的4m ESP8266有4Mbits的闪存(512K字节),但是你正在累积你在RAM中下载的文件,这更加稀缺。 ESP8266具有80K字节的RAM。 Arduino核心和网络堆栈已经使用了部分RAM。
我在带有连接的WiFi客户端的ESP8266上加载了一个最小程序,并且可以看到51K字节的RAM。
你也经常使用String
。 String
使用从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
。