Módulo micro SD Arduino: datalogger CSV con RTC y errores comunes
Módulo micro SD con Arduino: pines SPI, formato FAT32, datos de sensores en CSV con hora del RTC, ESP32 SD_MMC, Pico y cómo resolver initialization failed.
El módulo micro SD para Arduino es una placa pequeña y barata que te permite guardar como archivos en una tarjeta micro SD las lecturas de temperatura, humedad, distancia o posición de tus sensores. Es la forma más sencilla de montar un registrador de datos (datalogger) que mide durante días o incluso meses sin ordenador conectado: Arduino toma las medidas, el módulo escribe cada una como una nueva línea en un archivo CSV de la tarjeta, y luego tú metes la tarjeta en el ordenador y haces un gráfico en Excel. El módulo se conecta por SPI y funciona con unas pocas líneas de código gracias a la librería SD que ya viene con el IDE de Arduino.
En esta guía aprenderás paso a paso cómo funciona el módulo, la diferencia entre módulos de 5V y 3.3V, la conexión SPI para Arduino Uno, Mega, ESP32 y Raspberry Pi Pico, cómo formatear la tarjeta en FAT32, cómo escribir y leer archivos y cómo llevar un registro CSV con fecha y hora usando un módulo RTC. También vemos la rápida interfaz SD_MMC del ESP32, el uso de la tarjeta SD en la Pico con MicroPython y cómo resolver el error tan habitual "initialization failed".

¿Qué es un módulo de tarjeta SD y cómo funciona?
Las tarjetas SD funcionan a 3,3 V y pueden comunicarse de dos maneras: el modo SD nativo, más rápido, y el modo SPI, más sencillo. Los microcontroladores como Arduino hablan con la tarjeta por SPI. La tarea del módulo es hacer que ambos sean compatibles eléctricamente: su regulador baja los 5 V a los 3,3 V que necesita la tarjeta, y un chip conversor de nivel (normalmente un 74LVC125A) convierte las señales de 5 V de Arduino a 3,3 V que la tarjeta puede soportar. Por dentro, la tarjeta está formada por bloques de 512 bytes, mientras que los archivos, carpetas y nombres los gestiona el sistema de archivos FAT. La librería SD hace todo este trabajo complicado por ti; tú solo abres un archivo, escribes en él y lo cierras.
| Característica | Valor |
|---|---|
| Interfaz | SPI (MISO, MOSI, SCK, CS) |
| Alimentación (módulo micro SD con regulador) | 4,5–5,5 V, regulador de 3,3 V en la placa |
| Nivel de señal | Compatible con 3,3 V y 5 V (gracias al conversor de nivel) |
| Tarjetas compatibles | micro SD (hasta 2 GB) y micro SDHC (4–32 GB) |
| Sistema de archivos | FAT16 o FAT32 |
| Consumo | Unos pocos mA en reposo, hasta 100 mA al escribir |
| Nombre de archivo (librería SD de Arduino) | Formato 8.3: hasta 8 caracteres de nombre + 3 de extensión |
Módulo SD de 5V o de 3.3V: ¿cuál deberías comprar?
| Tipo de módulo | Alimentación | Nivel de señal | Ideal para |
|---|---|---|---|
| Módulo micro SD con regulador (74LVC125A) | 5 V | 3,3 V y 5 V | Uno, Nano, Mega; ESP32 y Pico si se alimenta a 5 V |
| Módulo SD de tamaño completo (pines +5 y +3.3) | 5 V o 3,3 V | La mayoría no tiene conversor de nivel real | Placas de 3,3 V; poco fiable con señales de 5 V |
| Módulo micro SD sin regulador (solo la ranura) | Solo 3,3 V | Solo 3,3 V | ESP32, Raspberry Pi Pico |
| Placas con ranura integrada (como la ESP32-CAM) | Desde la placa | 3,3 V | Se usa directamente con SD_MMC |
Si usas un Arduino Uno, Nano o Mega, elige un módulo micro SD con regulador y conversor de nivel como el de la foto y conecta VCC al pin 5V. El ESP32 y la Pico funcionan a 3,3 V; también puedes usar el mismo módulo con ellos, pero conviene alimentarlo igualmente a 5 V (VIN en el ESP32, VBUS en la Pico cuando se alimenta por USB). Como el conversor de nivel funciona a 3,3 V, la señal MISO que vuelve al microcontrolador ya sale a 3,3 V. Los módulos sin regulador se conectan directamente al pin 3V3; si tienes que usar uno con un Arduino de 5 V, pon un divisor de tensión de 1 kΩ + 2 kΩ en cada una de las líneas MOSI, SCK y CS, o usa un conversor de nivel lógico. Puedes comprobar los valores de las resistencias con la calculadora de divisor de tensión.
Conexión del módulo SD: pines SPI
| Pin del módulo | Arduino Uno / Nano | Arduino Mega | ESP32 | Raspberry Pi Pico |
|---|---|---|---|---|
| GND | GND | GND | GND | GND |
| VCC | 5V | 5V | VIN (5 V) | VBUS (5 V) |
| MISO | D12 | D50 | GPIO 19 | GP16 |
| MOSI | D11 | D51 | GPIO 23 | GP19 |
| SCK | D13 | D52 | GPIO 18 | GP18 |
| CS | D10 | D53 | GPIO 5 | GP17 |
MISO, MOSI y SCK deben ir a los pines SPI por hardware en todas las placas; CS (chip select) puede ser cualquier pin digital, siempre que pongas el mismo número en SD.begin() en tu código. En los shields comerciales CS suele ser D4 o D10. Puedes conectar varios dispositivos al mismo bus SPI: todos comparten MISO, MOSI y SCK, y cada uno tiene su propio pin CS. Explicamos en detalle cómo funciona el SPI en comunicación SPI. Para ver dónde están los pines en tu placa, usa la herramienta de pinout.
Preparar la tarjeta SD: formatear en FAT32
- Tamaño de la tarjeta: elige una micro SDHC de entre 4 y 32 GB. La librería SD de Arduino admite tarjetas SDSC (hasta 2 GB) y SDHC; las SDXC de 64 GB o más vienen de fábrica en exFAT, y esta librería no puede leer exFAT.
- Sistema de archivos: formatea la tarjeta en FAT32 (en tarjetas de 2 GB o menos también sirve FAT16). NTFS y exFAT no funcionan.
- Windows: en el Explorador de archivos haz clic derecho sobre la tarjeta, elige Formatear y selecciona FAT32 como sistema de archivos con el tamaño de unidad de asignación predeterminado. En tarjetas de más de 32 GB, Windows no ofrece FAT32.
- macOS: selecciona la tarjeta en la Utilidad de Discos, pulsa Borrar y elige MS-DOS (FAT) como formato y Registro de arranque maestro como esquema.
- La opción más segura: el programa gratuito SD Card Formatter de la SD Association formatea la tarjeta según el estándar y elimina la mayoría de los errores extraños.
- Una sola partición: la tarjeta debe tener una única partición. Las tarjetas usadas antes en una Raspberry Pi o una cámara pueden conservar varias; bórralas antes de formatear.
Primera prueba paso a paso: escribir y leer en la tarjeta SD
- Inserta la tarjeta formateada en el módulo y conéctalo al Arduino según la tabla anterior.
- La librería SD viene con el IDE de Arduino, así que no hay que instalar nada; solo se incluyen SPI.h y SD.h al principio del sketch.
- Sube el código siguiente y abre el Monitor Serie a 9600 baudios.
- Si ves "tamam" (OK) y el contenido del archivo, la tarjeta y las conexiones están bien. Cada vez que la placa arranca se añade una nueva línea a TEST.TXT.
- Cuando saques la tarjeta y la metas en el ordenador, podrás abrir TEST.TXT con cualquier editor de texto.
1#include <SPI.h>
2#include <SD.h>
3
4const int CS_PIN = 10; // modülün CS pini / module CS pin
5
6void setup() {
7 Serial.begin(9600);
8 Serial.print(F("SD kart baslatiliyor... "));
9 if (!SD.begin(CS_PIN)) { // kart başlatılamadı / card init failed
10 Serial.println(F("initialization failed"));
11 while (true); // burada dur / stop here
12 }
13 Serial.println(F("tamam"));
14
15 File dosya = SD.open("TEST.TXT", FILE_WRITE); // yoksa oluşturur, sona ekler / creates it, appends
16 if (dosya) {
17 dosya.println(F("Merhaba BlueGrays!"));
18 dosya.close(); // tamponu karta yazar / flushes the buffer to the card
19 Serial.println(F("TEST.TXT yazildi"));
20 } else {
21 Serial.println(F("TEST.TXT acilamadi")); // dosya açılamadı / could not open file
22 }
23
24 dosya = SD.open("TEST.TXT"); // okumak için aç / open for reading
25 if (dosya) {
26 Serial.print(F("Boyut (bayt): "));
27 Serial.println(dosya.size());
28 while (dosya.available()) {
29 Serial.write(dosya.read()); // içeriği seri porta yaz / print contents to serial
30 }
31 dosya.close();
32 }
33}
34
35void loop() {
36}| Función | Qué hace |
|---|---|
| SD.begin(cs) | Inicializa la tarjeta; devuelve true si lo consigue |
| SD.open("NOMBRE.TXT", FILE_WRITE) | Abre el archivo para escribir; lo crea si no existe y, si existe, añade al final |
| SD.open("NOMBRE.TXT") | Abre el archivo para leer (FILE_READ) |
| archivo.print() / println() | Escribe texto o un número en el archivo |
| archivo.flush() | Escribe en la tarjeta los datos del búfer sin cerrar el archivo |
| archivo.close() | Escribe los datos pendientes en la tarjeta y cierra el archivo |
| archivo.available() / read() | Comprueba si quedan bytes por leer / lee un byte |
| SD.exists() / SD.remove() / SD.mkdir() | Comprueba si un archivo existe / borra un archivo / crea una carpeta |
Guardar datos de sensores en CSV con marca de tiempo del RTC
El formato más práctico para un datalogger es CSV (valores separados por comas): cada línea es una medida, cada columna un valor, y la primera línea lleva los títulos de las columnas. Para saber cuándo se tomó cada lectura, debes añadir la fecha y la hora a cada línea. millis() solo indica el tiempo desde que se encendió el Arduino y vuelve a cero con cada reinicio, por eso usamos un módulo RTC (reloj de tiempo real) con pila de botón. El RTC sigue contando aunque el Arduino esté apagado. El DS1307 es barato, pero puede desviarse unos segundos al día; el DS3231, gracias a su cristal con compensación de temperatura, solo se desvía alrededor de un minuto al año. Los comparamos en módulos de reloj RTC.

El circuito: el módulo SD va a los pines SPI como en la tabla anterior, el módulo RTC al bus I2C (en el Uno SDA = A4, SCL = A5, VCC = 5V) y el pin de datos del sensor DHT22 a D2; si usas el sensor sin placa, añade una resistencia de 10 kΩ entre el pin de datos y VCC. Instala las librerías RTClib (Adafruit) y DHT sensor library desde el Gestor de bibliotecas. Para los detalles de conexión del sensor, consulta sensor de temperatura y humedad DHT11 y DHT22.
1#include <SPI.h>
2#include <SD.h>
3#include <Wire.h>
4#include <RTClib.h>
5#include <DHT.h>
6
7const int CS_PIN = 10; // SD modülü CS / SD module CS
8const unsigned long ARALIK = 10000; // 10 saniyede bir kayıt / log every 10 seconds
9
10RTC_DS1307 rtc; // DS3231 için RTC_DS3231 / RTC_DS3231 for a DS3231
11DHT dht(2, DHT22); // veri pini D2, DHT11 de olur / data pin D2, DHT11 also works
12unsigned long sonKayit = 0;
13
14void setup() {
15 Serial.begin(9600);
16 dht.begin();
17 if (!rtc.begin()) {
18 Serial.println(F("RTC bulunamadi")); // RTC yok / RTC not found
19 while (true);
20 }
21 if (!rtc.isrunning()) { // saat hiç kurulmamış / clock never set
22 rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // derleme anına kur / set to compile time
23 }
24 if (!SD.begin(CS_PIN)) {
25 Serial.println(F("SD kart hatasi")); // SD başlatılamadı / SD init failed
26 while (true);
27 }
28 if (!SD.exists("VERI.CSV")) { // yeni dosyaya başlık satırı / header row for a new file
29 File f = SD.open("VERI.CSV", FILE_WRITE);
30 if (f) {
31 f.println(F("tarih,saat,sicaklik_C,nem_yuzde"));
32 f.close();
33 }
34 }
35}
36
37void loop() {
38 if (millis() - sonKayit < ARALIK) return; // zamanı gelmedi / not time yet
39 sonKayit = millis();
40
41 float t = dht.readTemperature();
42 float h = dht.readHumidity();
43 if (isnan(t) || isnan(h)) { // sensör okunamadı / sensor read failed
44 Serial.println(F("DHT okuma hatasi"));
45 return;
46 }
47
48 DateTime simdi = rtc.now();
49 char ts[8], hs[8], satir[48];
50 dtostrf(t, 1, 1, ts); // AVR'de sprintf %f desteklemez / AVR sprintf has no %f
51 dtostrf(h, 1, 1, hs);
52 snprintf(satir, sizeof(satir), "%04d-%02d-%02d,%02d:%02d:%02d,%s,%s",
53 simdi.year(), simdi.month(), simdi.day(),
54 simdi.hour(), simdi.minute(), simdi.second(), ts, hs);
55
56 File f = SD.open("VERI.CSV", FILE_WRITE); // sona ekle / append
57 if (f) {
58 f.println(satir);
59 f.close(); // her kayıtta kapat: güç kesilse de veri kalır / close every time so data survives a power cut
60 Serial.println(satir);
61 } else {
62 Serial.println(F("VERI.CSV acilamadi"));
63 }
64}Cada 10 segundos el código lee la temperatura y la humedad, obtiene la fecha y la hora del RTC y añade al final de VERI.CSV una línea como 2026-11-04,14:05:30,23.5,45.2. Como el archivo se cierra después de cada registro, los datos guardados hasta ese momento sobreviven incluso a un corte de luz. En las placas AVR sprintf() no admite números decimales (%f), por eso los valores se convierten antes en texto con dtostrf(). Como la espera se hace con millis() en lugar de delay(), puedes hacer otras tareas dentro de loop(). Si el RTC nunca se ha ajustado, se pone en hora con el momento en que se compiló el código. Si usas un DS3231, basta con escribir RTC_DS3231 en lugar de RTC_DS1307 y comprobar lostPower() en vez de isrunning().
¿Cuánto espacio ocupa? Cada línea tiene unos 31 bytes. Con un registro cada 10 segundos se generan 8.640 líneas al día, unos 260 KB; en un año son aproximadamente 95 MB. Es decir, a este ritmo una tarjeta de 8 GB dura décadas. El verdadero límite no es la tarjeta sino la alimentación: si el proyecto va a funcionar con pilas, calcula antes cuánto durarán con la calculadora de duración de batería.
Abrir en Excel los datos de la tarjeta SD
- Desconecta la alimentación del Arduino, saca la tarjeta del módulo y métela en el ordenador.
- Copia VERI.CSV al ordenador; es más seguro trabajar con una copia que directamente sobre la tarjeta.
- Abre un libro en blanco en Excel y elige el archivo con Datos > Desde el texto/CSV.
- En la ventana de vista previa selecciona Coma como delimitador y pulsa Cargar; las columnas se separan en fecha, hora, temperatura y humedad.
- Selecciona las columnas de temperatura y humedad e inserta un gráfico de líneas desde la pestaña Insertar para ver su evolución en el tiempo.
1// Excel'de ondalık ayırıcı virgülse / if Excel uses a decimal comma
2// Bu iki fonksiyonu kayıt kodunda loop()'un üstüne ekle / add these two functions above loop() in the logging sketch
3void noktayiVirgulYap(char *s) {
4 for (; *s; s++) {
5 if (*s == '.') *s = ','; // 23.5 -> 23,5
6 }
7}
8
9void excelSatiri(char *satir, size_t boyut, const DateTime &simdi, char *ts, char *hs) {
10 noktayiVirgulYap(ts);
11 noktayiVirgulYap(hs);
12 snprintf(satir, boyut, "%04d-%02d-%02d;%02d:%02d:%02d;%s;%s", // ayırıcı ; / separator ;
13 simdi.year(), simdi.month(), simdi.day(),
14 simdi.hour(), simdi.minute(), simdi.second(), ts, hs);
15}
16
17// loop() içinde snprintf satırının yerine / in loop(), replace the snprintf line with:
18// excelSatiri(satir, sizeof(satir), simdi, ts, hs);
19// Başlık satırı da / header row too: tarih;saat;sicaklik_C;nem_yuzdeSi prefieres enviar las lecturas a Excel en directo mientras el Arduino está conectado al ordenador, sin sacar la tarjeta, echa un vistazo a los métodos con Data Streamer y PLX-DAQ en enviar datos de Arduino a Excel. La tarjeta SD, en cambio, es imprescindible en los proyectos que funcionan sobre el terreno, lejos de cualquier ordenador.
Usar una tarjeta SD con el ESP32 (SPI)
El núcleo Arduino del ESP32 trae su propia librería SD y se usa casi igual, pero con tres diferencias importantes: las rutas empiezan por / ("/olcumler.csv"), se permiten nombres largos y FILE_WRITE sobrescribe el archivo desde cero. Para añadir al final tienes que usar FILE_APPEND; si copias el código del Uno tal cual, tus datos antiguos se borrarán en cada arranque. Los pines SPI por defecto son SCK 18, MISO 19 y MOSI 23, y para CS se suele usar el GPIO 5. El tipo y el tamaño de la tarjeta también se leen con una sola línea:
1#include <SPI.h>
2#include <SD.h>
3
4const int CS_PIN = 5; // VSPI: SCK 18, MISO 19, MOSI 23 / default VSPI pins
5const char *DOSYA = "/olcumler.csv"; // yol / ile başlar / path starts with /
6
7void setup() {
8 Serial.begin(115200);
9 if (!SD.begin(CS_PIN)) { // varsayılan SPI hızı 4 MHz / default SPI clock 4 MHz
10 Serial.println("Card Mount Failed");
11 return;
12 }
13 uint8_t tur = SD.cardType();
14 if (tur == CARD_NONE) {
15 Serial.println("Kart takili degil"); // kart yok / no card inserted
16 return;
17 }
18 Serial.printf("Kart tipi: %s\n", tur == CARD_SDHC ? "SDHC" : (tur == CARD_SD ? "SDSC" : "MMC"));
19 Serial.printf("Boyut: %llu MB\n", SD.cardSize() / (1024 * 1024));
20
21 if (!SD.exists(DOSYA)) { // uzun dosya adı serbest / long file names are fine
22 File f = SD.open(DOSYA, FILE_WRITE); // FILE_WRITE dosyayı sıfırlar / FILE_WRITE truncates
23 if (f) {
24 f.println("sure_s,isik_ham");
25 f.close();
26 }
27 }
28}
29
30void loop() {
31 File f = SD.open(DOSYA, FILE_APPEND); // ESP32'de sona ekleme / append on ESP32
32 if (f) {
33 f.printf("%lu,%d\n", millis() / 1000, analogRead(34)); // GPIO34'teki LDR / LDR on GPIO34
34 f.close();
35 }
36 delay(5000);
37}El código guarda cada 5 segundos el valor en bruto (0–4095) de una LDR conectada al GPIO 34. En el ESP32 ni siquiera necesitas un módulo RTC para tener la hora real: puede conectarse al Wi-Fi, obtener la hora de un servidor NTP y añadir una marca de tiempo a cada línea con getLocalTime(). Si los cables son largos o la tarjeta falla a ratos, baja la velocidad del SPI: SD.begin(5, SPI, 1000000) inicia la tarjeta a 1 MHz. En un registrador a pilas, usar deep sleep entre lecturas multiplica la duración de la batería.
ESP32 SD_MMC: la interfaz SD rápida y la ESP32-CAM
Además del SPI, el ESP32 tiene un controlador SDMMC que habla el protocolo rápido propio de la tarjeta. En modo de 4 bits, la librería SD_MMC es varias veces más rápida que el SPI, ideal para archivos grandes como fotos o audio. En el ESP32 clásico los pines son fijos: CLK GPIO 14, CMD GPIO 15, D0 GPIO 2, D1 GPIO 4, D2 GPIO 12 y D3 GPIO 13, y estas líneas necesitan resistencias pull-up de 10 kΩ. En modo de 1 bit solo se usan CLK, CMD y D0; es más lento, pero quedan libres los GPIO 4, 12 y 13. La ranura micro SD de la ESP32-CAM está conectada a estos pines, y usar el modo de 1 bit evita que el LED del flash del GPIO 4 parpadee cada vez que se accede a la tarjeta.
1#include "FS.h"
2#include "SD_MMC.h"
3
4void setup() {
5 Serial.begin(115200);
6 // 1-bit mod: yalnız CLK 14, CMD 15, D0 2 / 1-bit mode: only CLK 14, CMD 15, D0 2
7 if (!SD_MMC.begin("/sdcard", true)) {
8 Serial.println("SD_MMC baglanamadi"); // kart bağlanamadı / mount failed
9 return;
10 }
11 Serial.printf("Bos alan: %llu MB\n", (SD_MMC.totalBytes() - SD_MMC.usedBytes()) / (1024 * 1024));
12
13 File f = SD_MMC.open("/gunluk.txt", FILE_APPEND);
14 if (f) {
15 f.println("ESP32-CAM acildi"); // açılış kaydı / boot log line
16 f.close();
17 }
18}
19
20void loop() {
21}Tarjeta SD con la Raspberry Pi Pico (MicroPython)
En MicroPython la tarjeta SD se maneja con el controlador sdcard.py de micropython-lib. Si tienes mpremote en el ordenador, instálalo con mpremote mip install sdcard, o copia el archivo a la Pico con Thonny. La tarjeta se monta como la carpeta /sd con os.mount() y a partir de ahí se usa con los comandos de archivo normales de Python (open, write). El código siguiente lee el sensor de temperatura interno de la Pico y escribe una línea CSV cada 10 segundos. Si la Pico es nueva para ti, lee primero qué es la Raspberry Pi Pico.
1from machine import Pin, SPI, ADC
2import os, time
3import sdcard # micropython-lib sürücüsü / micropython-lib driver
4
5spi = SPI(0, baudrate=1000000, sck=Pin(18), mosi=Pin(19), miso=Pin(16))
6sd = sdcard.SDCard(spi, Pin(17, Pin.OUT)) # CS = GP17; kart yoksa OSError / OSError if no card
7os.mount(os.VfsFat(sd), "/sd") # kart artık /sd klasörü / the card is now the /sd folder
8
9sensor = ADC(4) # dahili sıcaklık sensörü / internal temperature sensor
10DOSYA = "/sd/pico_log.csv"
11
12if "pico_log.csv" not in os.listdir("/sd"): # yeni dosyaya başlık / header for a new file
13 with open(DOSYA, "w") as f:
14 f.write("tarih,saat,sicaklik_C\n")
15
16while True:
17 v = sensor.read_u16() * 3.3 / 65535
18 t = 27 - (v - 0.706) / 0.001721 # RP2040 veri sayfası formülü / RP2040 datasheet formula
19 y, ay, g, sa, dk, sn = time.localtime()[:6]
20 with open(DOSYA, "a") as f: # "a" = sona ekle / append
21 f.write("{:04d}-{:02d}-{:02d},{:02d}:{:02d}:{:02d},{:.1f}\n".format(y, ay, g, sa, dk, sn, t))
22 print(sa, dk, sn, t)
23 time.sleep(10) # 10 saniye bekle / wait 10 secondsLa Pico no tiene un reloj con pila: cuando está conectada a Thonny, su hora se ajusta automáticamente desde el ordenador, pero funcionando sola empieza el 1 de enero de 2021. Para tener marcas de tiempo exactas puedes añadir un módulo DS3231 o, en la Pico W, obtener la hora de internet por NTP. Si no hay tarjeta o el cableado está mal, el controlador lanza OSError: no SD card. Si programas la Pico con el IDE de Arduino (núcleo arduino-pico), puedes seguir el mismo método con la librería SD; los pines SPI0 por defecto coinciden con la tabla y para el CS basta con escribir SD.begin(17).
Evitar la pérdida de datos: alimentación, frecuencia de escritura y vida útil de la tarjeta
- Sin close() ni flush() no llega nada a la tarjeta: la librería acumula primero los datos en un búfer de 512 bytes. Si mantienes el archivo siempre abierto, llama a flush() cada pocas líneas.
- No saques la tarjeta mientras escribe: retirarla o cortar la alimentación en plena escritura puede corromper el sistema de archivos. Es buena costumbre añadir un botón que detenga el registro y un LED que indique que está grabando.
- Asegura una buena alimentación: la tarjeta consume hasta 100 mA al escribir. Un condensador de 10–100 µF entre VCC y GND del módulo reduce las caídas de tensión y los errores de escritura aleatorios.
- No abras y cierres demasiadas veces: si tomas decenas de lecturas por segundo, abrir y cerrar el archivo en cada línea es lento; guarda las lecturas en la RAM y escríbelas en bloques de 10–20 líneas.
- Vida útil de la tarjeta: las tarjetas SD reparten internamente las escrituras entre distintas celdas (wear leveling), así que un registrador que escribe unas pocas líneas por minuto no la desgastará en años. Aun así, elige una tarjeta de una marca conocida.
- Divide el archivo: abrir un archivo distinto cada día (por ejemplo 20261104.CSV) mantiene los archivos pequeños y, si algo falla, solo pierdes los datos de ese día.
Ideas de proyectos con el módulo SD
- Estación meteorológica con registro: guarda cada hora la temperatura, la humedad y la presión con un BME280 y haz el gráfico de toda una estación.
- Diario de riego: registra los valores del sensor de humedad del suelo y los momentos en que funciona la bomba para analizar tu pauta de riego.
- Registrador de rutas GPS: guarda en CSV tu ruta en bici o de senderismo con un GPS NEO-6M y después muéstrala en un mapa.
- Registro de entradas con tarjeta: escribe en un archivo cada tarjeta leída con un RFID RC522 junto con la fecha y la hora.
- Control del consumo eléctrico: mide y registra la corriente que consume un aparato a lo largo del día con un sensor de corriente ACS712.
- Reproductor MP3: el DFPlayer Mini reproduce archivos de audio desde su propia ranura micro SD; Arduino solo le envía órdenes.
Errores frecuentes y cómo solucionarlos
| Síntoma | Causa probable | Solución |
|---|---|---|
| "initialization failed" | No hay tarjeta, el cableado está mal o el pin CS no coincide con el código | Comprueba que MISO, MOSI y SCK están en los pines SPI por hardware y que el número de CS en SD.begin() es correcto |
| "initialization failed" (el cableado está bien) | Módulo con regulador alimentado a 3,3 V o alimentación débil | Alimenta el módulo a 5 V, acorta los cables y pon un condensador entre VCC y GND |
| "Could not find FAT16/FAT32 partition" | La tarjeta está en exFAT o NTFS; tarjeta SDXC de 64 GB o más | Formatea en FAT32 una tarjeta de hasta 32 GB |
| El archivo no se abre ("error opening") | El nombre no cumple la regla 8.3 o el archivo anterior no se cerró | Usa un nombre corto como VERI.CSV y cierra cada archivo con close() |
| El archivo está vacío o faltan las últimas líneas | Se cortó la alimentación antes de llamar a close() o flush() | Cierra el archivo tras cada registro o llama a flush() con regularidad |
| La SD deja de funcionar al añadir otro dispositivo SPI | El CS del otro dispositivo queda al aire o el módulo no libera la línea MISO | Pon todos los pines CS como OUTPUT y en HIGH al principio de setup(); si hace falta, usa un módulo que libere MISO |
| El Uno se cuelga o se comporta de forma rara | Falta RAM: la librería SD usa unos 650 bytes y el búfer de una pantalla OLED 1 KB | Escribe los textos con F(); si hace falta, pasa a un Mega o a un ESP32 |
| En el ESP32 los datos antiguos se borran en cada arranque | El archivo se abre con FILE_WRITE | Usa FILE_APPEND para añadir al final |
| "Card Mount Failed" en el ESP32 | Alimentación, cableado, velocidad SPI demasiado alta o faltan pull-ups en SD_MMC | Baja el SPI a 1 MHz; con SD_MMC prueba el modo de 1 bit |
Un módulo SD convierte un proyecto que solo mide en un dispositivo que lleva un registro, y unos pocos días de datos reales dicen mucho más que una sola lectura. En la app BlueGrays encontrarás el registrador de temperatura con ESP32, DHT22, RTC DS1307, micro SD y OLED, relojes digitales con RTC y proyectos de temperatura y humedad, todos con esquemas de circuito y código paso a paso.
Preguntas frecuentes
¿Qué tamaño de tarjeta SD admite Arduino?
La librería SD estándar de Arduino admite tarjetas SDSC y SDHC formateadas en FAT16 o FAT32, es decir, tarjetas de hasta 32 GB. Las SDXC de 64 GB o más vienen en exFAT y esta librería no puede leerlas. Para un datalogger, una tarjeta de 4–16 GB es más que suficiente.
¿Por qué la tarjeta SD da el error "initialization failed"?
Las causas más habituales son un pin CS incorrecto, MISO, MOSI o SCK sin conectar a los pines SPI por hardware, una tarjeta formateada en algo distinto de FAT32 y un módulo con regulador alimentado a 3,3 V. Ejecuta primero el ejemplo CardInfo y luego prueba con cables más cortos y alimentando el módulo a 5 V.
¿El módulo micro SD funciona con 3.3V?
Los módulos sin regulador funcionan directamente a 3,3 V y son adecuados para el ESP32 o la Pico. Los módulos micro SD con regulador y conversor de nivel necesitan 4,5–5,5 V; si se alimentan a 3,3 V, a la tarjeta no le llega suficiente tensión. Puedes alimentarlos desde VIN en el ESP32 o desde VBUS en la Pico.
¿Cómo abro en Excel el archivo CSV de la tarjeta SD?
Copia el archivo al ordenador e impórtalo en Excel con Datos > Desde el texto/CSV, eligiendo la coma como delimitador. Como Excel en español usa la coma decimal, los números pueden verse mal; en ese caso convierte las columnas con la configuración regional Inglés (Estados Unidos) o usa punto y coma como separador en el código.
¿Cada cuánto puede Arduino escribir en la tarjeta SD?
Escribir unas pocas líneas por segundo no es problema, pero abrir y cerrar el archivo en cada línea lleva tiempo. Con medidas rápidas, acumula los datos en la RAM y escríbelos por bloques, o deja el archivo abierto y llama a flush() con regularidad. Con ritmos lentos, como un registro por minuto, abrir, escribir y cerrar cada vez es el método más seguro.
¿Se puede usar el módulo SD junto con un RFID o una pantalla TFT?
Sí. Los dispositivos SPI comparten las líneas MISO, MOSI y SCK, y cada uno usa su propio pin CS. Si hay problemas, pon todos los pines CS como OUTPUT y en HIGH al principio de setup(). El conversor de nivel de algunos módulos micro SD baratos nunca libera la línea MISO; en ese caso usa un módulo que sí la libere o un segundo bus SPI en el ESP32.
Proyectos para hacer después de leer esto
Ver todos los proyectos
Temperatura y humedad con DHT11
¿Qué temperatura hace en tu habitación, y el aire está húmedo o seco? El sensor DHT11 mide la temperatura y la humedad, y el Arduino escribe los valores en una pantalla LCD de dos líneas, actualizándo

Registrador de Temperatura ESP32 (DHT22 + DS1307 RTC + microSD + OLED)
¡Construye un registrador de temperatura con marca de tiempo con ESP32! Lee temperatura/humedad del DHT22 cada minuto, obtén la hora real del DS1307 RTC y registra en tarjeta microSD como CSV. El OLED muestra en vivo la temperatura (fuente grande), porcentaje de humedad, marca de tiempo y contador de registros. El archivo `/temp_log.csv` en la tarjeta SD se abre en Excel, Google Sheets o Python pandas para análisis — perfecto para monitoreo de invernadero, seguimiento de temperatura del hog

Reloj digital con ESP32 y RTC DS1307 (I2C + LCD)
En este proyecto, mostramos la hora y la fecha en una pantalla LCD I2C de 16x2 mediante el módulo de reloj en tiempo real (RTC) DS1307. El DS1307 es un RTC con batería de respaldo que conserva la hora incluso si el ESP32 se apaga. Ambos módulos comparten la misma línea I2C (SDA/SCL), por lo que aprendemos a controlar varios dispositivos con solo dos cables de señal. Con este proyecto conocerás el protocolo I2C, el funcionamiento de los módulos RTC y la visualización dinámica en pantallas LCD.

ESP32 DHT22 Temperatura y humedad (con pantalla LCD)
Se trata de un proyecto que mide la temperatura y la humedad ambientales mediante el sensor DHT22 y las muestra en tiempo real en una pantalla LCD I2C 16x2. Los datos del sensor se leen mediante el protocolo de un solo cable (one-wire) utilizando la biblioteca DHT de Adafruit. Este proyecto constituye la base para estaciones meteorológicas IoT, sistemas de automatización doméstica inteligente o sistemas de monitorización ambiental en invernaderos.

Modo de suspensión profunda del ESP32 — Ahorro de batería (OLED + contador en RTC RAM)
El modo «Deep Sleep» del ESP32 reduce el consumo de corriente a unos 10 µA al desactivar la CPU y la mayoría de los periféricos, lo cual es de vital importancia para los dispositivos IoT que funcionan con pilas. En este proyecto utilizamos tres fuentes de activación diferentes: el temporizador (15 s), un pin externo (EXT0 — botón GPIO 33) y el sensor táctil (T0/GPIO 4). Las variables marcadas con `RTC_DATA_ATTR` se conservan durante el modo Deep Sleep: el contador de arranque, el contador de act

ESP32: hora real desde Internet con NTP
El ESP32 se conecta a Wi-Fi y obtiene la hora real con precisión de milisegundos desde servidores NTP (Network Time Protocol). Gracias a `configTzTime()`, se aplica automáticamente la zona horaria de Turquía (TRT, UTC+3) y el cambio DST se gestiona mediante la cadena POSIX TZ. La hora se muestra en el monitor serie y en una pantalla LCD I2C opcional. `configTzTime()` inicia el servicio SNTP; se realizan resincronizaciones periódicas mientras hay acceso a la red, y el reloj del sistema sigue avan

Reloj matricial, calendario y estación meteorológica (MAX7219, DS1307)
Un panel de texto en movimiento para tu mesa o tu pared que muestra por turnos la hora, la fecha y el clima de la habitación. En la pantalla LED de 8x32 aparece primero la temperatura en grados Celsiu

Reloj RTC DS1302 con pantalla LCD
Un pequeño reloj de mesa que no pierde la hora aunque se vaya la luz. El módulo de reloj DS1302 guarda la hora gracias a su propia pila diminuta; cada segundo el Arduino la lee y escribe la hora y la
Más artículos
App BlueGrays
Monta este circuito paso a paso en tu teléfono
Esquema, código y lista de piezas en una sola pantalla. Más de 160 proyectos de Arduino, ESP32 y Pico listos para montar.
Escanea con tu teléfono
Apunta la cámara al código y se abrirá la tienda de apps de tu teléfono.
o ábrela en la tienda

