Learn

Log to an SD card: a GPS data logger on an Arduino Mega

Advanced

Or see every lesson.

  • 261parts on the bench
  • 31boards running now
  • 1.00xreal time, on every board
Arduino Mega: GPS logger on a microSD cardlive0.000 s 0.00x
Watch TRACK.CSV grow beside the card, and click it to download
The GPS logger example on a simulated ATmega2560. Every new position is added to TRACK.CSV on the card.

A microSD card module lets your Arduino save data that you can open later on a computer: temperature every minute, a GPS track, or a log of when a door opened. The SD library makes it simple. Open a file, print to it like the serial monitor, and close it.

The circuit above is an Arduino Mega with a NEO-6M GPS module and a microSD card module. Once a second the GPS reports a new position, and the sketch adds a line to TRACK.CSV on the card. The file grows in a list beside the card, and you can click it to download it and open it in a spreadsheet. It runs in your browser on the sketch below.

What you need

  • An Arduino Mega 2560 (an Uno works for the SD card alone)
  • A microSD card module (SPI) and a microSD card formatted FAT16 or FAT32
  • A NEO-6M GPS module, for this project
  • A half-size breadboard and jumper wires

Wiring

Part and pinGoes toNote
SD CSPin 53Chip select on a Mega; pin 4 or 10 is usual on an Uno
SD SCKPin 52SPI clock on a Mega (pin 13 on an Uno)
SD MOSIPin 51Data to the card on a Mega (pin 11 on an Uno)
SD MISOPin 50Data from the card on a Mega (pin 12 on an Uno)
SD VCC and GND5 V and GNDThe module has its own 3.3 V regulator
GPS TXPin 19 (RX1)The GPS talks to the Mega’s second serial port
GPS VCC and GND5 V and GNDThe breakout has its own regulator

Open, print, close

Start the card once in setup() with SD.begin(csPin). It returns true if the card answered. The sketch prints "Card ready." when it does. Turn off the card module’s inserted property in the editor and run again, and it prints "No card: positions go to the serial monitor only." instead.

To write, open the file with FILE_WRITE. That adds to the end of the file, so old lines stay. Then use print() and println() on the file, exactly like Serial. Always close() the file when you are done. Until you close it or call flush(), some of what you wrote may still be in memory, not on the card.

Adding lines to a file, from the GPS logger example
#include <SPI.h>
#include <SD.h>

const int CARD_CS = 53;

void setup() {
  Serial.begin(9600);
  bool cardReady = SD.begin(CARD_CS);
  Serial.println(cardReady ? "Card ready." : "No card");
  File file = SD.open("track.csv", FILE_WRITE);
  if (file) {
    if (file.size() == 0) {
      file.println("time,lat,lng,kmh");
    }
    file.close();
  }
}

Why the logger writes five lines at a time

Writing to a card takes time, and the GPS does not wait. While the sketch is busy writing, bytes from the GPS pile up in a 64-byte buffer, and anything past that is lost. So the sketch keeps each new line in memory and writes them to the card five at a time.

This is a real pattern for any logger that also has to keep up with something else. Real cards are also slow now and then: a write can take much longer while the card erases. In Mokxi the card is slower in a different way, because the Mega’s SPI is done in software here, so the batching matters on both.

What goes in the file

Each line is the time, the latitude, the longitude and the speed, split by commas: a CSV file. In our run the first lines read "12:00:04,38.889832,-77.035233,36.0" and then one more every second. Any spreadsheet opens it, and most mapping tools can draw the track.

The GPS module in Mokxi has no sky. Its position is a setting, and its speed and course settings move it along a heading once a second. Click the GPS to take its fix away. The sketch prints "No fix yet." and logs nothing until the fix comes back.

Why this project uses a Mega

The GPS needs a serial port. The Uno has only one, and the serial monitor uses it. The Mega has four serial ports, so the GPS gets Serial1. On an Uno, the GPS gets a SoftwareSerial port instead. The NEO-6M GPS tutorial shows that way.

The SD card part works on an Uno too. Use pins 13, 11 and 12 for SCK, MOSI and MISO, and pin 4 or 10 for CS.

Common mistakes

SD.begin() fails. Check the CS pin number, the wiring, and that the card is formatted FAT16 or FAT32. Most libraries cannot read exFAT, the format large new cards often come with.

Forgetting close(). The last lines never reach the card.

Long file names. The SD library uses 8.3 names: up to eight letters, a dot and three more, like TRACK.CSV.

Opening the file once and never closing it in a long run. If the power goes, everything since the last flush() is lost.

Questions

Which pins does an SD card module use on an Arduino?

The SPI pins, plus a chip select you choose. On an Uno: SCK 13, MOSI 11, MISO 12 and CS usually 4 or 10. On a Mega: SCK 52, MOSI 51, MISO 50 and CS 53.

What format should the SD card be?

FAT16 or FAT32. The card in Mokxi is a 4 MB FAT16 card, and you can download it as a disk image any computer can open.

Can I add my own files to the simulated card?

Yes. The + button beside the card adds a file, and the files property sets what is on it before a run. A sketch can read them with SD.open() and read().

What does Mokxi not model on the SD card?

High-capacity SDHC cards, FAT32, long file names, and the slow, uneven write times of real cards.

Build this for real

Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.