проблема инициализации micro SD на ESP32-DevKitC V4

Ivan_X

✩✩✩✩✩✩✩
11 Ноя 2025
11
0
Здравствуйте! У меня не получается запустить micro SD на ESP32, я уже пробовал 2 карты, но так и не запустилось. Карт-ридер подключен к базовым пинам VSPI, Использовал код с примера библиотеки SD (SDtest), даже немного дорабатывал его, ставил в ArduinoIDE ESP32 Dev module и ESP32_WROOM_DA, ничего не поменялось) Использовал абсолютно новый карт-ридер, популярный на aliexpress, синий, такой длинный, не знаю как объяснить:) Кто возможно сталкивался с подобным, подскажите пожалуйста возможные решения проблемы. Вот код который я использовал:

C++:
/*
 * pin 1 - not used          |  Micro SD card     |
 * pin 2 - CS (SS)           |                   /
 * pin 3 - DI (MOSI)         |                  |__
 * pin 4 - VDD (3.3V)        |                    |
 * pin 5 - SCK (SCLK)        | 8 7 6 5 4 3 2 1   /
 * pin 6 - VSS (GND)         | ▄ ▄ ▄ ▄ ▄ ▄ ▄ ▄  /
 * pin 7 - DO (MISO)         | ▀ ▀ █ ▀ █ ▀ ▀ ▀ |
 * pin 8 - not used          |_________________|
 *                             ║ ║ ║ ║ ║ ║ ║ ║
 *                     ╔═══════╝ ║ ║ ║ ║ ║ ║ ╚═════════╗
 *                     ║         ║ ║ ║ ║ ║ ╚══════╗    ║
 *                     ║   ╔═════╝ ║ ║ ║ ╚═════╗  ║    ║
 * Connections for     ║   ║   ╔═══╩═║═║═══╗   ║  ║    ║
 * full-sized          ║   ║   ║   ╔═╝ ║   ║   ║  ║    ║
 * SD card             ║   ║   ║   ║   ║   ║   ║  ║    ║
 * Pin name         |  -  DO  VSS SCK VDD VSS DI CS    -  |
 * SD pin number    |  8   7   6   5   4   3   2   1   9 /
 *                  |                                  █/
 *                  |__▍___▊___█___█___█___█___█___█___/
 *
 * Note:  The SPI pins can be manually configured by using `SPI.begin(sck, miso, mosi, cs).`
 *        Alternatively, you can change the CS pin and use the other default settings by using `SD.begin(cs)`.
 *
 * +--------------+---------+-------+----------+----------+----------+----------+----------+
 * | SPI Pin Name | ESP8266 | ESP32 | ESP32‑S2 | ESP32‑S3 | ESP32‑C3 | ESP32‑C6 | ESP32‑H2 |
 * +==============+=========+=======+==========+==========+==========+==========+==========+
 * | CS (SS)      | GPIO15  | GPIO5 | GPIO34   | GPIO10   | GPIO7    | GPIO18   | GPIO0    |
 * +--------------+---------+-------+----------+----------+----------+----------+----------+
 * | DI (MOSI)    | GPIO13  | GPIO23| GPIO35   | GPIO11   | GPIO6    | GPIO19   | GPIO25   |
 * +--------------+---------+-------+----------+----------+----------+----------+----------+
 * | DO (MISO)    | GPIO12  | GPIO19| GPIO37   | GPIO13   | GPIO5    | GPIO20   | GPIO11   |
 * +--------------+---------+-------+----------+----------+----------+----------+----------+
 * | SCK (SCLK)   | GPIO14  | GPIO18| GPIO36   | GPIO12   | GPIO4    | GPIO21   | GPIO10   |
 * +--------------+---------+-------+----------+----------+----------+----------+----------+
 *
 * For more info see file README.md in this library or on URL:
 * https://github.com/espressif/arduino-esp32/tree/master/libraries/SD
 */

#include "FS.h"
#include "SD.h"
#include "SPI.h"

SPIClass vspi = SPIClass(VSPI);

#define REASSIGN_PINS
int sck = 18;
int miso = 19;
int mosi = 23;
int cs = 5;

void listDir(fs::FS &fs, const char *dirname, uint8_t levels) {
  Serial.printf("Listing directory: %s\n", dirname);

  File root = fs.open(dirname);
  if (!root) {
    Serial.println("Failed to open directory");
    return;
  }
  if (!root.isDirectory()) {
    Serial.println("Not a directory");
    return;
  }

  File file = root.openNextFile();
  while (file) {
    if (file.isDirectory()) {
      Serial.print("  DIR : ");
      Serial.println(file.name());
      if (levels) {
        listDir(fs, file.path(), levels - 1);
      }
    } else {
      Serial.print("  FILE: ");
      Serial.print(file.name());
      Serial.print("  SIZE: ");
      Serial.println(file.size());
    }
    file = root.openNextFile();
  }
}

void createDir(fs::FS &fs, const char *path) {
  Serial.printf("Creating Dir: %s\n", path);
  if (fs.mkdir(path)) {
    Serial.println("Dir created");
  } else {
    Serial.println("mkdir failed");
  }
}

void removeDir(fs::FS &fs, const char *path) {
  Serial.printf("Removing Dir: %s\n", path);
  if (fs.rmdir(path)) {
    Serial.println("Dir removed");
  } else {
    Serial.println("rmdir failed");
  }
}

void readFile(fs::FS &fs, const char *path) {
  Serial.printf("Reading file: %s\n", path);

  File file = fs.open(path);
  if (!file) {
    Serial.println("Failed to open file for reading");
    return;
  }

  Serial.print("Read from file: ");
  while (file.available()) {
    Serial.write(file.read());
  }
  file.close();
}

void writeFile(fs::FS &fs, const char *path, const char *message) {
  Serial.printf("Writing file: %s\n", path);

  File file = fs.open(path, FILE_WRITE);
  if (!file) {
    Serial.println("Failed to open file for writing");
    return;
  }
  if (file.print(message)) {
    Serial.println("File written");
  } else {
    Serial.println("Write failed");
  }
  file.close();
}

void appendFile(fs::FS &fs, const char *path, const char *message) {
  Serial.printf("Appending to file: %s\n", path);

  File file = fs.open(path, FILE_APPEND);
  if (!file) {
    Serial.println("Failed to open file for appending");
    return;
  }
  if (file.print(message)) {
    Serial.println("Message appended");
  } else {
    Serial.println("Append failed");
  }
  file.close();
}

void renameFile(fs::FS &fs, const char *path1, const char *path2) {
  Serial.printf("Renaming file %s to %s\n", path1, path2);
  if (fs.rename(path1, path2)) {
    Serial.println("File renamed");
  } else {
    Serial.println("Rename failed");
  }
}

void deleteFile(fs::FS &fs, const char *path) {
  Serial.printf("Deleting file: %s\n", path);
  if (fs.remove(path)) {
    Serial.println("File deleted");
  } else {
    Serial.println("Delete failed");
  }
}

void testFileIO(fs::FS &fs, const char *path) {
  File file = fs.open(path);
  static uint8_t buf[512];
  size_t len = 0;
  uint32_t start = millis();
  uint32_t end = start;
  if (file) {
    len = file.size();
    size_t flen = len;
    start = millis();
    while (len) {
      size_t toRead = len;
      if (toRead > 512) {
        toRead = 512;
      }
      file.read(buf, toRead);
      len -= toRead;
    }
    end = millis() - start;
    Serial.printf("%u bytes read for %lu ms\n", flen, end);
    file.close();
  } else {
    Serial.println("Failed to open file for reading");
  }

  file = fs.open(path, FILE_WRITE);
  if (!file) {
    Serial.println("Failed to open file for writing");
    return;
  }

  size_t i;
  start = millis();
  for (i = 0; i < 2048; i++) {
    file.write(buf, 512);
  }
  end = millis() - start;
  Serial.printf("%u bytes written for %lu ms\n", 2048 * 512, end);
  file.close();
}

void setup() {
  Serial.begin(115200);
  pinMode(cs, OUTPUT);
  vspi.begin(sck, miso, mosi, cs);
#ifdef REASSIGN_PINS
  vspi.begin(sck, miso, mosi, cs);
  if (!SD.begin(cs, vspi, 20000000)) {
#else
  if (!SD.begin()) {
#endif
    Serial.println("Card Mount Failed");
    return;
  }
  uint8_t cardType = SD.cardType();

  if (cardType == CARD_NONE) {
    Serial.println("No SD card attached");
    return;
  }

  Serial.print("SD Card Type: ");
  if (cardType == CARD_MMC) {
    Serial.println("MMC");
  } else if (cardType == CARD_SD) {
    Serial.println("SDSC");
  } else if (cardType == CARD_SDHC) {
    Serial.println("SDHC");
  } else {
    Serial.println("UNKNOWN");
  }

  uint64_t cardSize = SD.cardSize() / (1024 * 1024);
  Serial.printf("SD Card Size: %lluMB\n", cardSize);

  listDir(SD, "/", 0);
  createDir(SD, "/mydir");
  listDir(SD, "/", 0);
  removeDir(SD, "/mydir");
  listDir(SD, "/", 2);
  writeFile(SD, "/hello.txt", "Hello ");
  appendFile(SD, "/hello.txt", "World!\n");
  readFile(SD, "/hello.txt");
  deleteFile(SD, "/foo.txt");
  renameFile(SD, "/hello.txt", "/foo.txt");
  readFile(SD, "/foo.txt");
  testFileIO(SD, "/test.txt");
  Serial.printf("Total space: %lluMB\n", SD.totalBytes() / (1024 * 1024));
  Serial.printf("Used space: %lluMB\n", SD.usedBytes() / (1024 * 1024));
}

void loop() {}
 

SlavaZagaynov

★✩✩✩✩✩✩
27 Ноя 2019
248
46
www.youtube.com
попробуй не SD, a SD_MMC

p.s. это точно работатет
для подключения 3 проводов достаточно
SD_MMC.setPins(clk, cmd, d0)
 
Изменено:
  • Лойс +1
Реакции: Ivan_X

Ivan_X

✩✩✩✩✩✩✩
11 Ноя 2025
11
0

@SlavaZagaynov, А MMC это разве не другой тип карт? Им вроде нужен другой карт-ридер с другими пинами? У меня на карт-ридере нет пинов CMD, D#, выведен только стандартный SPI: (MISO, MOSI, SCK, CS)
 

SlavaZagaynov

★✩✩✩✩✩✩
27 Ноя 2019
248
46
www.youtube.com
@Ivan_X, я давно с этим разбирался, подробностей не помню. Там что-то типа такого... Были карты SD со своим протоколом передачи данных и всё сбыло хорошо, а потом стали видео снимать, потребовалась высокая скорость и SD такая и говорит, "я не успеваю, хоть убейте меня".
Ну инженеры репу почесали и убили её, сделали новый програмный протокол в ставом физическом формате карт.
А на картах не пишут что за карта, только иногда на устройствых, что поддерживаются карты только до 16 ГБ, но и это не факт что заработает.
Реально старый формат это карты на 1 ГБ, если у тебя такая из прошлого века завалялать, то она заработает.

см. Схема подключения для режима 1-bit
 
  • Лойс +1
Реакции: Ivan_X

Ivan_X

✩✩✩✩✩✩✩
11 Ноя 2025
11
0
То есть, можно по сути подключить тот же самый SPI карт-ридер для SDMMC?
 

Ivan_X

✩✩✩✩✩✩✩
11 Ноя 2025
11
0

@SlavaZagaynov,
Спасибо за помощь!) А у вас есть какая нибудь нарисованная схема или пины micro SD -> ESP?
 

SlavaZagaynov

★✩✩✩✩✩✩
27 Ноя 2019
248
46
www.youtube.com
я использкю такие пины
GPIO_39: : SD_MMC CMD (mosi)
GPIO_40: : SD_MMC CLK (clk)
GPIO_41: : SD_MMC D0 (miso)

код:
            int clk = 40;
            int cmd = 39;
            int d0  = 41;          
           
            Serialprintln("запуск SD_MMC "+String(clk)+"/"+String(cmd)+"/"+String(d0));
           
    if(! SD_MMC.setPins(clk, cmd, d0)){
        Serialprintln("! ERR SD_MMC Pin change failed!");
    }          

  if (!SD_MMC.begin("/sdcard", true)) {    Serialprintln("! ERR SD_MMC Card Mount Failed");  }
  uint8_t cardType = SD_MMC.cardType();

  if (cardType == CARD_NONE) {    Serialprintln("! ERR SD_MMC No SD_MMC card attached");  }

  Serialprintln("SD_MMC Card Type: ");
  if (cardType == CARD_MMC) {    Serialprintln("MMC");
  } else if (cardType == CARD_SD) {    Serialprintln("SDSC");
  } else if (cardType == CARD_SDHC) {    Serialprintln("SDHC");
  } else {    Serialprintln("UNKNOWN");
  }

  uint64_t cardSize = SD_MMC.cardSize() / (1024 * 1024);
  Serial.printf("SD_MMC Card Size: %lluMB\n", cardSize);

  Serial.printf("Total space: %lluMB\n", SD_MMC.totalBytes() / (1024 * 1024));
  Serial.printf("Used space: %lluMB\n", SD_MMC.usedBytes() / (1024 * 1024));
 
  • Лойс +1
Реакции: Ivan_X

kapitanrtv

✩✩✩✩✩✩✩
29 Июн 2021
2
0
У меня так
CS - GPIO2
SCK - GPI04
MOSI - GPI06
MISO - GPI05
Хотя долго не запускалась, оказалось что работает только от 5в 3,3 ей мало....
 

Ivan_X

✩✩✩✩✩✩✩
11 Ноя 2025
11
0
Я проверил, попробовал подключить по 1-битной шине, не получилось) в Serial выводится ошибка 0x107, как я понял, это значит что карта не отвечает на инициализацию... У меня ESP32 DevKitC V4, подключил так: MISO -> G2, MOSI -> G15, SCK -> G14. Распиновку платы приложу, может понадобится... Кто знает, можете пожалуйста подсказать почему не работает?) Я уже и к 3.3 через 10 кОм все пины подтягивал как в гайде, не инициализируется...63a467e13cc54.jpg
 

kapitanrtv

✩✩✩✩✩✩✩
29 Июн 2021
2
0
Приветствую. Я недавно "пересел"на esp32? до этого arduino использовал. Тоже долго не мог SD подцепить, тем более что я с кодами совсем не дружу и всё делаю через FLProg. Вот проект, будут вопросы обращайся.
 

Вложения

Ivan_X

✩✩✩✩✩✩✩
11 Ноя 2025
11
0

@kapitanrtv,
Здравствуйте) А что находится в файле? Я не могу сейчас распаковать архив, если там код, можете пожалуйста скопировать его текстом?
 

Бизон

✩✩✩✩✩✩✩
7 Июл 2026
1
0
@Ivan_X,

1783443147667.pngуже пару месяцев мучаюсь ибо совсем не спец,но при такой распиновке сд карта определялась. такой вариант меня не устраивает, хочу сделать одностороннюю плату. но трассировка мне все нервы вымотала.и по ходу что-то испортил, датчики влажности почвы емкостные из 6 шт 3 по воздуху показывают 0, а другие 3 показывают то что должны по сухому состоянию

P.S. все решилось на стандартных пинах и библиотека припаяв к ножкам модуля микро сд карты керамического конденсатора на 100мкФ
 
Изменено: