简体   繁体   English

无法从 SD 卡 (ESP32) 以字节为单位打开文件

[英]Unable to open file in bytes from sd card (ESP32)

I want to open a.wav file in bytes from the sd card connected to esp32.我想从连接到 esp32 的 sd 卡中以字节为单位打开 a.wav 文件。 My code is based in this question我的代码基于这个问题

I just want upload a file from my sd card to a server but by the moment I can't read the file despites the file exists in the sd card:我只想将文件从我的 sd 卡上传到服务器,但尽管文件存在于 sd 卡中,但此刻我无法读取该文件:

Look this lines of code:看这行代码:

 char *fname = "/sdcard/test.wav";
  FILE *fp = fopen(fname, "rb"); // read in bytes
   
  if(!fp) {
    Serial.println("File doens't exist");
  }

I don't understand why it File file = SD.open("/test.wav") works but the above code not.我不明白为什么 File file = SD.open("/test.wav") 有效但上面的代码无效。 According to my reference I should read this file in bytes and not in a normal manner like this => File file = SD.open("/test.wav").根据我的参考,我应该以字节为单位读取这个文件,而不是像这样以正常方式读取 => File file = SD.open("/test.wav")。

I would like know how I can see the full path of my sd card because the original code uses this:我想知道如何查看我的 SD 卡的完整路径,因为原始代码使用了这个:

char *fname = "/sdcard/test_text.txt";
  FILE *fp = fopen(fname, "rb"); 

why that uses this path /sdcard/test_text.txt I don't know exactly.为什么使用这条路径 /sdcard/test_text.txt 我不太清楚。 If I try to open by using:如果我尝试使用以下方式打开:

File file = SD.open("/test.wav") 

will works but some lines of code after this will throws errors because the file should be read in bytes.会工作,但之后的一些代码行会抛出错误,因为文件应该以字节为单位读取。

I would like to see your advices guys I will appreciate any idea to fix this problem.我想看看你们的建议,我将不胜感激解决此问题的任何想法。

this is the entire code:这是完整的代码:

#include "Arduino.h"
#include "WiFi.h"
#include "SD.h"
#include "FS.h"
#include "HTTPClient.h"
//SD CARD MODULE
#define SD_CS          5
#define SPI_MOSI      23
#define SPI_MISO      19
#define SPI_SCK       18

// Wifi Credentials
const char* ssid     = "XXX";
const char* password = "XXX";

void setup() {
  Serial.begin(115200);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("MY IP address: ");
  Serial.println(WiFi.localIP());

  
  if (!SD.begin(SD_CS)) {
    Serial.println("SD init failed!");
    return;
  }
   Serial.println("SD init successfull!");

  
}

void loop()
{
  WiFiClient client;
  Serial.println("starting file upload");
  IPAddress host(192, 168, 18, 8); //server ip
  int port = 80;
  if (!client.connect(host, port))
  { // check connection to host if untrue internet connection could be down
    Serial.println("couldn't connect to host");
  }
  Serial.println("Connect to host!");

  HTTPClient http;
  const char* serverName = "http://192.168.18.8/upload/upload.php";
  http.begin(client, serverName);

  char *fname = "/sdcard/test.wav";
  FILE *fp = fopen(fname, "rb"); // read in bytes
   
  if(!fp) {
    Serial.println("File doens't exist");
  }

  //get file size
  fseek(fp, 0, SEEK_END); //send file pointer to end of file 
  int file_size = ftell(fp); //get end position of file
  fseek(fp, 0, SEEK_SET); //send pointer back to start

  int max_upload_size = 10; // array size, larger = less uploads but too large can cause memory issues
  int num_of_uploads = file_size / max_upload_size; // figure out how many evenly sized upload chunks we need
  int num_of_uploads_mod = file_size % max_upload_size; //find out size of remaining upload chunk if needed
  int i;
  //upload file in even chunks    
  if (num_of_uploads > 0)
  {
    char buff1[max_upload_size+1] = {}; // array to save file too. add 1 for end of array symbol '\n'
    for (i = 0; i < num_of_uploads; i++)
    {
      fread(buff1, sizeof(buff1)-1, 1, fp); // -1 as don't want to count the '\n'
      http.addHeader("file_name", "file_name"); //header to say what the file name is
      int httpResponseCode = http.POST((uint8_t *)buff1, sizeof(buff1)-1); //send data. Datatype is (uint8_t *)
    }
  }
  //upload any remaining data
  if (num_of_uploads_mod > 0)
  {
    int remainder = file_size - num_of_uploads * max_upload_size;
    uint8_t buff2[remainder] = {};
    fread(buff2, sizeof *buff2, sizeof buff2 / sizeof *buff2, fp);
    http.addHeader("file_name", "file_name");
    http.addHeader("Content-Type", "application/octet-stream");
    int httpResponseCode = http.POST(buff2, sizeof(buff2));
  }
  http.end(); // Close connection
  delay(10 * 1000);
} 

thanks so much.非常感谢。

Unfortunately, this isn't straight-forward.不幸的是,这不是直截了当的。 You can either use the SD component directly or mount the correct file system driver (typically FatFs for an SD card).您可以直接使用 SD 组件或安装正确的文件系统驱动程序(通常是用于 SD 卡的 FatFs)。 To use fopen, you need to register the correct driver first, hints can be found here: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/fatfs.html#using-fatfs-with-vfs-and-sd-cards要使用 fopen,您需要先注册正确的驱动程序,提示可以在这里找到: https ://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/fatfs.html #using-fatfs-with-vfs-and-sd-cards

I haven't tried this myself yet, but the magic function seems to be esp_vfs_fat_sdspi_mount that should enable the use of fopen with the SD card over SPI.我自己还没有尝试过,但神奇的功能似乎是esp_vfs_fat_sdspi_mount应该可以通过 SPI 将 fopen 与 SD 卡一起使用。 The official documentation lacks a real-world example, but you might find something in this thread or via your preferred search engine.官方文档缺少真实示例,但您可以在此线程中或通过您首选的搜索引擎找到一些内容。 For further help, you might want to ask a question on arduino.se instead, where a number of experienced ESP32 experts are present.如需进一步帮助,您可能想在arduino.se上提问,那里有许多经验丰富的 ESP32 专家。

I struggled myself with using SD Cards (fat32) on my ESP32.我在 ESP32 上使用 SD 卡 (fat32) 时遇到了困难。 When trying to open my file using尝试使用打开我的文件时

std::ofstream dataFile("/sdcard/data.json", std::ofstream::out);

It wouldn't create my file.它不会创建我的文件。 a sys/stat would thus give a -1.因此,sys/stat 会给出 -1。 Turned out that you really need to use the 8.3 naming convention for FAT32.事实证明,您确实需要对 FAT32 使用 8.3 命名约定。 There's no "MS windows-magic" That abbreviates the file to: sdcard.j~1 etc. So just use a correct file name.没有将文件缩写为:sdcard.j~1 等的“MS windows-magic”。所以只需使用正确的文件名。 not "/sdcard/mylomgfilename.exotic_extention" but just a "/mpoint/12345678.123" filename like "/sdcard/data.txt".不是“/sdcard/mylomgfilename.exotic_extention”,而是像“/sdcard/data.txt”这样的“/mpoint/12345678.123”文件名。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM