Skip to content

ESP32 and very slow SD SPI read/write performance #6338

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
1 task done
simkard69 opened this issue Feb 23, 2022 · 4 comments
Closed
1 task done

ESP32 and very slow SD SPI read/write performance #6338

simkard69 opened this issue Feb 23, 2022 · 4 comments
Labels
Resolution: Duplicate Issue is a duplicate of another issue

Comments

@simkard69
Copy link

simkard69 commented Feb 23, 2022

Board

ESP32 DEV Module

Device Description

Same performance problem with various SD card types and various ESP32 dev modules :

  • simple DEV module (the one with 30 pins)
  • a Lilygo SIM7600

Hardware Configuration

SD SPI card slot connected using the VSPI bus so default SPI in terms of Arduino IDE.
Precisely the following :

SPI MOSI MISO CLK CS
VSPI GPIO 23 GPIO 19 GPIO 18 GPIO 5

Version

v2.0.2

IDE Name

Arduino 1.8.16

Operating System

Windows 10

Flash frequency

80Mhz

PSRAM enabled

no

Upload speed

115200

Description

Very very slow SD SPI performance.

I've tried multiple tests with SPI SD, it ends up the same with very poor SD read/write performances.

  • Test using file.read() and file.write(value) have their bandwidth around 1250bps
  • Test using file.write(BUFFER, LENGTH) and file.read(BUFFER, LENGTH), I get around 5000bps

Tried changing wiring/cables/SD card slot (which has resistors), nothing changes.
Anyway, only the bandwidth is criticaly poor.
Stability seems ok.

Sketch

// uncomment to use SPI. comment to use SD_MMC
#define USE_SPI

#include "math.h"

#include "FS.h"

#ifdef USE_SPI
#include "SD.h"
#include "SPI.h"
#define SD_CARD_FS SD
/*
const int ss_cs = 13;
const int mosi = 15;
const int sck = 14;
const int miso = 2;
*/
const int ss_cs = 5;
#else
#include "SD_MMC.h"
#define SD_CARD_FS SD_MMC
#endif

void testFileIO(fs::FS &fs, const char * path, uint32_t buffSize, uint32_t numMB) {
  uint8_t * buff = new uint8_t[buffSize];

  Serial.println("Card WRITE test");
  
  File file = fs.open(path, FILE_WRITE);
  if (file) {
    size_t i;
    uint32_t start = millis();
    auto numToWrite = (numMB * 1024 * 1024) / buffSize;
    for (i = 0; i < numToWrite; i++) {
      file.write(buff, buffSize);
      yield();
    }
    uint32_t end = millis() - start;
    float kbps = numMB * 1024 * 1024 / end;

    Serial.printf("%u MB written using %d byte buffer for %u ms @ %f KBps\n", numMB, buffSize, end, kbps);
    file.close();
  } else {
    Serial.println("Failed to open file for writing");
  }

  Serial.println("Card READ test");
  file = fs.open(path);
  if (file) {
    uint32_t len = file.size();
    size_t flen = len;
    uint32_t start = millis();
    while (len) {
      size_t toRead = len;
      if (toRead > buffSize) {
        toRead = buffSize;
      }
      file.read(buff, toRead);
      len -= toRead;
    }
    uint32_t end = millis() - start;
    float kbps = numMB * 1024 * 1024 / end;
    Serial.printf("%u MB read using %d byte buffer for %u ms @ %f KBps\n", flen / 1024 / 1024, buffSize, end, kbps);
    file.close();
  } else {
    Serial.println("Failed to open file for reading");
  }

  delete[] buff;
}

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

#ifdef USE_SPI
  //SPI.begin(sck, miso, mosi, ss_cs);
  SPI.begin();
  if (!SD.begin(ss_cs, SPI)) {
    Serial.println("Card Mount Failed");
    return;
  }
#else
  if (!SD_MMC.begin("/sd", true)) {
    Serial.println("Card Mount Failed");
    return;
  }
#endif

  Serial.println("Card Mount Success");
  for (int i = 0; i <= 7; i++) {
    testFileIO(SD_CARD_FS, "/test.txt", 512 * pow(2, i), 2);
  }
}

void loop() {

}

Debug Message

...
[ 83696][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 83798][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 83900][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 84002][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 84104][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 84206][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 84308][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 84410][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 84512][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 84614][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 84716][W][sd_diskio.cpp:174] sdCommand(): no token received
...

Other Steps to Reproduce

It might be due to the SD card slow which has resistors, I'll try to remove them to do some tests.

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@simkard69 simkard69 added the Status: Awaiting triage Issue is waiting for triage label Feb 23, 2022
@mrengineer7777
Copy link
Collaborator

Duplicate of #6295. Should be fixed in arduino-esp32 v2.0.3. See also workarounds in #6295.

@simkard69
Copy link
Author

So basically it is just a "software" related bug ?
What a pain ...
So ok, now I know what is the root cause of my problem, now the question is, as per now, what is the best solution :

  • Using one of the workarounds available in the post you provided
  • Waiting for the v2.0.3 arduino-esp32 ... but when is it planned approximatively for release ?

Thanks

@mrengineer7777
Copy link
Collaborator

I don't use the Arduino IDE, so not sure if you can compile to include the workarounds. If you can target the arduino-esp32 master branch it includes the fixes.

I'm not an Espressif employee so don't know about release date. Based on previous releases I would guess by the end of March.

@simkard69
Copy link
Author

I can report that using the fix mentionned in this link solved my problem for good !
So happy it was not my fault/code haha XDDD

https://github.com/espressif/arduino-esp32/pull/6103/files

@VojtechBartoska VojtechBartoska added Resolution: Duplicate Issue is a duplicate of another issue and removed Status: Awaiting triage Issue is waiting for triage labels Feb 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Duplicate Issue is a duplicate of another issue
Projects
None yet
Development

No branches or pull requests

3 participants