The microSD card provides an easy and cheap basis for microcontroller data log storage. Here's how to interface it to your microcontroller.
Serial Peripheral Interface (SPI)
SD/MMC cards (including microSD) use a fast, 4-wire, Serial Peripheral Interface or SPI bus supported by many microcontrollers.
The Arduino's AVR chips all have SPI capability in hardware and so does the mbed (ARM Cortex M3) I've been working with. PIC microcontrollers (I'm no expert) apparently have a Synchronous Serial Port (SSP) that supports SPI.
Four wires are used. !CS is an active low chip select so that you can select specific SPI devices that share the same bus. I didn't need to do that with the SD card this time around. MOSI is Master Out, Slave In. Master is the MCU, slave is the SD card. MISO is Master In, Slave Out.
I find the SPI nomenclature far more intuitive than the mind-bending RX/TX and DTE/DCE craziness of RS-232 (etc). It always takes a second to remember: do I attach RX to RX or RX to TX? And is it RX from the perspective of the pc or the micro? Gah!
Not so with SPI. Just connect MOSI to MOSI, MISO to MISO and SCK to SCK. Simple.
SD/MMC Interface
SD/MMC cards safely operate at 3.3V so interfacing to a 5V MCU is a little more complex than just wiring. More on that in a moment.
Wiring
One can buy a breakout board such as the one from Sparkfun to use microSD cards or buy a connector from DigiKey, Mouser, etc., and wire it up to a custom PCB.
The ultimate in jumper-free convenience |
Another cheap, simple approach that I discovered online is to solder 0.100" pin headers onto an SD-to-MicroSD adapter (like this one), wire it up on a breadboard or whatever, and then plug microSD cards into the adapter. See the pic below for the SD card with the pin headers soldered on.
The full size SD/MMC card or adapter has several contacts on the back. Here is the pinout:
3.3V MCU Devices
If you have a 3.3V MCU, then connect MOSI to your MCU's MOSI pin, MISO to MISO, SCK to SCK. You can either attach !CS to a pin on the MCU, to a mux (like a 74*151), or hardwire it to ground if it's the only thing on the SPI bus.
5V MCU Devices
Voltage level shifting from 5V down to the SD card's 3.3V can be done in several ways. A simple resistor voltage divider seems to be adequate but could limit data rate. You really only need to level shift the lines going from the MCU to the SD card: MOSI and SCK. Most MCUs should read the correct levels on the 3.3V MISO line.
Here's a good tutorial with some other interfacing options for level shifting. My eeZee MicroSD above has a 3.3V regulator and level shifter IC built-in so it's 5V safe.
A couple of other possibilities are the use of level shifting chips. The Propeller Robot Control Board uses bi-directional Texas Instruments TXB0108 chips, for example. You can also use a 74*244 or 74*245.
Software Interface
Once the card is wired up, you can't just throw data at it. The card has to be formatted with a FAT16 or FAT32 filesystem and the Arduino has to run FAT filesystem code to create/append files. That is, if you want to pull data off the card using your PC or Mac.
FAT16 can only handle volumes up to 2G in size. Arduino users can incorporate the small-footprint fat16lib or SDuFAT library for use with these smaller cards. When formatting the card on XP, select "FAT" as the filesystem type.
I discovered after some testing that I had to use FAT32 software, and a larger Arduino FAT library, sdfatlib, with my 4G card.
Case Study
So why am I so interested in data logging all of a sudden? I've entered the Sparkfun Autonomous Vehicle Competition (AVC) for 2011. The design for my robot's navigation system combines a rate gyro sensor and GPS, and likely other sensors, to be fused algorithmically.
I want to collect gyro and GPS data from real test runs and then in the comfort of my home, write prototype code to process the data to estimate heading and position. I'd previously interfaced the rate gyro and the GPS to the Arduino but I needed a cheap and easy way to store the data for later download and analysis. Using an SD card was ideal.
For my project, the Sparkfun AVC robot, I found an SD card and adapter on sale at Radio Shack and I breadboarded everything, drawing 3.3V from the SMT regulator I was already using to power the LISY300AL gyro.
I used a simple voltage divider on the !CS, MOSI, and SCK lines, consisting of 330 ohm and 180 ohm resistors (sacrificing power consumption for speed, I suppose; 5V/500 ohms = ~10mA)
I added a couple of indicator LEDs for power and data transmission. The data LED indicators are powered with small signal BJTs, the bases of which are connected to MISO and MOSI, respectively, through 1K current limiting resistors.
After some testing on the bench, it was time for the maiden voyage. I had to mount all the electronics onto the RC truck chassis: SD card breadboard, Arduino, and GPS. Then I had to merge prototype code for the gyro, gps, and FAT32 filesystem. Then, finally, drive the RC Truck around and gather some data to analyze.
More on the data capture and analysis next time.