首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使服务器能够使用arduino for ESP32 WebServer自动下载文件,而无需使用SPIFFS,而可以使用SDcard文件

如何使服务器能够使用arduino for ESP32 WebServer自动下载文件,而无需使用SPIFFS,而可以使用SDcard文件
EN

Stack Overflow用户
提问于 2019-11-21 07:22:22
回答 2查看 3.5K关注 0票数 0
代码语言:javascript
运行
复制
#include <WiFiClient.h>
#include <WebServer.h>
#include <WiFi.h>
#include <ESPmDNS.h>
#include <SPI.h>
#include <SD.h>


String serverIndex = "<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>"
"<form method='POST' action='#' enctype='multipart/form-data' id='upload_form'>"
    "<input type='file' name='update'>"
    "<input type='submit' value='Upload'>"
"</form>"
"<div id='prg'>progress: 0%</div>"
"<script>"
"$('form').submit(function(e){"
    "e.preventDefault();"
      "var form = $('#upload_form')[0];"
      "var data = new FormData(form);"
      " $.ajax({"
            "url: '/update',"
            "type: 'POST',"               
            "data: data,"
            "contentType: false,"                  
            "processData:false,"  
            "xhr: function() {"
                "var xhr = new window.XMLHttpRequest();"
                "xhr.upload.addEventListener('progress', function(evt) {"
                    "if (evt.lengthComputable) {"
                        "var per = evt.loaded / evt.total;"
                        "$('#prg').html('progress: ' + Math.round(per*100) + '%');"
                    "}"
               "}, false);"
               "return xhr;"
            "},"                                
            "success:function(d, s) {"    
                "console.log('success!')"
           "},"
            "error: function (a, b, c) {"
            "}"
          "});"
"});"
"</script>";

const char* ssid = "Entrib-Main";
const char* password = "shopWorx110T";

WebServer server(80);
File root;
bool opened = false;

String printDirectory(File dir, int numTabs) {
  String response = "";
  dir.rewindDirectory();

  while(true) {
     File entry =  dir.openNextFile();
     if (! entry) {
       // no more files
       //Serial.println("**nomorefiles**");
       break;
     }
     for (uint8_t i=0; i<numTabs; i++) {
       Serial.print('\t');   // we'll have a nice indentation
     }
     // Recurse for directories, otherwise print the file size
     if (entry.isDirectory()) {
       printDirectory(entry, numTabs+1);
     } else {
       response += String("<a href='") + String(entry.name()) + String("'>") + String(entry.name()) + String("</a>") + String("</br>");
     }
     entry.close();
   }
   return String("List files:</br>") + response + String("</br></br> Upload file:") + serverIndex;
}

void handleRoot() {

  root = SD.open("/");
  String res = printDirectory(root, 0);
  server.send(200, "text/html", res);
}


bool loadFromSDCARD(String path){
  path.toLowerCase();
  String dataType = "text/plain";
  if(path.endsWith("/")) path += "index.htm";

  if(path.endsWith(".src")) path = path.substring(0, path.lastIndexOf("."));
  else if(path.endsWith(".jpg")) dataType = "image/jpeg";
  else if(path.endsWith(".txt")) dataType = "text/plain";
  else if(path.endsWith(".zip")) dataType = "application/zip";  
  else if(path.endsWith(".bin")) dataType = "text/plain"; 
  Serial.println(dataType);
  File dataFile = SD.open(path.c_str());

  if (!dataFile)
    return false;

  if (server.streamFile(dataFile, dataType) != dataFile.size()) {
    Serial.println("Sent less data than expected!");
  }

  dataFile.close();
  return true;
}

void handleNotFound(){

  if(loadFromSDCARD(server.uri())) return;
  String message = "SDCARD Not Detected\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET)?"GET":"POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i=0; i<server.args(); i++){
    message += " NAME:"+server.argName(i) + "\n VALUE:" + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
  Serial.println(message);
}

void setup(void){
  SPI.begin(14, 2, 15, 13);
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  //use IP or iotsharing.local to access webserver
  if (MDNS.begin("iotsharing")) {
    Serial.println("MDNS responder started");
  }
  if (!SD.begin()) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  //handle uri  
  server.on("/", handleRoot);
  server.onNotFound(handleNotFound);




  /*handling uploading file */
  server.on("/update", HTTP_POST, [](){
    server.sendHeader("Connection", "close");
  },[](){
    HTTPUpload& upload = server.upload();
    if(opened == false){
      opened = true;
      root = SD.open((String("/") + upload.filename).c_str(), FILE_WRITE);  
      if(!root){
        Serial.println("- failed to open file for writing");
        return;
      }
    } 
    if(upload.status == UPLOAD_FILE_WRITE){
      if(root.write(upload.buf, upload.currentSize) != upload.currentSize){
        Serial.println("- failed to write");
        return;
      }
    } else if(upload.status == UPLOAD_FILE_END){
      root.close();
      Serial.println("UPLOAD_FILE_END");
      opened = false;
    }
  });
  server.begin();
  Serial.println("HTTP server started");
}

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

这是一个工作代码,用于从ESP32 TTGO T1模块获取sd卡数据,并显示sd卡目录上的所有文件,并在单击文件名后下载该文件。但是,当我试图修改代码以使服务器能够自动下载SD卡文件时,不需要单击文件名,它就无法工作。我也尝试过用SD替换异步web服务器代码中的,但是它并没有在服务器上提供任何输出。

我已经为AsyncWebServer附加了代码,下面的代码可以很好地工作在SPIFFS中,但是没有使用SD

代码语言:javascript
运行
复制
#include "WiFi.h"
#include "SPIFFS.h"
#include "ESPAsyncWebServer.h"
#include "SPI.h"
#include "SD.h"

const char* ssid = "Entrib-Main";
const char* password =  "shopWorx110T";

AsyncWebServer server(80);
File root;
String serverIndex = "<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>"
"<form method='POST' action='#' enctype='multipart/form-data' id='upload_form'>"
    "<input type='file' name='update'>"
    "<input type='submit' value='Upload'>"
"</form>"
"<div id='prg'>progress: 0%</div>"
"<script>"
"$('form').submit(function(e){"
    "e.preventDefault();"
      "var form = $('#upload_form')[0];"
      "var data = new FormData(form);"
      " $.ajax({"
            "url: '/update',"
            "type: 'POST',"               
            "data: data,"
            "contentType: false,"                  
            "processData:false,"  
            "xhr: function() {"
                "var xhr = new window.XMLHttpRequest();"
                "xhr.upload.addEventListener('progress', function(evt) {"
                    "if (evt.lengthComputable) {"
                        "var per = evt.loaded / evt.total;"
                        "$('#prg').html('progress: ' + Math.round(per*100) + '%');"
                    "}"
               "}, false);"
               "return xhr;"
            "},"                                
            "success:function(d, s) {"    
                "console.log('success!')"
           "},"
            "error: function (a, b, c) {"
            "}"
          "});"
"});"
"</script>";


String printDirectory(File dir, int numTabs) {
  String response = "";
  dir.rewindDirectory();

  while(true) {
     File entry =  dir.openNextFile();
     if (! entry) {
       // no more files
       //Serial.println("**nomorefiles**");
       break;
     }
     for (uint8_t i=0; i<numTabs; i++) {
       Serial.print('\t');   // we'll have a nice indentation
     }
     // Recurse for directories, otherwise print the file size
     if (entry.isDirectory()) {
       printDirectory(entry, numTabs+1);
     } else {
       response += String("<a href='") + String(entry.name()) + String("'>") + String(entry.name()) + String("</a>") + String("</br>");
     }
     entry.close();
   }
   return String("List files:</br>") + response + String("</br></br> Upload file:") + serverIndex;
}

void setup(){
  Serial.begin(115200);
  SPI.begin(14, 2, 15, 13);

  if(!SPIFFS.begin()){
        Serial.println("An Error has occurred while mounting SPIFFS");
        return;
  }

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  Serial.println(WiFi.localIP());

  server.on("/download", HTTP_GET, [](AsyncWebServerRequest *request){
    SPI.begin(14, 2, 15, 13);
    root = SD.open("/");
    String res = printDirectory(root, 0);
    request->send(SD, "/data/sample.bin", "text/html", true);
  });

   root = SD.open("/");
   String res = printDirectory(root, 0);

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
   root = SD.open("/");
   String res = printDirectory(root, 0);
    request->send(200, "text/html", res);
  }); 

  server.begin();
}

void loop(){}

请任何人建议对此代码进行任何更改,以使其能够工作SD卡文件自动下载从服务器或如果您有任何其他工作代码为同一问题,将不胜感激。谢谢:)

EN

回答 2

Stack Overflow用户

发布于 2020-08-11 08:39:52

我不确定它能解决沙洛姆-丹尼尔的问题。

我只是想展示一下如何从连接到esp32的sd卡下载一个名为esp32的文件到客户端。

CS在Esp32上连接到io 5。

在Esp32上,SCK连接到io 18。

MOSI在Esp32上连接到io 23。

MISO与Esp32上的io 19连接。

从SD.end开始可能有点奇怪,但这是我能使它正常工作的唯一方法。

代码语言:javascript
运行
复制
server.on("/download", HTTP_GET, [](AsyncWebServerRequest *request){
    SD.end();
    SD.begin(SD_CS); 
    File file = SD.open("/data.txt");
    if(!SD.begin(SD_CS)) {
        Serial.println("Card Mount Failed");
        request->send (200, "text/html", "<H1>Card Mount Failed</h1>");
    } 
    else if(!file){
        Serial.println("Failed to open file for reading");
        request->send (200, "text/html", "<H1>Failed to open file for reading</h1>");
    }
    else{
        request->send(file, "/data.txt", "text/xhr", true);
        Serial.print("Recieved data.txt request from client IP ");
        Serial.println(request->client()->remoteIP());
    } 
});
票数 1
EN

Stack Overflow用户

发布于 2020-08-07 21:46:06

代码语言:javascript
运行
复制
 // Define CS pin for the SD card module
 #define SD_CS 5  


 server.on("/download", HTTP_GET, [](AsyncWebServerRequest *request){
 SD.begin(SD_CS);  
 if(!SD.begin(SD_CS)) {
 Serial.println("Card Mount Failed");
 logmessage = "Card Mount Failed"; 
 return;
 }  
 File file = SD.open("/data.txt");
 if(!file){
 //Serial.println(" Failed to open file for reading");
 return;
 }
 request->send(file, "/data.txt", "text/xhr", true);
 Serial.print("Recieved data.txt request from client IP ");
 Serial.println(request->client()->remoteIP());
 });
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58969337

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档