我想从连接到esp32的sd卡上打开一个以字节为单位的。wav文件。我的代码是基于这个问题
我只是想上传一个文件从我的sd卡到服务器,但目前我无法读取文件,尽管文件存在于sd卡:
看这几行代码:
char *fname = "/sdcard/test.wav";
FILE *fp = fopen(fname, "rb"); // read in bytes
if(!fp) {
Serial.println("File doens't exist");
}
我不明白为什么它File File = SD.open("/test. wave ")工作,但上面的代码没有。根据我的参考,我应该以字节为单位读取这个文件,而不是像这样以正常的方式读取=>File File = SD.open("/test. wave ").
我想知道我怎么能看到我的sd卡的完整路径,因为原始代码使用这个:
char *fname = "/sdcard/test_text.txt";
FILE *fp = fopen(fname, "rb");
为什么使用这个路径/sdcard/test_text.txt我不知道确切的。如果我尝试使用:
打开File file = SD.open("/test.wav")
可以工作,但是在此之后的一些代码行会抛出错误,因为文件应该以字节为单位读取。
我想听听你的建议,我将感谢任何解决这个问题的想法。
这是整个代码:
#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);
}
谢谢你。
不幸的是,这不是直截了当的。您可以直接使用SD组件,也可以挂载正确的文件系统驱动程序(通常是用于SD卡的fatf)。要使用fopen,首先需要注册正确的驱动程序,提示可以在这里找到:https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/fatfs.html#using-fatfs-with-vfs-and-sd-cards
我还没有自己尝试过,但神奇的功能似乎是esp_vfs_fat_sdspi_mount
,应该能够使用fopen与SD卡在SPI上。官方文档缺少一个真实的例子,但是您可以在这个帖子中或通过您喜欢的搜索引擎找到一些东西。为了进一步的帮助,你可能想问一个关于arduino的问题。
我在ESP32上使用SD卡(fat32)时遇到了困难。当试图使用
打开我的文件时std::ofstream dataFile("/sdcard/data.json", std::ofstream::out);
它不会创建我的文件。因此sys/stat将给出-1。事实证明,您确实需要为FAT32使用8.3的命名约定。没有"MS windows-magic";这将文件缩写为:sdcard。j ~ 1等。所以请使用正确的文件名。不是"/sdcard/mylomgfilename.exotic_extention"只是一个"/mpoint/12345678.123"文件名类似于"/sdcard/data.txt".