0

I'm using ESP8266 Arduino for compiling and uploading my code to NodeMCU 1.0 (ESP-12E Module). Flash Size: 4M (3M SPIFFS) CPU frequency: 80 MHz Upload Speed: 115200

I'm using portable arduino-1.6.9-windows extracted in my D: drive. I'm using the latest ESP8266 Arduino image brought by git command.

I've written this basic code to download 'datalog.txt' file (stored in the root of my SD card).

#include <ESP8266WiFi.h>
#include <WiFiClient.h> 
#include <ESP8266WebServer.h>
#include <SPI.h>
#include <SD.h>

const int chipSelect = 4;

const char *ssid = "tiny-esp";
const char *password = "password";

ESP8266WebServer server(80);

String home = "<h1>Hello! from ESP8266!</h1>"
                "<p><a href=\"down\"><button>Download</button></a>";

void handleRoot() {
    server.send(200, "text/html", home);
}

void handleDownload() {

    File dataFile = SD.open("datalog.txt");
    int fsizeDisk = dataFile.size();
    Serial.print("fsizeDisk: ");
    Serial.println(fsizeDisk);

    size_t fsizeSent = server.streamFile(dataFile,"text/plain");

    Serial.print("fsizeSent: ");
    Serial.println(fsizeSent);

    dataFile.close();
}


void setup() {
    delay(500);
    Serial.begin(115200);
    Serial.println();

    WiFi.softAP(ssid, password);

    IPAddress apip = WiFi.softAPIP();
    Serial.print("Please visit: \n");
    Serial.println(apip);

    // see if the card is present and can be initialized:
    if (!SD.begin(chipSelect)) {
        Serial.println("\nCard failed, or not present");
        // don't do anything more:
        return;
    }
    Serial.println("\nCard Initialized.");

    server.on("/", handleRoot);
    server.on("/down", handleDownload);
    server.begin();
    Serial.println("HTTP server started");
}

void loop() {
    server.handleClient();
}

But, when I press the 'Download' button, the ESP hangs, dumps some errors and then restarts as displayed below (from my Serial Monitor):

Please visit: 
192.168.4.1

Card Initialized.
HTTP server started
fsizeDisk: 28600

Panic D:\arduino-1.6.9-windows\arduino-1.6.9\hardware\esp8266com\esp8266\cores\esp8266\core_esp8266_main.cpp:98 __yield

ctx: sys 
sp: 3ffffc80 end: 3fffffb0 offset: 01b0

>>>stack>>>
3ffffe30:  3ffefdf4 000003b9 000003b9 4010020c  
3ffffe40:  00000000 3ffe9645 00000001 4020815d  
3ffffe50:  3ffefdf4 00000481 3fff0d50 402077e5  
3ffffe60:  3fff337c 00000b68 00000000 40207823  
3ffffe70:  3fff3a74 3fff1480 3fff3a74 3fff1474  
3ffffe80:  3fff337c 00000b68 3fff307c 40202a57  
3ffffe90:  3fff3a74 00000b68 3fff2cfc 40202c07  
3ffffea0:  00000000 3ffe9704 3fff337c 3fff1474  
3ffffeb0:  3fff337c 3fff147c 3fff2cfc 40202d34  
3ffffec0:  3ffeead0 0883f900 3fff1478 40202d54  
3ffffed0:  3fff337c 3fff147c 3fff1478 4022670d  
3ffffee0:  00000000 0104a8c0 00000010 00000000  
3ffffef0:  00000000 00000010 3ffefe40 40221001  
3fffff00:  40210000 00000000 0000007d 3fff151c  
3fffff10:  3ffebae4 3fff1520 3fff3434 40224b39  
3fffff20:  3fff1370 3fff1fac 3fff1fac 4021547e  
3fffff30:  40215972 3ffed310 3ffebabc 3fff1fac  
3fffff40:  3ffebad6 00000000 3fff3434 40223f35  
3fffff50:  0204a8c0 3ffee318 02a93dee 00000000  
3fffff60:  40104b62 02a93dee 3ffeead0 60000600  
3fffff70:  4022d230 3ffeeaa8 3ffeead0 0884220c  
3fffff80:  4022d256 3fffdab0 00000000 3fff2004  
3fffff90:  3fffdc90 00000000 3fff3434 4022ce8b  
3fffffa0:  40000f49 3fffdab0 3fffdab0 40000f49  
<<<stack<<<

 ets Jan  8 2013,rst cause:2, boot mode:(3,7)

load 0x4010f000, len 1384, room 16 
tail 8
chksum 0x2d
csum 0x2d
v00000000
~ld

Please visit: 
192.168.4.1

Card Initialized.
HTTP server started

I tried updating the code by writing custom "server.streamFile()" function and adding

"Content-Disposition: attachment; filename=\"datalog.txt\"\r\n";

to the header to allow downloading the txt file as an attachment.

The modified code is [Only handleDownload() function has been changed]:

#include <ESP8266WiFi.h>
#include <WiFiClient.h> 
#include <ESP8266WebServer.h>
#include <SPI.h>
#include <SD.h>

const int chipSelect = 4;

const char *ssid = "tiny-esp";
const char *password = "password";

ESP8266WebServer server(80);

String home = "<h1>Hello! from ESP8266!</h1>"
                "<p><a href=\"down\"><button>Download</button></a>";

void handleRoot() {
    server.send(200, "text/html", home);
}

void handleDownload() {

    int32_t time = millis();
    File dataFile = SD.open("datalog.txt");
    int fsizeDisk = dataFile.size();
    Serial.print("fsizeDisk: "); Serial.println(fsizeDisk);

    String WebString = "";
    WebString += "HTTP/1.1 200 OK\r\n";
    WebString += "Content-Type: text/plain\r\n";
    WebString += "Content-Disposition: attachment; filename=\"datalog.txt\"\r\n";
    WebString += "Content-Length: " + String(fsizeDisk) + "\r\n";
    WebString += "\r\n";
    server.sendContent(WebString);

    char buf[1024];
    int siz = dataFile.size();
    while(siz > 0) {
        size_t len = std::min((int)(sizeof(buf) - 1), siz);
        dataFile.read((uint8_t *)buf, len);
        server.client().write((const char*)buf, len);
        siz -= len;
    }
    Serial.print(siz);
    Serial.println(" Bytes left!");

    dataFile.close();
    time = millis() - time;
    Serial.print(time); Serial.println(" ms elapsed");
}


void setup() {
    delay(500);
    Serial.begin(115200);
    Serial.println();

    WiFi.softAP(ssid, password);

    IPAddress apip = WiFi.softAPIP();
    Serial.print("Please visit: \n");
    Serial.println(apip);

    // see if the card is present and can be initialized:
    if (!SD.begin(chipSelect)) {
        Serial.println("\nCard failed, or not present");
        // don't do anything more:
        return;
    }
    Serial.println("\nCard Initialized.");

    server.on("/", handleRoot);
    server.on("/down", handleDownload);
    server.begin();
    Serial.println("HTTP server started");
}

void loop() {
    server.handleClient();
}

Now, when I press the Download button, a popup opens up in browser displaying "datalog.txt" has started downloading. But after about 20-30 seconds it says "Download failed". The esp freezes after printing the 'fsizeDisk'.

Meanwhile, the serial monitor reads:

Please visit: 
192.168.4.1

Card Initialized.
HTTP server started
fsizeDisk: 28600

I don't understand what am I doing wrong. Please help!

EDIT: I added delay(2) and a Serial.println(cnt++) inside while(siz > 0) in handleDownload() for debugging:

int cnt=1;
delay(10);
while(siz > 0) {
    delay(2);
    Serial.println(cnt++);
    size_t len = std::min((int)(sizeof(buf) - 1), siz);
    dataFile.read((uint8_t *)buf, len);
    server.client().write((const char*)buf, len);
    siz -= len;
}

What happens now is, I get

Please visit: 
192.168.4.1

Card Initialized.
HTTP server started
fsizeDisk: 28600
1
2
3
4
5
6
7
8

The loop may hang up at any count(e.g. 10, 15, 17, 23, etc). Also, in my browser, it reads as 28% downloaded (for cnt=8) or so. So, file starts downloading but hangs up midway. I've tried increasing the delay upto 10 ms, but there has been no progress.

3
  • Try running blink on you hardware for a few minutes to illuminate hardware/IDE issues. Dec 5, 2016 at 14:23
  • Ultimately this may be something you need to pursue with the authors of the ESP8266 port. Perhaps you can try downloading a file without saving it anywhere (just throw away the data) or generate dummy data in a file and saving that. You could also try using a small test file of known contents. And try a different SD card. How are you powering this? The card might consume more current when being written. Dec 5, 2016 at 14:40
  • I've already posted this question in esp8266 forum. There has been no replies yet. I'm powering this (NodeMCU) using USB2.0 from my laptop. I don't think SD card is an issue here. I'm not writing anything on the card, just reading it. I'll try using a file of small size (~2kB). I'll also try downloading a file without saving it anywhere. Dec 6, 2016 at 6:49

1 Answer 1

1

try to add a yield() command in to your wihle-loop. With yield() the ESP hast time to do his background jobs.

1
  • I tried adding delay(2) in the while-loop. Now the download starts, but it does not finish. I've tried delay upto 10 ms, but there has been no improvement. I'll try adding yield() instead. In the meanwhile, please see the EDIT. Dec 6, 2016 at 7:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.