esp-iot-solution
esp-iot-solution copied to clipboard
writing to an SD card U1 - takes just block of 4 bit at 20MHz (AEGHB-56)
Environment
-
Development Kit: [none]
-
Module or chip used: [ESP32-WROOM-32]
-
IDF version (run
git describe --tags
to find it): // v4.2.4-182-g30af2e87f5 -
Build System: [CMake]
-
Operating System: [Windows]
-
Power Supply: [Battery]
SD Card (SD (UHS-1 class) Latency writings
Hi all, I have a web server running on a custom board with ESP32 and a OV2640 camera. I can stream correctly and take snapshot but when I get, from a JS code ,an image of about 200KB via HTTP and I have to save the image in the SD card, I see it has latency. I see by de-queuing at 4 bit at time from my http handler (see below) the image correctly at about 20Mhz (host.max_freq_khz = 200000;) but if I de-queue 512 byte at time in order to increase the writing speed I have wrong and bad images ; so im forced to lower the frequency in order to use larger block . Nothing change lets say because 20Mhz at 4 bit is similar to 5MHz to 512 after some tests. I'm using AP mode to connect via HTTTP client (browser).
The customer wants to speed up the saving process. Since different handler are served by the http server and 2 task are running also in parallel , I moved the function to a super highest prioroty task (priority to 20) by coping the httpd_req_t struct into a global struct but nothing change: same behaviour. To be sure it wasnt a network TCP issue I bypassed the saving and redirected the "200KB" image to a python app on a PC by using a TCP socket : the image is great. So it seems to me SDMMC driver is not working properly maybe because i have an old version of ESP-IDF? Please consider my connection with SD is 1-line mode. Hope in your support, thanks a lot.
Code to reproduce this issue
// char* buf;
// size_t buf_len;
// char var[32] = {0,};
// buf_len = httpd_req_get_url_query_len(req) + 1;
// if (buf_len > 1) {
// buf = (char*)malloc(buf_len);
// if(!buf){
// isUpdating = false;
// httpd_resp_send_500(req);
// return ESP_FAIL;
// }
// if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) {
// if (httpd_query_key_value(buf, "image", var, sizeof(var)) == ESP_OK ) {
// if (DEBUG) printf("Image upload\n");
// //upload an image
// int ret, remaining = req->content_len;
// bool imgCaptured = false;
// char sdFileName[128];
// sprintf(sdFileName, "%s/%i.jpg", snapshotFolder, currentUser.nrOfSnapshots);
// if (DEBUG) printf("Saving %s...\n", sdFileName);
// FILE* f = fopen(sdFileName, "w");
// if (DEBUG) printf("Size: %i\n", remaining);
// //char body[512];
// char* body;
// body = (char*)malloc(512);
// while (remaining > 0) {
// /* Read the data for the request */
// if ((ret = **httpd_req_recv**(req, body,
// **MIN(remaining, 512)**)) <= 0) {
// if (ret == HTTPD_SOCK_ERR_TIMEOUT) {
// /* Retry receiving if timeout occurred */
// continue;
// }
// isUpdating = false;
// return ESP_FAIL;
// }
// if (f == NULL) {
// if (DEBUG) printf("Failed to open file for writing\n");
// imgCaptured = false;
// }else{
// if (fwrite(body, sizeof(uint8_t), **MIN(remaining, 512**), f) < **MIN(remaining, 512**))
// imgCaptured = false;
// else
// imgCaptured = true;
// }
// remaining -= ret;
// }
// fclose(f);
// if (imgCaptured) {
// if (DEBUG) printf("Image saved, updating xml\n");
// if (addSnapshot()) ledOkMsg();
// }else{
// ledErrorMsg(SD_ERROR);
// }
// } else {
// isUpdating = false;
// httpd_resp_send_404(req);
// return ESP_FAIL;
// }
// } else {
// isUpdating = false;
// httpd_resp_send_404(req);
// return ESP_FAIL;
// }
// free(buf);
// } else {
// isUpdating = false;
// httpd_resp_send_404(req);
// return ESP_FAIL;
// }
// httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
// httpd_resp_set_hdr(req, "Cache-Control", "no-store, max-age=0");
// httpd_resp_set_type(req, "text/html");
// return httpd_resp_send(req, "OK", strlen("OK"));
Hi @NCKGWT , we recommend you first test your SD card independently using the example, to see what the actual write speed is.
Hi @NCKGWT, it sounds like your issue is in ESP-IDF, not in esp-iot-solution. You may have better luck there.
Some pointers to investigate though, having spent far too long troubleshooting SD stuff in my own projects:
the max_freq_khz doesn't set the SD card frequency very sensibly - it uses the next lowest/equal value from SDMMC_FREQ_52M
(52MHz), SDMMC_FREQ_HIGHSPEED
(40MHz), SDMMC_FREQ_26M
(26MHz), SDMMC_FREQ_DEFAULT
(20MHz), and SDMMC_FREQ_PROBING
(400kHz).
If you set the max_freq_khz frequency to anything below 20Mhz, it will end up running at 400kHz. This is located in esp-idf/components/sdmmc/sdmmc_common.c
This behaviour is supposed to have been improved in IDF v5.0 (https://docs.espressif.com/projects/esp-idf/en/v5.0.1/esp32/migration-guides/release-5.x/storage.html#sdmmc-sdspi)
You could try adjusting sdmmc_init_host_frequency()
to add an intermediate clock rate at 5 or 10 MHz.