我有一个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() {
}
答案 0 :(得分:0)
您可能会耗尽ESP8266中的可用内存。开始没有很多。
您的4m ESP8266具有4Mbits的闪存(512KB),但是您正在将下载的文件累积在RAM中,这更加稀缺。 ESP8266具有80KB的RAM。其中一些RAM已被Arduino Core和网络堆栈使用。
我在连接了WiFi客户端的ESP8266上加载了一个最小程序,并看到51KB的可用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
相比,最好将文件一次读入String
数组中,或者一次将其保存到SPIFFS块中(块大小为512)更好。 / p>