Forum: Mikrocontroller und Digitale Elektronik ESP32 SPI SD-Card-Modul


von Chandler B. (chandler)


Lesenswert?

Hallo,
ich möchte gerne mit einem ESP32-Wroom-32 und ESP-IDF Daten von einer 
SD-Karte lesen.
Dazu habe ich einen mikroSD-Karten-Modul wo man über SPI kommunizieren 
kann.
Verbunden habe ich das Modul an HSPI und mit dem 3,3 V vom ESP-Board.

Jetzt habe ich das Beispiel sdspi (esp-idf-v5.4) genommen und die Pins 
aus der Konfig angepasst. Dennoch bekomme ich einen Fehler
1
I (317) main_task: Started on CPU0
2
I (327) main_task: Calling app_main()
3
I (327) example: CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED: 1
4
I (327) example: CONFIG_EXAMPLE_DEBUG_PIN_CONNECTIONS: FALSE
5
I (327) example: Initializing SD card
6
I (327) example: Using SPI peripheral
7
I (337) example: CONFIG_EXAMPLE_PIN_CLK: 14
8
I (337) example: CONFIG_EXAMPLE_PIN_MOSI: 13
9
I (347) example: CONFIG_EXAMPLE_PIN_MISO: 12
10
I (347) example: CONFIG_EXAMPLE_PIN_CS: 15
11
I (347) example: Mounting filesystem
12
I (357) gpio: GPIO[15]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
13
E (567) sdmmc_sd: sdmmc_init_sd_if_cond: send_if_cond (1) returned 0x108
14
E (567) vfs_fat_sdmmc: sdmmc_card_init failed (0x108).
15
HINT: Please verify if there is an SD card inserted into the SD slot. Then, try rebooting the board.
16
I (567) gpio: GPIO[15]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
17
E (567) example: Failed to initialize the card (ESP_ERR_INVALID_RESPONSE). Make sure SD card lines have pull-up resistors in place.
18
HINT: Please refer ./README.md for details
19
I (587) main_task: Returned from app_main()
1
void app_main(void)
2
{
3
    esp_err_t ret;
4
5
    // Options for mounting the filesystem.
6
    // If format_if_mount_failed is set to true, SD card will be partitioned and
7
    // formatted in case when mounting fails.
8
    esp_vfs_fat_sdmmc_mount_config_t mount_config = {
9
#ifdef CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED
10
        .format_if_mount_failed = true,
11
#else
12
        .format_if_mount_failed = false,
13
#endif // EXAMPLE_FORMAT_IF_MOUNT_FAILED
14
        .max_files = 5,
15
        .allocation_unit_size = 16 * 1024
16
    };
17
    sdmmc_card_t *card;
18
    const char mount_point[] = MOUNT_POINT;
19
    ESP_LOGI(TAG, "CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED: %d", mount_config.format_if_mount_failed);
20
#ifdef CONFIG_EXAMPLE_DEBUG_PIN_CONNECTIONS
21
    ESP_LOGI(TAG, "CONFIG_EXAMPLE_DEBUG_PIN_CONNECTIONS: TRUE");
22
#else
23
    ESP_LOGI(TAG, "CONFIG_EXAMPLE_DEBUG_PIN_CONNECTIONS: FALSE");
24
#endif
25
26
    ESP_LOGI(TAG, "Initializing SD card");
27
28
    // Use settings defined above to initialize SD card and mount FAT filesystem.
29
    // Note: esp_vfs_fat_sdmmc/sdspi_mount is all-in-one convenience functions.
30
    // Please check its source code and implement error recovery when developing
31
    // production applications.
32
    ESP_LOGI(TAG, "Using SPI peripheral");
33
34
    // By default, SD card frequency is initialized to SDMMC_FREQ_DEFAULT (20MHz)
35
    // For setting a specific frequency, use host.max_freq_khz (range 400kHz - 20MHz for SDSPI)
36
    // Example: for fixed frequency of 10MHz, use host.max_freq_khz = 10000;
37
    sdmmc_host_t host = SDSPI_HOST_DEFAULT();
38
39
    // For SoCs where the SD power can be supplied both via an internal or external (e.g. on-board LDO) power supply.
40
    // When using specific IO pins (which can be used for ultra high-speed SDMMC) to connect to the SD card
41
    // and the internal LDO power supply, we need to initialize the power supply first.
42
#if CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO
43
    sd_pwr_ctrl_ldo_config_t ldo_config = {
44
        .ldo_chan_id = CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_IO_ID,
45
    };
46
    sd_pwr_ctrl_handle_t pwr_ctrl_handle = NULL;
47
48
    ret = sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &pwr_ctrl_handle);
49
    if (ret != ESP_OK) {
50
        ESP_LOGE(TAG, "Failed to create a new on-chip LDO power control driver");
51
        return;
52
    }
53
    host.pwr_ctrl_handle = pwr_ctrl_handle;
54
#endif
55
56
    spi_bus_config_t bus_cfg = {
57
        .mosi_io_num = PIN_NUM_MOSI,
58
        .miso_io_num = PIN_NUM_MISO,
59
        .sclk_io_num = PIN_NUM_CLK,
60
        .quadwp_io_num = -1,
61
        .quadhd_io_num = -1,
62
        .max_transfer_sz = 400,
63
    };
64
    ESP_LOGI(TAG, "CONFIG_EXAMPLE_PIN_CLK: %d", bus_cfg.sclk_io_num);
65
    ESP_LOGI(TAG, "CONFIG_EXAMPLE_PIN_MOSI: %d", bus_cfg.mosi_io_num);
66
    ESP_LOGI(TAG, "CONFIG_EXAMPLE_PIN_MISO: %d", bus_cfg.miso_io_num);
67
68
    ret = spi_bus_initialize(host.slot, &bus_cfg, SDSPI_DEFAULT_DMA);
69
    if (ret != ESP_OK) {
70
        ESP_LOGE(TAG, "Failed to initialize bus.");
71
        return;
72
    }
73
74
    // This initializes the slot without card detect (CD) and write protect (WP) signals.
75
    // Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
76
    sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
77
    slot_config.gpio_cs = PIN_NUM_CS;
78
    slot_config.host_id = host.slot;
79
    ESP_LOGI(TAG, "CONFIG_EXAMPLE_PIN_CS: %d", slot_config.gpio_cs);
80
81
    ESP_LOGI(TAG, "Mounting filesystem");
82
    ret = esp_vfs_fat_sdspi_mount(mount_point, &host, &slot_config, &mount_config, &card);
83
84
    if (ret != ESP_OK) {
85
        if (ret == ESP_FAIL) {
86
            ESP_LOGE(TAG, "Failed to mount filesystem. "
87
                     "If you want the card to be formatted, set the CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option.");
88
        } else {
89
            ESP_LOGE(TAG, "Failed to initialize the card (%s). "
90
                     "Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret));
91
#ifdef CONFIG_EXAMPLE_DEBUG_PIN_CONNECTIONS
92
            check_sd_card_pins(&config, pin_count);
93
#endif
94
        }
95
        return;
96
    }

von Harald K. (kirnbichler)


Lesenswert?

Ja, und?

Die Fehlermeldung ist sehr ausführlich und gibt Hinweise, was Du Dir 
ansehen solltest.

Hast Du irgendwas davon berücksichtigt?

von Obelix X. (obelix)


Lesenswert?

Was ist bei dir anders als in folgendem Guide?

https://randomnerdtutorials.com/esp32-microsd-card-arduino/

von Chandler B. (chandler)


Lesenswert?

Obelix X. schrieb:
> Was ist bei dir anders als in folgendem Guide?
>
> https://randomnerdtutorials.com/esp32-microsd-card-arduino/

Anders ist:
1) ich benutze ESP-IDF und nicht Arduino
2) ich benutze die Pins für HSPI und nicht VSPI (die Pins sind aber für 
HSPI konfiguriert, siehe Log)
3) meine SD-Karte ist nur 512 MB groß

Angeschlossen habe ich es
SD-Card-Reader -> ESP32-Wroom-32
GND -> GND
VCC -> 3V3
CS -> GPIO15
MOSI -> GPIO13
CLK -> GPIO14
MISO -> GPIO12

von Chandler B. (chandler)


Lesenswert?

Harald K. schrieb:
> Ja, und?
>
> Die Fehlermeldung ist sehr ausführlich und gibt Hinweise, was Du Dir
> ansehen solltest.
>
> Hast Du irgendwas davon berücksichtigt?

die erste Fehlermeldung sagt mir, dass keine SD-Karte drinn ist.
Die ist aber eingelegt.

Die zweite sagt, dass ein pull-up resistor vorhanden sein soll.
Da lese ich aber immer unterschiedliches. In den ganzen Tutorials ist 
nirgends ein Widerstand eingesetzt.
Von wo nach wo (und wie groß) müsste dieser denn sein?

von Harald K. (kirnbichler)


Lesenswert?

Chandler B. schrieb:
> Von wo nach wo (und wie groß) müsste dieser denn sein?

Eine der Fehlermeldungen verweist auf "readme.md". Hast Du da 
reingesehen?

(Ich kann das nicht für Dich, weil ich da erst mal rauskramen müsste, 
was auch immer Du Dir da für Libraries zusammengeklickt hast)

von Chandler B. (chandler)


Angehängte Dateien:

Lesenswert?

Harald K. schrieb:
> Chandler B. schrieb:
>> Von wo nach wo (und wie groß) müsste dieser denn sein?
>
> Eine der Fehlermeldungen verweist auf "readme.md". Hast Du da
> reingesehen?
>
> (Ich kann das nicht für Dich, weil ich da erst mal rauskramen müsste,
> was auch immer Du Dir da für Libraries zusammengeklickt hast)

Zusammengeklickt habe ich nichts. Ich habe eins zu eins das Beispiel 
genommen und die Pins angepasst.
1
Although it is possible to connect an SD card breakout adapter, keep in mind that connections using breakout cables are often unreliable and have poor signal integrity. You may need to use lower clock frequency when working with SD card breakout adapters.
die habe ich auf 400 khz gesetzt

Pins (siehe Anhang)
Wobei bei mir
MISO auf GPIO12
CS auf GPIO15
SCK auf GPIO14
MOSI auf GPIO13

https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/peripherals/sd_pullup_requirements.html#overview-of-compatibility
hiernach hat der ESP32-WROOM-32 keinen Pullup
1
No Pull-ups
2
When using a development board without pull-ups:
3
4
If your host and slave device are on separate boards, replace one of them with a board that has pull-ups. For the list of Espressif's development boards with pull-ups, go to Development Boards.
5
6
Attach external pull-ups by connecting each pin which requires a pull-up to VDD via a 10 kΩ resistor.

aber auch mit 10kOhm bekomme ich die selben Fehler

von Obelix X. (obelix)


Lesenswert?

Mit einem Oszi überprüfen ob alle Signale richtig an der SD-Karte 
ankommen. Bilder vom Aufbau und Schaltplan.

: Bearbeitet durch User
von Rüdiger B. (rbruns)


Lesenswert?

Damit hatte ich auch gekämpft:
SD_MMC.h benutzt den ESP32 MMC Code, ist etwas schneller.
SD.h ist allgemeiner und benutzt standarmässig HSPI, kann aber eine 
grössere Anzahl dateien gleichzitig öffnen(wenn konfiguriert).
Wichtig ist das immer die richtige von 4 internen SPI Engines verwendet 
wird, Nummer 1 und 2 werden Intern benutzt.
Hier meine Test mit auskommmentieten Fehlern.
1
//#define VSPI 3  //SPI 3 bus normally attached to pins 5, 18, 19 and 23, but can be matrixed to any pins
2
SPIClass SD_SPI = SPIClass(VSPI); // Neither HSPI nor VSPI=CYD seem to work
3
//SPIClass SD_SPI = SPIClass(BOARD_SDCARD_MISO,BOARD_SDCARD_SCK,BOARD_SDCARD_MOSI,BOARD_SDCARD_CS); // Neither HSPI nor VSPI seem to work
4
//SPIClass SD_SPI = SPIClass(14,2,15,13); // ESP32-CAM   SD_SPI.begin(14, 2, 15, 13); //sck,miso,mosi,ss
5
6
7
//SPI    MOSI    MISO    SCLK    CS
8
//VSPI  GPIO 23  GPIO 19  GPIO 18  GPIO 5
9
//HSPI  GPIO 13  GPIO 12  GPIO 14  GPIO 15
10
  SD_SPI.begin(18, 19, 23); // 
11
  //SDSPI.begin(SCLK, MISO, MOSI);
12
  pinMode (BOARD_SDCARD_CS, OUTPUT);
13
14
  digitalWrite(BOARD_SDCARD_CS, HIGH);
15
//   SD_SPI.begin(14, 2, 15, BOARD_SDCARD_CS); //sck,miso,mosi,ss ESP32-CAM
16
  Serial.println("SPI Started");
17
  //SD_SPI.setFrequency(1000000);
18
 if(!SD.begin(BOARD_SDCARD_CS, SD_SPI, 40000000, "/sd",(uint8_t) 15)){
19
// if(!SD.begin(BOARD_SDCARD_CS, SD_SPI)){
20
    Serial.println("Card Mount Failed");
21
    LITTLEFS_test();
22
    //return;
23
  }

von Harald K. (kirnbichler)


Lesenswert?

Chandler B. schrieb:
> aber auch mit 10kOhm bekomme ich die selben Fehler

Zeig ein Bild Deines Aufbaus. Tüddeldraht auf dem Frickelboard?

von Jan H. (jan_h74) Flattr this


Lesenswert?

SD_MMC 1-bit mode bei ESP32 funtioniert nur bei feste pinbelegung ! Da 
kan mann nicht ueber die pin matrix andere pins auswahlen ! Nur folgende 
pins functionieren :
#define SDCARD_SS 13
#define SDCARD_CLK 14
#define SDCARD_MOSI 15
#define SDCARD_MISO 2
SD_CARD_MISO wird nicht genutzt, soll aber mit ein pullup initialisiert 
werden.
Oder du verwendet SPI mode, dort sind die pins frei wahlbar.
Siehe auch 
https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/peripherals/sdmmc_host.html

von Chandler B. (chandler)


Angehängte Dateien:

Lesenswert?

Harald K. schrieb:
> Chandler B. schrieb:
>> aber auch mit 10kOhm bekomme ich die selben Fehler
>
> Zeig ein Bild Deines Aufbaus. Tüddeldraht auf dem Frickelboard?

Ich habe den Reader mit jumperkabel direkt mit dem ESP verbunden.

von Rüdiger B. (rbruns)


Lesenswert?

Dir ist klar das der Reader auf 5 Volt läuft und der ESP32 mit 3,3 Volt 
?

von Chandler B. (chandler)


Angehängte Dateien:

Lesenswert?

Rüdiger B. schrieb:
> Dir ist klar das der Reader auf 5 Volt läuft und der ESP32 mit 3,3 Volt
> ?

mhh, war davon ausgegangen, dass die Signale trotzdem mit 3V laufen 
würden.

habe jetzt einen SD-karten adapter direkt angeschlossen. Damit scheint 
es dann zu funktionieren.
Für die Spannung nehme ich dann jetzt natürlich nur die 3,3V
1
I (348) example: Mounting filesystem
2
I (358) gpio: GPIO[5]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
3
I (488) sdspi_transaction: cmd=5, R1 response: command not supported
4
I (648) example: Filesystem mounted
5
Name: SC32G
6
Type: SDHC
7
Speed: 20.00 MHz (limit: 20.00 MHz)
8
Size: 30436MB
9
CSD: ver=2, sector_size=512, capacity=62333952 read_bl_len=9
10
SSR: bus_width=1
11
I (658) example: Opening file /sdcard/hello.txt
12
I (708) example: File written
13
I (708) example: Renaming file /sdcard/hello.txt to /sdcard/foo.txt
14
I (708) example: Reading file /sdcard/foo.txt
15
I (708) example: Read from file: 'Hello SC32G!'
16
I (708) example: Opening file /sdcard/nihao.txt
17
I (728) example: File written
18
I (728) example: Reading file /sdcard/nihao.txt
19
I (728) example: Read from file: 'Nihao SC32G!'
20
I (728) gpio: GPIO[5]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
21
I (738) example: Card unmounted
22
I (738) gpio: GPIO[23]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
23
I (748) gpio: GPIO[19]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
24
I (758) gpio: GPIO[18]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
25
I (768) main_task: Returned from app_main()

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.