
Adafruit MicroSD SPI or SDIO Card Breakout Board
Created by Jeff Epler
Last updated on 2021-03-24 11:06:08 AM EDT

2
3
6
8
8
8
8
9
9
9
10
10
11
12
14
17
20
23
29
30
30
31
32
33
36
39
40
40
40
41
43
44
46
47
48
49
52
55
59
62
62
62
62
Guide Contents
Guide Contents
Overview
Pinouts
CircuitPython
Preparing your SD card
General Steps for Accessing SD Cards
Tip: Create a mount_sd.py file
sdcardio: For SD cards on SPI interfaces
sdioio: For SD cards on SDIO interfaces
adafruit_sdcard.py: For legacy uses
Using sdcardio
Initialize & Mount SD Card Filesystem
Reading & Writing Data
Example complete mount_sd.py
ItsyBitsy M4 Express + Breakout
Grand Central M4 Express
PyGamer
Feather Sense + Adalogger FeatherWing
Python Docs
Using sdioio
Initialize & Mount SD Card Filesystem
Reading & Writing Data
Example complete mount_sd.py
Grand Central M4 Express + SDIO Breakout
Feather STM32F405 Express
Python Docs
Adafruit CircuitPython SD
Adafruit CircuitPython Module Install
Initialize & Mount SD Card Filesystem
Reading & Writing Data
Example complete mount_sd.py
Adalogger M0 Feather
Python Docs
Examples
Listing files on SD card
Benchmarking SD card access
Logging temperature to SD card
Playing MP3 from SD Card
Showing BMPs from SD card
Downloads
Files
Schematic
Fab Print
© Adafruit Industries https://learn.adafruit.com/adafruit-microsd-spi-sdio Page 2 of 64

Overview
Micro SD cards and microcontrollers go together like micro-peanutbutter-and-jelly: SD cards are
inexpensive, durable, easy to find at any shop, come in many sizes and can plug into any computer using
a common SD card reader. That makes them perfect for microcontroller storage and retrieval - whether it's
images, fonts, GIFs, audio files, or sensor logs.
Wiring up SD cards when you're starting out is super easy - you just pick up one of Adafruit's SPI-to-SD
breakout boards (https://adafru.it/qyF), wire it to an SPI port and a chip select pin and with a little library
work you're reading and writing files (https://adafru.it/Myb). That's all good and great but you may
eventually find that your SD card project is a little...slow. Even with fast SPI ports, there's only one data
pin, which can make it hard to stream large files fast.
If you've hit that limit, this new breakout (https://adafru.it/Mzd) is designed to help. Unlike previous
adapters, it is not fixed for SPI usage, and can be used with SDIO hardware support. SDIO is a multi-pin
data protocol (up to 4 data pins at once!) SDIO also tends to be able to be clocked faster than SPI. Of
course, your speeds will vary depending on what microcontroller you hook it up to. When we used SDIO
instead of SPI on CircuitPython with the SAMD51 Grand Central (https://adafru.it/grandc), we got a speed
increase of about 200% when reading data off the card
© Adafruit Industries https://learn.adafruit.com/adafruit-microsd-spi-sdio Page 3 of 64

You will need to verify that your microcontroller has SDIO support and you have SDIO firmware/library
support as well. SDIO is usually available on higher end chips, and you may need to use some specific
pins. You can
still
use this for SPI mode, but it does not have level shifters, so it's not for use with 5V
microcontrollers.
For use with 3V power and logic microcontrollers only! The SDIO pins are bi-directional, and we've never
seen a 5V microcontroller with SDIO, so there's no level shifting or power regulator.
The breakout comes with a bit of header so you can use in a breadboard. It doesn't come with the micro
SD card itself!
© Adafruit Industries https://learn.adafruit.com/adafruit-microsd-spi-sdio Page 4 of 64

Secure Digital (https://adafru.it/rye), or SD, cards and tiny microSD cards are an inexpensive and
ubiquituous means of adding lots of storage to devices. For a few dollars you can have gigabytes of
storage at your fingertips (smaller than your fingertips actually!). With CircuitPython boards you typically
have a very limited amount of flash memory to store code and data.
Wouldn't it be nice if you could connect a microSD card to a Python board and expand its storage? It
turns you can use microSD cards with CircuitPython! In fact some boards like the Metro M4 Grand Central
come with microSD card support built-in, and for other boards like the Feather M4 Express family they can
easily be connected to a microSD card that expands their storage.
WIth the Adafruit MicroSD SPI or SDIO Card Breakout Board, you can add an SD card to your project
using the common SPI interface or the higher performance SDIO interface.
This guide also shows how to use a microSD card to store files for a CircuitPython board. Specifically
using a microSD card with CircuitPython boards like Feather M0 Adalogger, Grand Central M4, ItsyBitsy
M4, and others will be covered in this guide. You'll learn how to connect a microSD card to the board and
mount it as a new filesystem that store code & data.
Starting with CircuitPython 6, there are two new modules to improve the performance of SD cards using
SDIO.
Make sure you're running CircuitPython 6.0 or later, including pre-releases. These modules aren't
availble in older versions. Remember, you can always downgrade to the stable version of
CircuitPython if necessary.
© Adafruit Industries https://learn.adafruit.com/adafruit-microsd-spi-sdio Page 5 of 64

Pinouts
Power Pins
3V - This is the power pin. MicroSD cards must use 3.3V, so take care to only hook 3.3V to this pin.
Hooking 5V or VBAT to this pin will damage your microSD card.
GND - common ground for power and logic.
Common Logic Pins
DET - Detect whether a microSD card is inserted. This pin is connected to GND internally when
there's no card, but when one is inserted it is pulled up to 3V with a 4.7kΩ resistor. That means that
when the pin's logic level is False there's no card and when it's True there is.
SPI Logic Pins
If you're using SPI to connect to your SD cards, the pins have the following functions:
CLK - This is the SPI Clock pin / SCK Serial Clock, its an input to the chip.
SO - this is the Serial Out / Microcontroller In Serial Out pin, for data sent from the SD card to your
processor.
SI - this is the Serial In / Microcontroller Out Serial In pin, for data sent from your processor to the SD
card. Its an input to the chip and can use 3 - 5V logic.
CS - this is the Chip Select pin, drop it low to start an SPI transaction. Its an input to the chip and can
use 3 - 5V logic.
Pull ups are provided on all SPI logic pins.
© Adafruit Industries https://learn.adafruit.com/adafruit-microsd-spi-sdio Page 6 of 64

SDIO Logic Pins
If you're using SDIO to connect to your SD cards, the pins have the following functions:
CLK - The SDIO clock pin. A clock signal is sent by the microcontroller to the SD card on this pin.
CMD - A bidirectional pin for communication between the microcontroller and the SD card, used for
commands and information.
4 Data pins - Four bidirectional pins for communication between the microcontroller and the SD card,
used for transferring bulk data. Take care to wire these in the correct order! The silk screen legends
read: D0, D1, DAT2, D3.
Pull ups are provided on all SDIO logic pins.
Note that when inserted, the SD card extends slightly beyond the edge of the PCB. Check out the
mechanical drawing on the Downloads page (https://adafru.it/Qce).
© Adafruit Industries https://learn.adafruit.com/adafruit-microsd-spi-sdio Page 7 of 64

CircuitPython
Are you new to using CircuitPython? No worries, there is a full getting started guide
here (https://adafru.it/cpy-welcome).
Adafruit suggests using the Mu editor to edit your code and have an interactive REPL in
CircuitPython. You can learn about Mu and installation in this tutorial (https://adafru.it/ANO).
Preparing your SD card
If you bought an SD card, chances are it's already pre-formatted with a FAT filesystem. However you may
have problems with how the factory formats the card, or if it's an old card it needs to be reformatted.
CircuitPython supports both FAT16 and FAT32 filesystems.
It's always good idea to format the card before using, even if it's new! Note that formatting will erase the
card, so save anything you want first.
We strongly recommend you use the official SD card formatter utility - written by the SD association.
It solves many problems that come with bad formatting!
https://adafru.it/FKd
The official SD formatter is available from
https://www.sdcard.org/downloads/formatter/ (https://adafru.it/FKd)
Download it and run it on your computer, there's also a manual linked from that page for additional
instructions.
General Steps for Accessing SD Cards
The following pages will show all the steps to set up an SD card, including wiring information if applicable.
They all follow the same general structure:
1. If necessary, create an SPI bus object connecting to the card (cards attached by SDIO do not have a
separate bus object)
2. Construct an SDCard object
3. Create a vfs (virtual filesystem) object
4. "Mount" the vfs object to make the SD card's files appear so they can be accessed by functions like
open()
Tip: Create a mount_sd.py file
If you put the exact lines necessary to mount the sd card in a separate Python file in CIRCUITPY as
mount_sd.py, you can easily call it from the REPL or from code.py with import :
In the examples, we'll assume you have already created a mount_sd.py file.
https://adafru.it/FKd
© Adafruit Industries https://learn.adafruit.com/adafruit-microsd-spi-sdio Page 8 of 64

CircuitPython has trouble recognizing cards bigger than 32GB. 32GB of data with CIrcuitPython?
That's a lot.
sdcardio: For SD cards on SPI interfaces
sdcardio is the module for SD cards that use an SPI interface. Unless otherwise noted, it's a good bet that
a microcontroller SD card interface uses SPI. SPI uses 4 signal wires and can function at rates from
400kHz up to multiple MHz. Under some circumstances, multiple SPI devices can share 3 out of the 4
pins.
sdioio: For SD cards on SDIO interfaces
sdioio is the module for SD cards that use an SDIO interface. A few specific boards have SDIO interfaces
available. SDIO uses at least 3 signal wires (CMD, CLK, and DATA0), but can use additional data wires
(DATA1, DATA2, DATA3). SDIO operates at 25MHz or 50MHz, and it can transfer 1 or 4 bits at a time.
However, in practice, it offers around 1.5 to 2x the speed of SPI when reading from an SD card.
The built in micro SD slot on the STM32F405 Feather is connected using SDIO. The Grand Central M4 can
connect the SD card using SDIO or SPI, depending which pins are used.
adafruit_sdcard.py: For legacy uses
adafruit_sdcard is covered in its own guide (https://adafru.it/MA2). There are still some cases where you
should use adafruit_sdcard :
You're not ready to upgrade to CircuitPython 6
Some boards without much capacity omit sdcardio , but you can put adafruit_sdcard in CIRCUITPY.
This applies to all boards with the SAM D21 microcontroller.
© Adafruit Industries https://learn.adafruit.com/adafruit-microsd-spi-sdio Page 9 of 64

Using sdcardio
sdcardio is an SPI interface SD card library in CircuitPython 6.0 that is optimized in C to be much
faster than the original adafruit_sdcard library. Some much smaller/older boards don't have enough
memory for this module, in which case you will have to use adafruit_sdcard
Use the code and wiring examples in this section if these conditions are met:
Your SD card slot uses the SPI bus to connect to the microcontroller (If it uses SDIO, go to the pages
for sdioio (https://adafru.it/MA3))
Your CircuitPython board supports the sdcardio module. (If not, go to the pages for
adafruit_sdcard (https://adafru.it/MA4))
Your CicuitPython version supports the sdcardio module. Only CircuitPython 6 and newer have
sdcardio. (If not, go to the pages for adafruit_sdcard (https://adafru.it/MA4))
If the same SPI bus is shared with other peripherals, it is important that the SD card be initialized
before accessing any other peripheral on the bus. Failure to do so can prevent the SD card from being
recognized until it is powered off or re-inserted.
The following section will show how to initialize the SD card and read & write data to it. You'll want to put
the correct lines to initialize it in mount_sd.py on your CIRCUITPY drive. For specific wiring information
and exact mount_sd.py files for several different boards, check out the following pages.
Initialize & Mount SD Card Filesystem
Before you can use the microSD card you need to initialize its SPI connection and mount its filesystem.
First import all the modules we'll need:
import board
import busio
import sdcardio
import storage
Next create the SPI bus and a digital output for the microSD card's chip select line (be sure to select the
right pin names for your wiring):
# Use the board's primary SPI bus
spi = board.SPI()
# Or, use an SPI bus on specific pins:
#spi = busio.SPI(board.SD_SCK, MOSI=board.SD_MOSI, MISO=board.SD_MISO)
# For breakout boards, you can choose any GPIO pin that's convenient:
cs = board.D10
# Boards with built in SPI SD card slots will generally have a
# pin called SD_CS:
#cs = board.SD_CS
Note that when you use sdcardio , cs is a Pin object, not a DigitalInOut object. If you change your code to
© Adafruit Industries https://learn.adafruit.com/adafruit-microsd-spi-sdio Page 10 of 64

use adafruit_sdcard , you need to use a DigitalInOut object instead.
At this point you're ready to create the microSD card object and the filesystem object:
sdcard = sdcardio.SDCard(spi, cs)
vfs = storage.VfsFat(sdcard)
Notice the sdcardio module has a SDCard class which contains all the logic for talking to the microSD
card at a low level. This class needs to be told the SPI bus and chip select pin in its constructor.
After a SDCard instance is created it can be passed to the storage module's VfsFat class. This class has
all the logic for translating CircuitPython filesystem calls into low level microSD card access. Both
the SDCard and VfsFat class instances are required to mount the card as a new filesystem.
Finally you can mount the microSD card's filesystem into the CircuitPython filesystem. For example to
make the path /sd on the CircuitPython filesystem read and write from the card run this command:
storage.mount(vfs, "/sd")
At this point, you can read and write to the SD card using common Python functions like open , read , and
write . The filenames will all begin with "/sd/" to differentiate them from the files on the CIRCUITPY drive. If
you're not familiar, here's an overview.
Reading & Writing Data
Once the microSD card is mounted inside CircuitPython's filesystem you're ready to read and write data
from it Reading and writing data is simple using Python's file operations like open (https://adafru.it/reL),
close (https://adafru.it/ryE), read (https://adafru.it/ryE), and write (https://adafru.it/ryE). The beauty of
CircuitPython and MicroPython is that they try to be as similar to desktop Python as possible, including
access to files.
For example to create a file and write a line of text to it you can run:
with open("/sd/test.txt", "w") as f:
f.write("Hello world!\r\n")
Notice the with statement is used to create a context manager that opens and automatically closes the
file. This is handy because with file access you Python you must close the file when you're done or else all
the data you thought was written might be lost!
The open function is used to open the file by telling it the path to it, and the mode (w for writing). Notice
the path is under /sd, /sd/test.txt. This means the file will be created on the microSD card that was
mounted as that path.
Inside the context manager you can access the f variable to operate on the file while it's open. The write
function is called to write a line of text to the file. Notice that unlike a print statement you need to end the
string passed to write with explicit carriage returns and new lines.
You can also open a file and read a line from it with similar code:
© Adafruit Industries https://learn.adafruit.com/adafruit-microsd-spi-sdio Page 11 of 64

with open("/sd/test.txt", "r") as f:
print("Read line from file:")
print(f.readline(), end='')
When reading a line from a file with readline , the newline character '\n' at the end of the line is included.
By printing with end='' , the newline normally added by print is skipped. Otherwise, when reading back the
file, it would appear that there were extra blank lines after every line of the file.
If you wanted to read and print all of the lines from a file you could call readline in a loop. Once readline
reaches the end of the file it will return an empty string so you know when to stop:
with open("/sd/test.txt", "r") as f:
print("Printing lines in file:")
line = f.readline()
while line != '':
print(line, end='')
line = f.readline()
You can also just use the open file object in a for loop. Each time the loop runs, the loop variable will be
assigned the content of the next line of the file:
with open("/sd/test.txt", "r") as f:
print("Printing lines in file:")
for line in f:
print(line, end='')
Finally one other very common file scenario is opening a file to add new data at the end, or append data.
This works exactly the same as in Python and the open function can be told you'd like to append instead
of erase and write new data (what normally happens with the w option for open ). For example to add a
line to the file:
with open("/sd/test.txt", "a") as f:
f.write("This is another line!\r\n")
Notice the a option in the open function--this tells Python to add data at the end of the file instead of
erasing it and starting over at the top. Try reading the file with the code above to see the new line that
was added!
Those are the basics to manipulating files on microSD cards with CircuitPython! Once you have it
working, put the correct lines in mount_sd.py in CIRCUITPY, then continue learning by checking out the
example pages to print directory listings, log sensor data, play MP3 files and display bitmap graphics.
Example complete mount_sd.py
This example works on the ItsyBitsy M4 Express together with the Adafruit MicroSD Breakout Board:
© Adafruit Industries https://learn.adafruit.com/adafruit-microsd-spi-sdio Page 12 of 64

import board
import busio
import sdcardio
import storage
spi = board.SPI()
cs = board.D10
sdcard = sdcardio.SDCard(spi, cs)
vfs = storage.VfsFat(sdcard)
storage.mount(vfs, "/sd")
Your board may be different. Refer to the following pages for more details.
© Adafruit Industries https://learn.adafruit.com/adafruit-microsd-spi-sdio Page 13 of 64

ItsyBitsy M4 Express + Breakout
sdcardio is an SPI interface SD card library in CircuitPython 6.0 that is optimized in C to be much
faster than the original adafruit_sdcard library. Some much smaller/older boards don't have enough
memory for this module, in which case you will have to use adafruit_sdcard
Ready to do a little wiring? Almost any Adafruit CircuitPython board will connect to the MicroSD Breakout
Board using SPI. The following is an example using the Itsy BItsy M4 express.
Board 3V to breakout 3V via supply rail
Board GND to breakout GND via supply rail
Board MI (or MISO) to breakout SO
Board MO (or MOSI) to breakout SI
Board SCK to breakout CLK
Board D10 to breakout CS
The example below uses D10, but you can use any available
digital pin instead. Change the mount_sd.py code below to
use the pin you selected instead of board.D10 .
The ItsyBitsy and the MicroSD breakout are a great way to have SD card storage in a small footprint, but
these instructions will work with just about any Adafruit Feather too. Just follow the fritzing diagram and
then put the following in mount_sd.py:
import board
import busio
import sdcardio
import storage
spi = board.SPI()
cs = board.D10 # Use the pin you wired to the breakout CS
sdcard = sdcardio.SDCard(spi, cs)
vfs = storage.VfsFat(sdcard)
storage.mount(vfs, "/sd")
© Adafruit Industries https://learn.adafruit.com/adafruit-microsd-spi-sdio Page 14 of 64

Adafruit Micro SD SPI or SDIO Card Breakout Board - 3V ONLY!
Micro SD cards and microcontrollers go together like micro-peanutbutter-and-jelly: SD cards are
inexpensive, durable, easy to find at any shop, come in many sizes and can plug into any...
$2.95
In Stock
Your browser does not support the video tag.
Adafruit ItsyBitsy M4 Express featuring ATSAMD51
What's smaller than a Feather but larger than a Trinket? It's an Adafruit ItsyBitsy M4 Express featuring the
Microchip ATSAMD51! Small,...
$14.95
In Stock
Add to Cart
Add to Cart
© Adafruit Industries https://learn.adafruit.com/adafruit-microsd-spi-sdio Page 15 of 64

SD/MicroSD Memory Card (8 GB SDHC)
Add mega-storage in a jiffy using this 8 GB class 4 micro-SD card. It comes with a SD adapter so you can
use it with any of our shields or adapters. Preformatted to FAT so it works out...
$9.95
In Stock
Add to Cart
© Adafruit Industries https://learn.adafruit.com/adafruit-microsd-spi-sdio Page 16 of 64

Grand Central M4 Express
sdcardio is an SPI interface SD card library in CircuitPython 6.0 that is optimized in C to be much
faster than the original adafruit_sdcard library. Some much smaller/older boards don't have enough
memory for this module, in which case you will have to use adafruit_sdcard
The Adafruit Grand Central M4 Express has a built-in SD card connected to the SPI bus, so no wiring or
soldering is needed!
To mount the SD card, use the following code. Remember to put it in the file mount_sd.py on CIRCUITPY
so you can easily call it from code.py or the REPL with import mount_sd .
import board
import busio
import sdcardio
import storage
spi = busio.SPI(board.SD_SCK, MOSI=board.SD_MOSI, MISO=board.SD_MISO)
cs = board.SD_CS
sdcard = sdcardio.SDCard(spi, cs)
vfs = storage.VfsFat(sdcard)
storage.mount(vfs, "/sd")
© Adafruit Industries https://learn.adafruit.com/adafruit-microsd-spi-sdio Page 17 of 64

Adafruit Grand Central M4 Express featuring the SAMD51
Are you ready? Really ready? Cause here comes the Adafruit Grand Central featuring the Microchip
ATSAMD51. This dev board is so big, it's not...
$37.50
In Stock
Add to Cart
© Adafruit Industries https://learn.adafruit.com/adafruit-microsd-spi-sdio Page 18 of 64

SD/MicroSD Memory Card (8 GB SDHC)
Add mega-storage in a jiffy using this 8 GB class 4 micro-SD card. It comes with a SD adapter so you can
use it with any of our shields or adapters. Preformatted to FAT so it works out...
$9.95
In Stock
Add to Cart
© Adafruit Industries https://learn.adafruit.com/adafruit-microsd-spi-sdio Page 19 of 64

PyGamer
sdcardio is an SPI interface SD card library in CircuitPython 6.0 that is optimized in C to be much
faster than the original adafruit_sdcard library. Some much smaller/older boards don't have enough
memory for this module, in which case you will have to use adafruit_sdcard
The PyGamer has a built-in SD card connected to a SPI bus, so no wiring or soldering is needed!
To mount the SD card, use the following code. Remember, to put it in the file mount_sd.py on
CIRCUITPY so you can easily call it from code.py or the REPL with import mount_sd .
import board
import sdcardio
import storage
spi = board.SPI()
cs = board.SD_CS
sdcard = sdcardio.SDCard(spi, cs)
vfs = storage.VfsFat(sdcard)
storage.mount(vfs, "/sd")
Adafruit PyGamer Starter Kit
Please note: you may get a royal blue or purple case with your starter kit (they're both lovely
colors)What fits in your pocket, is fully Open...
$59.95
In Stock
© Adafruit Industries https://learn.adafruit.com/adafruit-microsd-spi-sdio Page 20 of 64