Imagine a project like a weather monitoring station that records temperature and humidity every few seconds. The built-in memory of an Arduino board is too limited to handle this amount of data.
So, how can we add more storage?
The simplest option is to use a Micro SD card—the same small card that goes into cameras and smartphones. These cards can store a large amount of data, ranging from a few MBs to several GBs. By using an SD card module, you can easily connect a Micro SD card to your Arduino and give your projects reliable data logging capability.
In this guide, we’ll go step by step to understand the Micro SD card module and learn how to connect it with Arduino.
Hardware Overview of Micro SD Card ModuleA standard SD card module usually consists of:
- Micro SD Card Socket – The slot where the memory card is inserted. Most modules have clear markings to show the correct orientation.
- 3.3V LDO Voltage Regulator – SD cards work at 3.3V, so this regulator safely reduces the Arduino’s 5V supply to 3.3V and keeps the voltage stable even if the input fluctuates.
- Logic Level Shifter (74LVC125A) – Since Arduino works with 5V logic, this chip shifts the 5V signals down to 3.3V so the SD card can communicate without getting damaged.
The pins of a Micro SD card module are:
- GND – Connect to Arduino ground
- VCC – Connect to Arduino 5V pin
- MISO (Master In Slave Out) – Transfers data from SD card to Arduino
- MOSI (Master Out Slave In) – Transfers data from Arduino to SD card.
- SCK (Serial Clock) – Receives clock signal from Arduino for synchronization
- CS (Chip Select) – Enables or disables the SD card module during SPI communication
Once you understand the working of the module, the next step is to connect it with an Arduino UNO. We’ll also use a 16x2 LCD with I2C interface to display the results.
The SD card module communicates using the SPI protocol, which means it relies on the SPI pins such as MOSI, MISO, SCK, and CS for data transfer. Although SD cards can also operate in SDIO (Secure Digital Input Output) mode, this tutorial will only focus on the SPI method.
To power the module, two additional connections—VCC (5V) and GND—are required.
Arduino UNO to SD Card Module ConnectionsConnecting an I2C LCD is straightforward. The VCC and GND pins of the LCD are connected to the 5V and GND pins of Arduino. For data transfer, the SCL (clock) and SDA (data) pins of the LCD are linked to Arduino’s SCL and SDA pins. On the Arduino UNO, these are the A5 (SCL) and A4 (SDA) pins, respectively.
⚠️ Important: Ensure the A0, A1, and A2 address jumpers on the I2C LCD are left open (not shorted). In this configuration, the LCD will operate with the default I2C address 0x27, which we’ll use in the code.
Arduino Code for checking Micro SD card Information/*
Code to get info about SD card and for testing if its working or not
by platwithcircuit.com
*/
#include <SPI.h>
// include SPI library header
#include <SD.h>
// include the SD library header
#include <LiquidCrystal_I2C.h>
// include I2C LCD library header
// set up variables using the SD utility library functions
Sd2Card card;
SdVolume volume;
SdFile root;
// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int chipSelect = 10;
void setup() {
// initialize the LCD
lcd.init();
// Turn ON the Backlight
lcd.backlight();
// Clear the display buffer
lcd.clear();
// Print a message to the LCD
lcd.setCursor(0, 0);
lcd.print("Initializing");
lcd.setCursor(0, 1);
lcd.print("SD Card...");
// Open serial communications and wait for port to open
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect
}
Serial.print("\nInitializing SD card...");
delay(1000);
// we'll use the initialization code from the utility libraries
// since we're just testing if the card is working!
if (!card.init(SPI_HALF_SPEED, chipSelect)) {
Serial.println("initialization failed. Things to check:");
Serial.println("* is a card inserted?");
Serial.println("* is your wiring correct?");
Serial.println("* did you change the chipSelect pin to match your shield or module?");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Initialization");
lcd.setCursor(0, 1);
lcd.print("Failed");
while (1)
;
} else {
Serial.println("Wiring is correct and a card is present.");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Initialization");
lcd.setCursor(0, 1);
lcd.print("Successfull");
delay(2000);
}
// print the type of card
Serial.println();
Serial.print("Card type: ");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Card Type:");
lcd.setCursor(0, 1);
switch (card.type()) {
case SD_CARD_TYPE_SD1:
Serial.println("SD1");
lcd.print("SD1");
break;
case SD_CARD_TYPE_SD2:
Serial.println("SD2");
lcd.print("SD2");
break;
case SD_CARD_TYPE_SDHC:
Serial.println("SDHC");
lcd.print("SDHC");
break;
default:
Serial.println("Unknown");
lcd.print("Unknown");
}
delay(2000);
// Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
if (!volume.init(card)) {
Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
while (1)
;
}
Serial.print("Clusters: ");
Serial.println(volume.clusterCount());
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Clusters:");
lcd.setCursor(0, 1);
lcd.print(volume.clusterCount());
delay(2000);
Serial.print("Blocks per Cluster: ");
Serial.println(volume.blocksPerCluster());
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Block per Clster");
lcd.setCursor(0, 1);
lcd.print(volume.blocksPerCluster());
delay(2000);
Serial.print("Total Blocks: ");
Serial.println(volume.blocksPerCluster() * volume.clusterCount());
Serial.println();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Total Blocks:");
lcd.setCursor(0, 1);
lcd.print(volume.blocksPerCluster() * volume.clusterCount());
delay(2000);
// print the type and size of the first FAT-type volume
uint32_t volumesize;
Serial.print("Volume type is: FAT");
Serial.println(volume.fatType(), DEC);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Volume type is:");
lcd.setCursor(0, 1);
lcd.print("FAT");
lcd.print(volume.fatType(), DEC);
delay(2000);
volumesize = volume.blocksPerCluster(); // clusters are collections of blocks
volumesize *= volume.clusterCount(); // we'll have a lot of clusters
volumesize /= 2; // SD card blocks are always 512 bytes (2 blocks are 1KB)
Serial.print("Volume size (KB): ");
Serial.println(volumesize);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Volume size (KB):");
lcd.setCursor(0, 1);
lcd.print(volumesize);
delay(2000);
Serial.print("Volume size (MB): ");
volumesize /= 1024;
Serial.println(volumesize);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Volume size (MB):");
lcd.setCursor(0, 1);
lcd.print(volumesize);
delay(2000);
Serial.print("Volume size (GB): ");
Serial.println((float)volumesize / 1024.0);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Volume size (GB):");
lcd.setCursor(0, 1);
lcd.print((float)volumesize / 1024.0);
delay(2000);
Serial.println("\nFiles found on the card (name, date and size in bytes): ");
root.openRoot(volume);
// list all files in the card with date and size
root.ls(LS_R | LS_DATE | LS_SIZE);
}
void loop(void) {
}
Output
To learn how to Read-Write Data on Micro SD Card checkout: How to Interface Micro SD Card Module with Arduino
Comments