Home

Guide no. 31

Log temperatures, voltages or any other measurement on a microSD card, in a file that opens in Excel. Which card and module to use, how to connect them, and a sketch that works on both the UNO and the ESP32.

By Ada Intelisano · informaticait.it technical team

Download the PDF (A4, 4 pages) Free to print and share, without changes — CC BY-ND 4.0
In short
  • A microSD card runs at 3.3 V and draws up to 100 mA while writing: with the UNO you need a module with a regulator and a level shifter.
  • The Arduino SD library reads only FAT16 and FAT32: use a microSD card up to 32 GB (SDHC). SDXC cards come formatted as exFAT.
  • Warning: FILE_WRITE on the UNO writes at the end of the file, on the ESP32 it erases it. On the ESP32 you use FILE_APPEND.
  • The data really reaches the card only with close() or flush(). For Excel with Italian settings: semicolon and decimal comma.

The card

TypeCapacityFile systemWith the SD library
SDup to 2 GBFAT12/16yes (not FAT12 on very small cards)
SDHCfrom 2 to 32 GBFAT32yes: the right choice
SDXCfrom 32 GB to 2 TBexFATno: you need SdFat, or reformat

Classes and file systems from the SD Association. Format with its program, SD Memory Card Formatter, rather than with the operating system tools: the SD Association recommends it and so does Adafruit. The SD library uses short names (8 characters plus a 3-character extension): MISURE.CSV is fine, daily_measurements.csv is not. On the ESP32 long names work, exFAT does not.

Voltages and modules

A microSD card is powered from 2.7 to 3.6 V and its lines cannot take more than 0.3 V above its supply: the 5 V of the UNO pins must be brought down. While writing it draws up to 100 mA (Transcend, default speed mode, the one used in SPI). Adafruit recommends a sturdy 3.3 V regulator and a chip-based level shifter, not resistor dividers: recent cards want clean, sharp edges. The Adafruit 254 module does exactly that (LP2985 regulator and 74HC4050 level shifter); the DFRobot DFR0229 uses resistor dividers instead and puts CS on pin 4. For outdoor use there are industrial microSD cards rated from −40 to 85 °C.

The wiring

Arduino UNO and microSD moduleSCLSDAAREFGND131211109876543210IOREFRESET3.3V5VGNDGNDVINDIGITAL (PWM ~)POWERANALOG INUNOmicroSD5V3VGNDCLKDODICSCDAdafruit 2545V → 5VGND → GNDCLK → 13DO → 12DI → 11CS → 10informaticait.it
ModuleArduino UNOESP32-DevKitC
CLK (SCK)13GPIO 18
DO (MISO)12GPIO 19
DI (MOSI)11GPIO 23
CS10GPIO 5
5V / GND5V / GND5V / GND

On the UNO, even if you use another pin for CS, pin 10 must stay an output, otherwise the library does not work. On the ESP32 there is also the fast SD_MMC connection, but it uses pins 2 and 12, which affect boot (see guide no. 26): Espressif flags it as incompatible with the DevKitC without modifications. With an SPI module there are no problems.

The sketch

// Data logger on microSD: every 10 seconds it adds a line to the file MISURE.CSV with the time and the voltage read.
// The file uses a semicolon and a decimal comma, as Excel expects with Italian settings.
// Same sketch for Arduino UNO (CS on pin 10) and ESP32 (CS on GPIO 5).
#include <SPI.h>
#include <SD.h>

#ifdef ARDUINO_ARCH_ESP32
const int PIN_CS = 5;
const int PIN_INPUT = 34;
const char *FILE_NAME = "/MISURE.CSV";
#define APPEND_MODE FILE_APPEND      // on the ESP32 FILE_WRITE would erase the file
#else
const int PIN_CS = 10;
const int PIN_INPUT = A0;
const char *FILE_NAME = "MISURE.CSV"; // the UNO SD library wants 8.3 names
#define APPEND_MODE FILE_WRITE       // on the UNO FILE_WRITE writes at the end of the file
#endif

const unsigned long EVERY_MS = 10000;
unsigned long last = 0;

float readVolts() {
#ifdef ARDUINO_ARCH_ESP32
  return analogReadMilliVolts(PIN_INPUT) / 1000.0;
#else
  return analogRead(PIN_INPUT) * 5.0 / 1023.0;
#endif
}

void setup() {
  Serial.begin(115200);
  if (!SD.begin(PIN_CS)) {
    Serial.println("Card not found: check wires, CS and formatting (FAT32)");
    while (true) delay(1000);
  }
  if (!SD.exists(FILE_NAME)) {             // new file: the header line first
    File f = SD.open(FILE_NAME, APPEND_MODE);
    f.println("secondi;volt");             // column titles: seconds; volts
    f.close();
  }
  Serial.println("Logging started");
}

void loop() {
  if (millis() - last < EVERY_MS) return;
  last = millis();
  String value = String(readVolts(), 3);
  value.replace('.', ',');                 // decimal comma for Excel with Italian settings
  File f = SD.open(FILE_NAME, APPEND_MODE);
  if (f) {
    f.print(millis() / 1000);
    f.print(';');
    f.println(value);
    f.close();                             // close() really saves the data on the card
    Serial.println(value);
  } else {
    Serial.println("Write error");
  }
}

Every 10 seconds the sketch opens the file, adds a line and closes it: if power fails you lose at most the last measurement. Compiled for the UNO it uses 941 bytes of RAM out of 2048 (the library always keeps a 512-byte block). The time comes from millis(), which rolls back to zero after about 50 days: for a real date and time add a DS3231 (guide no. 16) or, with the ESP32, the time from the Internet (guide no. 30).

CSV and Excel

Semicolon and decimal commaMISURE.CSV (text)secondi;volt10;1,65220;1,64830;1,661ExcelItalian Excel: two columnssecondivolt101,652201,648301,661informaticait.it

The CSV format (RFC 4180) uses a comma between fields and a point for decimals. But Excel set to Italian, which uses the comma for decimals, expects a semicolon: an “international” CSV opened with a double click ends up all in one column. That is why the sketch writes 10;1,652. If the file goes to a program, a script or Excel with English settings, use the comma and the point. Otherwise, in Excel: Data › From Text/CSV and choose the delimiter.

Common mistakes

What happensWhyFix
“Card not found”wires, wrong CS, exFAT or unformatted cardcheck the wires, format FAT32 with SD Memory Card Formatter
On the ESP32 the file always has just one lineFILE_WRITE erases the file every time it is openedFILE_APPEND
Empty file after unplugging the powerdata left in memoryclose() or flush() after every write
The file is not createdname longer than 8+3 characters or folder that does not existshort name; create the folder first
Writing sometimes failsweak power supply during the 100 mA peakssuitable regulator, short wires
In Excel everything is in one columndelimiter different from the one Excel expectssemicolon, or Data › From Text/CSV
ESP32 does not start with the SD_MMC readerpull-ups on pins 2 and 12 at bootuse the SPI connection
Sources: SD Association, capacities and file systems; SD Memory Card Formatter; Transcend, microSDHC datasheet TS16GUSDHC6; Kingston, industrial microSD cards · Arduino, SD library (documentation and source code) and millis(); Bill Greiman, SdFat · Espressif, arduino-esp32 (SD, SD_MMC, FS, pins_arduino.h) and ESP-IDF (FatFs, “SD Pull-up Requirements”) · Adafruit, product 254, guide and Eagle files; DFRobot, DFR0229 (wiki and schematic) · IETF, RFC 4180 (CSV); Microsoft Support, importing and exporting CSV files and list separator

Useful products

Other guides

All our guides →
Loading...
Back to top