背景:我在SD卡上保存了一个.wav文件。我想使用我的esp32将该文件传输到服务器。我使用节点红色来处理服务器端的活动。
采用的方法:
<代码>H 113使用http post将数据发送到服务器。H 214H 115
如果文件太大,无法在单个缓冲区中发送,则将文件分割,并发送多个http帖子。H 216G 217
问题:我可以成功地发送文本文件。当我试图发送.wav文件时,发送的wave文件的大小会增加,并且该文件已损坏。分析这个文件是很困难的,因为它不是所有的文本,我所做的就是在notepad++中打开这个文件,看看我是否能发现任何东西。理论上一切都应该是一样的,但是有几个字符在传输的文件中作为空白方格出现,而一些字符则是完全相同的。
Analysis/Theory:
我完全不知道这是什么问题。我的主要理论是用int16_t编写波形文件,但是为了发布需要的数据* uint8_t,也许当int16转换为uint8数据丢失时,我试图将int16_t转换成两个int8_t字节,就像https://stackoverflow.com/a/53374797/14050333做的那样,但是没有运气,也许我是在下结论。任何帮助都将是非常感谢的!
代码:
用于销售文本文件的完整代码。
void loop()
{
WiFiClient client;
Serial.println("starting file upload");
IPAddress host(192, 168, 0, 37);
int port = 1880;
if (!client.connect(host, port))
{ // check connection to host if untrue internet connection could be down
Serial.println("couldn't connect to host");
}
HTTPClient http;
const char* serverName = "http://192.168.0.37:1880/sensor_file";
http.begin(client, serverName);
char *fname = "/sdcard/test_text.txt";
FILE *fp = fopen(fname, "rb"); // read in bytes
//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", "test file"); //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;
char buff2[remainder+1] = {};
fread(buff2, sizeof(buff2)-1, 1, fp); //read from file and store to buff2
http.addHeader("File_name", "test file");
int httpResponseCode = http.POST((uint8_t *)buff2, sizeof(buff2)-1); //send buff2 to server
}
http.end(); // Close connection
delay(10 * 1000);
}
对.wav文件进行调整
int remainder = file_size - num_of_uploads * max_upload_size;
int16_t buff2[remainder+1] = {};
fread(buff2, sizeof(buff2)-1, 1, fp); //remainder
http.addHeader("File_name", "test file");
int httpResponseCode = http.POST((uint8_t *)buff2, sizeof(buff2)-1);
发布于 2021-11-12 23:56:33
起作用了!
如堆运行所述,代码中有两个主要问题。第一个问题是,我在wav文件中读取的是int16_t,正确的数据类型是uint8_t。
为什么要使用int16 16_t类型元素数组作为缓冲区?您正在以二进制模式读取文件,所以不管是.wav、.jpg、.ttf还是其他任何东西,它都只是一个字节序列(uint8_t,而不是int16_t)。另一件事是,fread()期望读取每个对象的大小作为第二个参数,将读取的对象数目作为第三个参数,因此,在对象为字节的情况下,首先将缓冲区定义为uint8_t buff1max_upload_size = {};(不需要+1/-1游戏),然后定义为fread( buff1,size of *buff1,size of buff1/size of *buff1,fp)。buff2也是如此。-堆下运行
第二个问题是,我没有在post流中包含指定内容类型的头。因为它不是文本文件所需要的,所以当以节点红色编写文件时,它允许您选择编码。我不认为我会需要它,但事实证明,我需要补充:
http.addHeader("Content-Type", "application/octet-stream");
以下是文件上传部分的工作代码:
if (num_of_uploads > 0)
{
uint8_t buff1[max_upload_size] = {};
for (i = 0; i < num_of_uploads; i++)
{
fread(buff1, sizeof *buff1, sizeof buff1 / sizeof *buff1, fp);
http.addHeader("File_name", "test file"); //header to say what the file name is
http.addHeader("Content-Type", "application/octet-stream");
int httpResponseCode = http.POST(buff1, sizeof(buff1));
}
}
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", "test file");
http.addHeader("Content-Type", "application/octet-stream");
int httpResponseCode = http.POST(buff2, sizeof(buff2));
}
出于好奇,我试着运行上面的代码,但是
uint16_t buff1[max_upload_size] = {};
和
http.POST((uint8_t) buff1, sizeof(buff2));
该文件上传,但大小是它应该是2倍,奇怪的是,但该文件没有损坏,并播放音频,因为它被记录。只是觉得挺有意思的。
当原来的问题成功回答后,我将结束这个答案。再次感谢你的帮助,我已经在这几个星期,你解决了我的问题在几个小时!
https://stackoverflow.com/questions/69936775
复制相似问题