ESP32 Thing Motion Shield Hookup Guide

Pages
Contributors: MTaylor
Favorited Favorite 2

Using the MicroSD Card

The microSD card relies on the libraries packaged with the ESP32 Arduino board files. The best way to garner knowledge is to go into the source files and read the various header files, or to use the example sketches.

To use the examples directly, make sure you assign the CS pin to 33.

This example also shows how to setup the CD pin as input, and to us it to detect a card. The program will halt during setup if a card is not detected, or if the card doesn't mount properly.

If everything's a go, the SD_Test_Motion_Board.ino example will report basic information about the card.

language:c
/*****************************************************************
SD_Test_Motion_Board.ino

This is a modified version of the SD_Test example sketch
included with the Arduino core for the esp32, from
https://github.com/espressif/arduino-esp32

This example:
* Uses the CD pin to check for a card
* Mounts the card
* Prints information about the card.

Use this for a starting place while working with SD cards.

Hardware requirements:
ESP32 Thing attached to Motion Board

Distributed as-is; no warranty is given.
*****************************************************************/
#include "FS.h"
#include "SD.h"
#include "SPI.h"

#define SD_CS_PIN 33
#define SD_CD_PIN 38


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

    //Check for card presence using CD pin
    pinMode(SD_CD_PIN, INPUT);
    if(digitalRead(SD_CD_PIN) == 1) {
        Serial.println("Card detected");
    } else {
        Serial.println("Card not present");
        return;
    }   
    //Call begin with (cs pin, SPI, rate (up to 10MHz), "/sd")
    if(!SD.begin(SD_CS_PIN, SPI, 1000000, "/sd")){
        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);

}

void loop(){

}

To help with development in the FileSerialExample.ino example, I've written a little SD extension library that allows writing of sequentially numbered files up to a particular size. It behaves like a serial port, so things like .println() can be used.

Don't run this example! This example requires FileSerial.cpp and FileSerial.h to operate. It is here to show how similar the file writing operation of these two included files is to a normal serial object. Get the full project (this example plus code and header) from https://github.com/sparkfun/ESP32_Motion_Shield/tree/master/Software/FileSerialExample.

In addition to standard methods such as print() and println(), the library includes the following functionality.

Construction

Create a file writing object with the class name FileSerial. You can construct in two ways:

  • FileSerial ExampleFileSet(&Serial); -- Verbose output of data/File IO status to passed serial object.
  • FileSerial ExampleFileSet; -- Non-verbose.

begin();

int begin(fs::FS * inputDevice, uint8_t ssPin, SPIClass &spi, uint32_t frequency, const char * mountpoint);

Call begin to mount the card and start the SPI device.

Pass: device, CS pin, port, frequency, and mount point.

Returns: 1 if success.

Example:ExampleFileSet.begin(&SD, 33, SPI, 10000000, "/sd")

setMaxFileSize();

void setMaxFileSize( int32_t inputSize );

Call to set the max file size in bytes.

Default: 250kB

Range:

  • 0 -- No cap.
  • 32 to 1000000000 -- 32 bytes to 1GB

setWriteBufferSize();

void setWriteBufferSize( uint8_t inputSize );

Call to set buffer size in bytes before performing file write.

Default: 100B

Range: 1 to 255 -- 1B to 255B

startLog()

int startLog( const char * inputPath, const char * inputStub );

Start a batch of log files. Pass directory name and file name. The file name will be appended with nnnn.txt where "nnnn" are sequential numbers.

If directory is a path, parent directories must exist!

  • "[existing directory]/[new directory]" is valid
  • "[new directory]/[new directory]" is not

Example:ExampleFileSet.startLog("testFiles", "file");

language:c
/******************************************************************************
FileSerialExample.ino
Example Serial-like file writer

Marshall Taylor @ SparkFun Electronics
original creation date: Nov 6, 2017
https://github.com/sparkfun/ESP32_Motion_Shield

This example demonstrates usage of the FileSerial library.

The FileSerial libary implements the ESP32 SD_Test functions as a class that acts like a
HardwareSerial device.  It has been modeled from the ESP32 Arduino core's
HardwareSerial class, but takes no input streams from the user.

There are a couple extra functions that aren't normally found in a serial device

    int startLog( const char * inputPath, const char * inputStub );
    int stopLog( void );
    void setMaxFileSize( int32_t inputSize );
    void setWriteBufferSize( uint8_t inputSize );

Construct with an optional serial device address, such as

    FileSerial ExampleFileSet(&Serial);

Doing so logs SD read/write information plus written data to the passed serial port.

Resources:
ESP32 Arduino core

Development environment specifics:
Arduino 1.8.2

This code is released under the [MIT License](http://opensource.org/licenses/MIT).
Please review the LICENSE.md file included with this example. If you have any questions 
or concerns with licensing, please contact techsupport@sparkfun.com.
Distributed as-is; no warranty is given.
******************************************************************************/

#include <Arduino.h>
#include "FileSerial.h"

//Pass address of serial port to see the file IO debug information
FileSerial ExampleFileSet(&Serial);

//...or don't
//FileSerial ExampleFileSet;

int loopCount = 0;

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

    delay(1000);
    Serial.println("Starting Sketch");

    //call begin with device, CS pin, port, frequency, and mount point.
    if(ExampleFileSet.begin(&SD, 33, SPI, 10000000, "/sd") == 0)
    {
        Serial.println("SD begin did not succeed, halting.");
        while(1);
    }
    //File name will be appended with file number, ex: filennnn.txt

    //You can set max file size in bytes, set 0 for unchecked.
    //Default is 250kB, range 0, 32 to 1000000000
    ExampleFileSet.setMaxFileSize(10000);

    //You can as set buffer size between file writes.
    //Default is 100B, range is 1 to 255B
    ExampleFileSet.setWriteBufferSize(80);

    //Start a batch of log files with startLog,
    //pass directory name and file name.
    //
    //If directoy is path, parent directories must exist!
    //"[existing directory]/[new directory]" is valid
    //"[new directory]/[new directory]" is not
    ExampleFileSet.startLog("testFiles", "file");
}

void loop(){
    while(Serial.available())
    {
        char c = Serial.read();
        ExampleFileSet.print(c);
    }
    ExampleFileSet.printf("Loop count: %d\n", loopCount); //Formatting works
    ExampleFileSet.println(2.54321, 3); //standard formatting works
    ExampleFileSet.println(0x2E0A, HEX); //and other types
    loopCount++;
    delay(100);

}