Sd card Arduino-Esp8266 12E读取SD卡文件

Sd card Arduino-Esp8266 12E读取SD卡文件,sd-card,esp8266,arduino-esp8266,Sd Card,Esp8266,Arduino Esp8266,我想在ESP8266 12E中执行JSON文件(15.2KB[(15601字节)]的读写操作 Arduino SDK ESP8266 12E SD卡 我可以: 使用HTTPClient编写文件 读取文件并使用以下代码在串行监视器上打印: server.on("/read", []() { myFile = SD.open("commands.txt"); byte thisByte; if (myFile) { while (myFile.available()) {

我想在
ESP8266 12E
中执行
JSON
文件(15.2KB[(15601字节)]的读写操作

  • Arduino SDK
  • ESP8266 12E
  • SD卡
  • 我可以:

  • 使用
    HTTPClient
    编写文件
  • 读取文件并使用以下代码在
    串行
    监视器上打印:

    server.on("/read", []() {
    myFile = SD.open("commands.txt");
    
    byte thisByte;      
    if (myFile) {
        while (myFile.available()) {
            thisByte = myFile.read();
            Serial.write(thisByte);
        }
    }
    
    myFile.close();
    server.send(200, "text/html", "File read Success.");
    });
    
  • 我运行了
    /read
    30到40次,运行良好,没有任何错误或ESP的
    WDT
    软重置

    我不能:

  • 读取
    字符串
    变量中的文件。代码为

    server.on("/read", []() {
    myFile = SD.open("commands.txt");
    
    String line = "";               
    if (myFile) {
        while (myFile.available()) {                
            line = myFile.readString();             
        }
    }
    
    Serial.println(line);
    
    myFile.close();
    server.send(200, "text/html", "File read Success.");
    });
    
  • 经过一些
    /read
    和/或
    /write
    之后,然后
    /read
    ESP复位

    Soft WDT reset
    
    ctx: cont 
    sp: 3fff0da0 end: 3fff10d0 offset: 01b0
    
    
    3fff0f50:  00004e00 3fff0fb0 3fff0fb0 402095c3  
    3fff0f60:  3fff0054 00004b73 3fff810f 4020a758  
    3fff0f70:  00000001 3ffe9320 3fff0fd4 40206c54  
    3fff0f80:  00000001 3ffe9320 3fff0074 4020a789  
    3fff0f90:  00000001 3ffe9320 3fff0fd4 402092b9  
    3fff0fa0:  00000001 3ffe9320 3ffefbac 4020245e  
    3fff0fb0:  00000000 00000000 00000000 402095c3  
    3fff0fc0:  6d6d6f63 73646e61 7478742e 40209600  
    3fff0fd0:  3fff2d3c 00000000 00000000 00000000  
    3fff0fe0:  3fff359c 00004dff 00004df1 4010068c  
    3fff0ff0:  00000000 00000001 3fff27dc 40206c4a  
    3fff1000:  3fff27dc 3ffef308 3fff27dc 40206c86  
    3fff1010:  00000000 00000000 00000000 40209770  
    3fff1020:  3fff27dc 3ffef308 3ffef2c8 40206d19  
    3fff1030:  3fff2d24 0000000f 00000005 40205b14  
    3fff1040:  00000000 00000000 00000000 0000000f  
    3fff1050:  00000001 3fff00a0 4020a114 3fff00b0  
    3fff1060:  00000000 00000000 3ffef2c8 3fff00a0  
    3fff1070:  00000001 3ffef2ec 3ffef2c8 40206f04  
    3fff1080:  3ffe8d68 00000000 00001388 3fff00b0  
    3fff1090:  00000000 3fff2c84 000003e8 3fff00a0  
    3fff10a0:  3fffdad0 00000000 3fff0098 40202367  
    3fff10b0:  3fffdad0 00000000 3fff0098 4020a160  
    3fff10c0:  feefeffe feefeffe 3fff00b0 4010070c  
    ets Jan  8 2013,rst cause:2, boot mode:(3,6)  
    load 0x4010f000, len 1384, room 16 
    
    我想将文件数据存储在
    字符串中
    变量中,然后逐行处理它

    完整代码如下:

    #include <Arduino.h>
    #include <SPI.h>
    #include <SD.h>
    #include <ESP8266WiFi.h>
    #include <ESP8266WiFiMulti.h>
    #include <ESP8266WebServer.h>
    #include <ESP8266HTTPClient.h>
    
    
    IPAddress ip(192, 168, 1, 81);         // choose IP address
    IPAddress subnet(255, 255, 255, 0);
    
    ESP8266WiFiMulti WiFiMulti;
    File myFile;
    
    ESP8266WebServer server(80);
    
    //06519942-652e-11e7-907b-a6006ad3dba0
    
    // SSID, PASSWORD
    const char *ssid = "06519942-652e-11e7-907b-a";
    const char *password = "password";
    
    void setup() {
    
        Serial.begin(115200);                      // so you can see debug messages automatically sent by ESP8266
        WiFi.mode(WIFI_AP);
        WiFi.softAPConfig(ip, ip, subnet);        // declared as: bool softAPConfig (IPAddress local_ip, IPAddress gateway, IPAddress subnet)
        WiFi.softAP(ssid, password, 7, 0, 1);  // network name, network password, wifi channel
    
        IPAddress myIP = WiFi.softAPIP();
        Serial.println();
        Serial.print("AP IP address: ");
        Serial.println(myIP);
        delay(1000);
    
        // Serial.setDebugOutput(true);
    
        Serial.print("Initializing SD card...");
        if (!SD.begin(16)) {
            Serial.println("initialization failed!");
            return;
        }
        Serial.println("initialization done.");
    
        Serial.println();
        Serial.println();
        Serial.println();
    
        for (uint8_t t = 4; t > 0; t--) {
            Serial.printf("[SETUP] WAIT %d...\n", t);
            Serial.flush();
            delay(1000);
        }
    
    
        WiFiMulti.addAP("SSID", "PASSWORD"); // Change it with yours
        delay(1000);
    
        server.on("/", []() {
            server.send(200, "text/html", "Welcome");
        });
    
        server.on("/read", []() {
            myFile = SD.open("commands.txt");
    
            byte thisByte;      
            if (myFile) {
                while (myFile.available()) {
                    thisByte = myFile.read();               
                    Serial.write(thisByte);
                }
            }
    
    
    
            myFile.close();
            server.send(200, "text/html", "File read Success.");
        });
    
        server.on("/write", []() {
            HTTPClient http;
    
            Serial.print("[HTTP] begin...\n");
    
            if (SD.exists("commands.txt")) {
                SD.remove("commands.txt");
                Serial.println("commands.txt removed.");
            }
    
            // configure server and url
            http.begin("http://controlxapi.azurewebsites.net/download");
    
            Serial.print("[HTTP] GET...\n");
    
            // start connection and send HTTP header
            int httpCode = http.GET();
    
            if (httpCode > 0) {
                // HTTP header has been send and Server response header has been handled
                Serial.printf("[HTTP] GET... code: %d\n", httpCode);
    
                // file found at server
                if (httpCode == HTTP_CODE_OK) {
    
                    Serial.println("Creating commands.txt...");
                    myFile = SD.open("commands.txt", FILE_WRITE);
    
                    // get lenght of document (is -1 when Server sends no Content-Length header)
                    int len = http.getSize();
                    Serial.println(len);
    
                    // create buffer for read
                    uint8_t buff[128] = { 0 };
    
                    // get tcp stream
                    WiFiClient * stream = http.getStreamPtr();
    
                    // read all data from server
                    while (http.connected() && (len > 0 || len == -1)) {
                        // get available data size
                        size_t size = stream->available();
    
                        if (size) {
                            // read up to 128 byte
                            int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size));
    
                            // write it to Serial
                            //Serial.write(buff, c);
                            myFile.write(buff, c);
    
                            if (len > 0) {
                                len -= c;
                            }
                        }
                        delay(1);
                    }
                    stream->flush();
                    myFile.close();
                    Serial.println();
                    Serial.print("[HTTP] connection closed. File write end.\n");
    
                }
            }
            else {
                Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
            }
    
            http.end();
            http.~HTTPClient();
            server.send(200, "text/html", "File write Success.");
        });
    
        //Start the server
        server.begin();
        Serial.println("HTTP server(local) started");
    }
    
    void loop() {
        server.handleClient();
        //delay(100);
        if (WiFiMulti.run() != WL_CONNECTED) {
            Serial.print(".");
            delay(1000);
        }
        else {
    
        }
    }
    
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    ip地址ip(192、168、1、81);//选择ip地址
    IP地址子网(255、255、255、0);
    ESP8266WiFiMulti WiFiMulti;
    文件myFile;
    ESP8266Web服务器(80);
    //06519942-652e-11e7-907b-a6006ad3dba0
    //密码
    const char*ssid=“06519942-652e-11e7-907b-a”;
    const char*password=“password”;
    无效设置(){
    Serial.begin(115200);//因此您可以看到ESP8266自动发送的调试消息
    WiFi.模式(WiFi\u AP);
    WiFi.softAPConfig(ip,ip,子网);//声明为:bool softAPConfig(IPAddress local_ip,IPAddress gateway,IPAddress子网)
    softAP(ssid,密码,7,0,1);//网络名称,网络密码,WiFi频道
    IPAddress myIP=WiFi.softAPIP();
    Serial.println();
    串行打印(“AP IP地址:”);
    序列号println(myIP);
    延迟(1000);
    //Serial.setDebugOutput(true);
    串行打印(“初始化SD卡…”);
    如果(!SD.begin(16)){
    Serial.println(“初始化失败!”);
    返回;
    }
    Serial.println(“初始化完成”);
    Serial.println();
    Serial.println();
    Serial.println();
    对于(uint8_t=4;t>0;t--){
    Serial.printf(“[设置]等待%d..\n”,t);
    Serial.flush();
    延迟(1000);
    }
    WiFiMulti.addAP(“SSID”,“PASSWORD”);//用您的更改它
    延迟(1000);
    服务器。在(“/”,[](){
    send(200,“text/html”,“Welcome”);
    });
    在(“/read”上,[](){
    myFile=SD.open(“commands.txt”);
    字节这个字节;
    如果(我的文件){
    while(myFile.available()){
    thisByte=myFile.read();
    串行写入(thisByte);
    }
    }
    myFile.close();
    send(200,“text/html”,“文件读取成功”);
    });
    在(“/write”,[](){
    HTTPClient-http;
    Serial.print(“[HTTP]begin…\n”);
    如果(SD.exists(“commands.txt”)){
    SD.remove(“commands.txt”);
    Serial.println(“commands.txt已删除”);
    }
    //配置服务器和url
    http.begin(“http://controlxapi.azurewebsites.net/download");
    Serial.print(“[HTTP]GET…\n”);
    //启动连接并发送HTTP头
    int httpCode=http.GET();
    如果(httpCode>0){
    //HTTP标头已发送,服务器响应标头已处理
    Serial.printf(“[HTTP]获取…代码:%d\n”,httpCode);
    //在服务器上找到文件
    如果(httpCode==HTTP\u代码\u确定){
    Serial.println(“Creating commands.txt…”);
    myFile=SD.open(“commands.txt”,FILE\u WRITE);
    //获取文档长度(当服务器不发送内容长度标头时为-1)
    int len=http.getSize();
    序列号println(len);
    //为读取创建缓冲区
    uint8_t buff[128]={0};
    //获取tcp流
    WiFiClient*stream=http.getStreamPtr();
    //从服务器读取所有数据
    而(http.connected()&&(len>0 | | len==-1)){
    //获取可用数据大小
    size\u t size=stream->available();
    如果(尺寸){
    //最多可读取128字节
    intc=stream->readBytes(buff,((size>sizeof(buff))?sizeof(buff):size));
    //把它写进串口
    //串行写入(buff,c);
    myFile.write(buff,c);
    如果(len>0){
    len-=c;
    }
    }
    延迟(1);
    }
    流->刷新();
    myFile.close();
    Serial.println();
    Serial.print(“[HTTP]连接已关闭。文件写入结束。\n”);
    }
    }
    否则{
    Serial.printf(“[HTTP]GET…失败,错误:%s\n”,HTTP.errorToString(httpCode.c_str());
    }
    http.end();
    http.~HTTPClient();
    send(200,“text/html”,“文件写入成功”);
    });
    //启动服务器
    server.begin();
    Serial.println(“HTTP服务器(本地)已启动”);
    }
    void循环(){
    server.handleClient();
    //延迟(100);
    如果(WiFiMulti.run()!=WL_已连接){
    连续打印(“.”);
    延迟(1000);
    }
    否则{
    }
    }
    
    问题的根源在于阅读

    String line = "";
    
    永远不要使用字符串类来获得可靠的性能。 原因-这会刺穿堆并导致内存泄漏->崩溃和重置

    要阅读以html、js、bmp等形式发送到浏览器,请使用以下命令:

     const char* path = "\myfolder\myfile.html";
    
     FILE_SYSTEM can be either SD, SPIFFS, LittleFS
    
     File dataFile = FILE_SYSTEM.open(path, "r");
      ... do all sorts of checking if needed
     // e.g. contentType = F("text/html"); -> determined by a function analysing the  
     file extension 
    
     if (server.streamFile(dataFile, contentType) != dataFile.size()) {
    }       // sends the file tothe browser
    
    只需下载到PC机即可

     contentType = F("application/octet-stream")
    
    Avr开发的一个技巧。摆脱String类,坚持使用c-char数组。开始很难,但最终会有所收获