Utilize Expansion module SD card with Arduino code

  • Hi,
    Is it possible to utilize the SD card on the Expansion Module with Arduino code? I'm finding that most of the Arduino libraries for SD cards are expecting an SPI interface. However I'm unclear what interface we have available. The docs mention these pins and functions related to SD: P8: DAT0, P23: SCLK and P4: CMD. These don't look like SPI to me.

    Can anyone shed some light on this for me?

    Thanks much

  • @peter_ The doc speaks about external pull-up resistors. I do not have such ones on my boards, and it still works well.

  • @robert-hh thanks again.

    Doesn't GPIO15 have to be an output? It's the SDcmd pin.

    are you referring to my calling pinMode(15, INPUT_PULLUP);?

    As odd as it sounds, I don't think these are mutually exclusive. This doc says CMD should be pulled high. I am working under the assumption that the MicroPython firmware does this behind the scenes.

  • @peter_ I do not know about the Arduino package. I use the SDCard with these settings successfully with MicroPyhton. So it can work. About your code. Doesn't GPIO15 have to be an output? It's the SDcmd pin.

  • In case it's helpful:

    Using the SD_Test arduino sketch, my debug messages end with:

    [   331][W][sd_diskio.cpp:104] sdWait(): Wait Failed
    [   331][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
    [   331][W][sd_diskio.cpp:510] ff_sd_initialize(): GO_IDLE_STATE failed
    [   336][E][sd_diskio.cpp:790] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
    [   645][W][sd_diskio.cpp:104] sdWait(): Wait Failed
    [   645][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
    Card Mount Failed```
    Using the SDMMC_Test arduino sketch, my debug messages end with:
    ```hal-cpu.c:211] setCpuFrequencyMhz(): PLL: 480 / 2 = 240 Mhz, APB: 80000000 Hz
    E (188) sdmmc_sd: sdmmc_init_sd_scr: send_scr (1) returned 0x109
    E (189) vfs_fat_sdmmc: sdmmc_card_init failed (0x109).
    [   189][E][SD_MMC.cpp:84] begin(): Failed to initialize the card (265). Make sure SD card lines have pull-up resistors in place.
    Card Mount Failed

    Then I added internal pullups like so:

    pinMode(14, INPUT_PULLUP);
    pinMode(2, INPUT_PULLUP);
    pinMode(15, INPUT_PULLUP);

    My debug messages change to:

    E (100) sdmmc_sd: sdmmc_check_scr: send_scr returned 0xffffffff
    E (100) vfs_fat_sdmmc: sdmmc_card_init failed (0xffffffff).
    [   101][E][SD_MMC.cpp:78] begin(): Failed to mount filesystem. If you want the card to be formatted, set format_if_mount_failed = true.
    Card Mount Failed

    I'm not sure how to use format_if_mount_failed, but I have read that formatting on Windows is helpful. I tried that.

    And finally, using the SPI method with the code I pasted earlier i get:

    [    31][W][sd_diskio.cpp:174] sdCommand(): no token received
    [   132][W][sd_diskio.cpp:174] sdCommand(): no token received
    [   532][W][sd_diskio.cpp:104] sdWait(): Wait Failed
    [   532][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
    [   532][W][sd_diskio.cpp:510] ff_sd_initialize(): GO_IDLE_STATE failed
    [   537][E][sd_diskio.cpp:790] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
    [   845][W][sd_diskio.cpp:104] sdWait(): Wait Failed
    [   845][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
    Card Mount Failed

  • Thank you @robert-hh. I've tried using those pins in my experimenting. I've tried:

    • 2 different SD cards (formatted as fat32 and fat16)

    • 2 different expansion boards

    • with a LoPy and a FiPy.

    Is there anyone out there who has successfully mounted an SD card with the official expansion board?

    I see that according to the ESP32 docs that external pullups are required, and that according to the Pycom docs these pullups are not needed. In my arduino code I have also tried pulling these pins high in my setup.

    Is contacting this @pycom user a reasonable way to get support beyond community engagement? I will use the email system in the meantime.


  • @peter_ As far as I used it for my homebuilt expansion board and the Pinout sheet of LoPy4 tells, the SDCARD is connected to P4 (GPIO15) for CMD, P8 (GPIO2) for DATA and P23 (GPIO14) for CLK. CS and CardDetect are not used.

  • Thanks @robert-hh and @jcaron. Sorry, it's taking me some time to formulate the right questions.

    fwiw, I have tried the arduino example code for the native SD support with no luck. The SD_MMC library requires a 10k pullup on GPIO2 which I will try later.

    I am locked in to what pins are connected to the lopy4 and where, because this is the expansion board we're talking about. So a better question is what are the SD card pins mapped to on the LOPY4 when it is plugged into the expansion board?

    The expansion v3 pinout diagram I am finding to be confusing. It indicates SD_CMD : GPIO11, SD_DAT : GPIO15 and SD_CLK : GPIO10. How are these GPIOs available on the expansion board available when they are not even broken out on the LOPY4? Is there some kind of multiplexing magic happening through the stock firmware? If that's the case then perhaps it's not possible to fully use the expansion board with arduino.

    The native libraries seem not to allow specifying pins . I have found code below that using SPI where specifying pins is possible, but I can't seem to get this to work either. When I use the pins suggested from the expansion board pinout, it boot loops. Using the SD related pins from the LOPY4 pinout doesn't work for me either sadly. SD_CS set to 13 is something I have seen in example code, but none of the pycom pinouts reference SD_CS or SD_SS. Maybe this is wrong also?

    Any more insight would be greatly appreciated. - Thanks

    #include "FS.h"
    #include "SD.h"
    #include "SPI.h"
    SPIClass spiSD(HSPI);
    #define SD_CS 13
    #define SDSPEED 27000000
    void setup() {
      spiSD.begin(10, 15, 11, SD_CS); //SCK,MISO,MOSI,ss  - as suggested by the expansion pinout 
      //spiSD.begin(14, 2, 15,  SD_CS); //SCK,MISO,MOSI,ss  - as suggested by the LOPY4 pinout 
      if (!SD.begin( SD_CS, spiSD, SDSPEED)) {
        Serial.println("Card Mount Failed");
    }// end of setup
    void loop() {

  • @peter_ there are libraries using SPI, and there are libraries using the native ESP32 SD/MMC support.

    See https://github.com/espressif/arduino-esp32/tree/master/libraries/SD_MMC for the latter.

    Note that I never used it myself.

  • @peter_ The ESP32 allows assigning the SPI signals to any pin. Some pins are input only, so you cannot use these for mosi.

Log in to reply

Pycom on Twitter