Modulo SD card Arduino: datalogger CSV con RTC e soluzione errori
Modulo SD card con Arduino: pin SPI, formattazione FAT32, dati dei sensori in CSV con orario RTC, ESP32 SD_MMC, Pico e soluzione a initialization failed.
Il modulo SD card per Arduino è una schedina piccola ed economica che ti permette di salvare come file su una micro SD le letture di temperatura, umidità, distanza o posizione dei tuoi sensori. È il modo più semplice per costruire un datalogger che misura per giorni o persino mesi senza un computer collegato: Arduino misura, il modulo scrive ogni lettura come una nuova riga in un file CSV sulla scheda, e tu poi inserisci la scheda nel computer e crei un grafico in Excel. Il modulo si collega via SPI e funziona con poche righe di codice grazie alla libreria SD già inclusa nell'IDE di Arduino.
In questa guida imparerai passo dopo passo come funziona il modulo, la differenza tra moduli a 5V e a 3.3V, i collegamenti SPI per Arduino Uno, Mega, ESP32 e Raspberry Pi Pico, come formattare la scheda in FAT32, come scrivere e leggere file e come tenere un registro CSV con data e ora usando un modulo RTC. Vediamo anche l'interfaccia veloce SD_MMC dell'ESP32, l'uso della SD sul Pico con MicroPython e come risolvere il frequentissimo errore "initialization failed".

Che cos'è un modulo SD card e come funziona?
Le schede SD funzionano a 3,3 V e possono comunicare in due modi: la modalità SD nativa, più veloce, e la più semplice modalità SPI. I microcontrollori come Arduino parlano con la scheda tramite SPI. Il compito del modulo è renderli compatibili dal punto di vista elettrico: il regolatore abbassa i 5 V ai 3,3 V richiesti dalla scheda, e un integrato traslatore di livello (di solito un 74LVC125A) converte i segnali a 5 V di Arduino in segnali a 3,3 V che la scheda può sopportare. Internamente la scheda è fatta di blocchi da 512 byte, mentre file, cartelle e nomi vengono gestiti dal file system FAT. La libreria SD fa tutto questo lavoro complicato al posto tuo: tu apri un file, ci scrivi e lo chiudi.
| Caratteristica | Valore |
|---|---|
| Interfaccia | SPI (MISO, MOSI, SCK, CS) |
| Alimentazione (modulo micro SD con regolatore) | 4,5–5,5 V, regolatore da 3,3 V sulla scheda |
| Livello dei segnali | Compatibile con 3,3 V e 5 V (grazie al traslatore di livello) |
| Schede supportate | micro SD (fino a 2 GB) e micro SDHC (4–32 GB) |
| File system | FAT16 o FAT32 |
| Assorbimento | Pochi mA a riposo, fino a 100 mA in scrittura |
| Nome del file (libreria SD di Arduino) | Formato 8.3: massimo 8 caratteri per il nome + 3 per l'estensione |
Modulo SD a 5V o a 3.3V: quale scegliere?
| Tipo di modulo | Alimentazione | Livello dei segnali | Ideale per |
|---|---|---|---|
| Modulo micro SD con regolatore (74LVC125A) | 5 V | 3,3 V e 5 V | Uno, Nano, Mega; ESP32 e Pico se alimentato a 5 V |
| Modulo SD a grandezza piena (pin +5 e +3.3) | 5 V o 3,3 V | Quasi sempre senza vero traslatore di livello | Schede a 3,3 V; poco affidabile con segnali a 5 V |
| Modulo micro SD senza regolatore (solo slot) | Solo 3,3 V | Solo 3,3 V | ESP32, Raspberry Pi Pico |
| Schede con slot integrato (come l'ESP32-CAM) | Dalla scheda | 3,3 V | Si usa direttamente con SD_MMC |
Se usi un Arduino Uno, Nano o Mega, scegli un modulo micro SD con regolatore e traslatore di livello come quello in foto e collega VCC al pin 5V. ESP32 e Pico lavorano a 3,3 V; puoi usare lo stesso modulo anche con loro, ma conviene comunque alimentarlo a 5 V (VIN sull'ESP32, VBUS sul Pico quando è alimentato via USB). Dato che il traslatore di livello è alimentato a 3,3 V, il segnale MISO che torna al microcontrollore è già a 3,3 V. I moduli senza regolatore si collegano direttamente al pin 3V3; se devi usarne uno con un Arduino a 5 V, metti un partitore di tensione da 1 kΩ + 2 kΩ su ciascuna delle linee MOSI, SCK e CS, oppure usa un convertitore di livello logico. Puoi verificare i valori delle resistenze con il calcolatore di partitore di tensione.
Collegamento del modulo SD card: i pin SPI
| Pin del modulo | 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 e SCK vanno collegati ai pin SPI hardware su ogni scheda; CS (chip select) può essere un qualsiasi pin digitale, purché tu passi lo stesso numero a SD.begin() nel codice. Sugli shield già pronti CS è di solito D4 o D10. Puoi collegare più dispositivi allo stesso bus SPI: condividono tutti MISO, MOSI e SCK e ognuno ha il proprio pin CS. Spieghiamo in dettaglio come funziona l'SPI in comunicazione SPI. Per vedere dove si trovano i pin sulla tua scheda, usa lo strumento pinout.
Preparare la SD card: formattazione in FAT32
- Capacità della scheda: scegli una micro SDHC da 4 a 32 GB. La libreria SD di Arduino supporta le schede SDSC (fino a 2 GB) e SDHC; le SDXC da 64 GB in su escono di fabbrica in exFAT, che questa libreria non sa leggere.
- File system: formatta la scheda in FAT32 (sulle schede fino a 2 GB va bene anche FAT16). NTFS ed exFAT non funzionano.
- Windows: in Esplora file fai clic destro sulla scheda, scegli Formatta e seleziona FAT32 come file system con la dimensione predefinita dell'unità di allocazione. Per le schede oltre 32 GB Windows non offre FAT32.
- macOS: seleziona la scheda in Utility Disco, fai clic su Inizializza e scegli MS-DOS (FAT) come formato e Master Boot Record come schema.
- La strada più sicura: il programma gratuito SD Card Formatter della SD Association formatta la scheda secondo lo standard e risolve la maggior parte degli errori strani.
- Una sola partizione: la scheda deve avere una sola partizione. Le schede usate in precedenza in un Raspberry Pi o in una fotocamera possono averne ancora diverse; eliminale prima di formattare.
Primo test passo dopo passo: scrivere e leggere sulla SD card
- Inserisci la scheda formattata nel modulo e collega il modulo ad Arduino seguendo la tabella qui sopra.
- La libreria SD è inclusa nell'IDE di Arduino, quindi non devi installare nulla; basta includere SPI.h e SD.h all'inizio dello sketch.
- Carica il codice qui sotto e apri il Monitor seriale a 9600 baud.
- Se vedi "tamam" (OK) e il contenuto del file, la scheda e i collegamenti sono a posto. A ogni avvio della scheda viene aggiunta una nuova riga a TEST.TXT.
- Quando togli la scheda e la inserisci nel computer, puoi aprire TEST.TXT con qualsiasi editor di testo.
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}| Funzione | Cosa fa |
|---|---|
| SD.begin(cs) | Inizializza la scheda; restituisce true se ci riesce |
| SD.open("NOME.TXT", FILE_WRITE) | Apre il file in scrittura; lo crea se non esiste, altrimenti aggiunge in fondo |
| SD.open("NOME.TXT") | Apre il file in lettura (FILE_READ) |
| file.print() / println() | Scrive testo o un numero nel file |
| file.flush() | Scrive sulla scheda i dati del buffer senza chiudere il file |
| file.close() | Scrive sulla scheda i dati rimasti e chiude il file |
| file.available() / read() | Controlla se ci sono ancora byte da leggere / legge un byte |
| SD.exists() / SD.remove() / SD.mkdir() | Controlla se un file esiste / cancella un file / crea una cartella |
Salvare i dati dei sensori in CSV con l'orario dell'RTC
Il formato più pratico per un datalogger è il CSV (valori separati da virgole): ogni riga è una misura, ogni colonna un valore, e la prima riga contiene i titoli delle colonne. Per sapere quando è stata fatta ogni lettura, devi aggiungere data e ora a ogni riga. millis() indica solo il tempo trascorso dall'accensione di Arduino e riparte da zero a ogni reset, per questo usiamo un modulo RTC (orologio in tempo reale) con batteria a bottone. L'RTC continua a contare anche quando Arduino è spento. Il DS1307 è economico ma può sbagliare di qualche secondo al giorno; il DS3231, grazie al quarzo compensato in temperatura, sbaglia solo di circa un minuto all'anno. Li confrontiamo in moduli orologio RTC.

Il circuito: il modulo SD va sui pin SPI come nella tabella precedente, il modulo RTC sul bus I2C (su Uno SDA = A4, SCL = A5, VCC = 5V) e il pin dati del sensore DHT22 su D2; se usi il sensore nudo, aggiungi una resistenza da 10 kΩ tra il pin dati e VCC. Installa le librerie RTClib (Adafruit) e DHT sensor library dal Gestore librerie. Per i dettagli sul collegamento del sensore, leggi sensore di temperatura e umidità DHT11 e 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}Ogni 10 secondi il codice legge temperatura e umidità, prende data e ora dall'RTC e aggiunge in fondo a VERI.CSV una riga come 2026-11-04,14:05:30,23.5,45.2. Poiché il file viene chiuso dopo ogni registrazione, i dati salvati fino a quel momento sopravvivono anche a un blackout. Sulle schede AVR sprintf() non supporta i numeri decimali (%f), quindi i valori vengono prima convertiti in testo con dtostrf(). Dato che l'attesa usa millis() invece di delay(), nel loop() puoi fare anche altre cose. Se l'RTC non è mai stato regolato, viene impostato sul momento in cui è stato compilato il codice. Se usi un DS3231, basta scrivere RTC_DS3231 al posto di RTC_DS1307 e controllare lostPower() invece di isrunning().
Quanto spazio occupa? Una riga è di circa 31 byte. Con una registrazione ogni 10 secondi si ottengono 8.640 righe al giorno, cioè circa 260 KB; in un anno sono circa 95 MB. A questo ritmo, quindi, una scheda da 8 GB basta per decenni. Il vero limite non è la scheda ma l'alimentazione: se il progetto deve funzionare a batteria, calcola prima quanto durerà con il calcolatore di durata della batteria.
Aprire in Excel i dati della SD card
- Togli l'alimentazione ad Arduino, estrai la scheda dal modulo e inseriscila nel computer.
- Copia VERI.CSV sul computer; lavorare su una copia è più sicuro che lavorare direttamente sulla scheda.
- Apri una cartella di lavoro vuota in Excel e scegli il file con Dati > Da testo/CSV.
- Nella finestra di anteprima seleziona Virgola come delimitatore e fai clic su Carica; le colonne vengono separate in data, ora, temperatura e umidità.
- Seleziona le colonne di temperatura e umidità e inserisci un grafico a linee dalla scheda Inserisci per vederne l'andamento nel tempo.
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_yuzdeSe preferisci mandare le letture in diretta in Excel mentre Arduino è collegato al computer, senza estrarre la scheda, dai un'occhiata ai metodi Data Streamer e PLX-DAQ in inviare i dati di Arduino a Excel. La SD card, invece, è indispensabile per i progetti che lavorano sul campo, lontano da qualsiasi computer.
Usare una SD card con l'ESP32 (SPI)
Il core Arduino dell'ESP32 include una propria libreria SD che si usa quasi allo stesso modo, ma con tre differenze importanti: i percorsi iniziano con / ("/olcumler.csv"), i nomi lunghi sono ammessi e FILE_WRITE riscrive il file da zero. Per aggiungere in fondo devi usare FILE_APPEND; se copi il codice di Uno così com'è, i tuoi vecchi dati verranno cancellati a ogni avvio. I pin SPI predefiniti sono SCK 18, MISO 19 e MOSI 23, e per CS si usa di solito il GPIO 5. Tipo e capacità della scheda si leggono anche con una sola riga:
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}Il codice salva ogni 5 secondi il valore grezzo (0–4095) di una fotoresistenza (LDR) collegata al GPIO 34. Sull'ESP32 non serve nemmeno un modulo RTC per avere l'ora reale: può collegarsi al Wi-Fi, prendere l'ora da un server NTP e aggiungere un timestamp a ogni riga con getLocalTime(). Se i cavi sono lunghi o la scheda è instabile, abbassa la velocità SPI: SD.begin(5, SPI, 1000000) avvia la scheda a 1 MHz. In un datalogger a batteria, usare il deep sleep tra una lettura e l'altra moltiplica la durata della batteria.
ESP32 SD_MMC: l'interfaccia SD veloce e l'ESP32-CAM
Oltre all'SPI, l'ESP32 ha anche un controller SDMMC che parla il protocollo veloce nativo della scheda. In modalità a 4 bit la libreria SD_MMC è diverse volte più veloce dell'SPI, ideale per file grandi come foto o audio. Sull'ESP32 classico i pin sono fissi: CLK GPIO 14, CMD GPIO 15, D0 GPIO 2, D1 GPIO 4, D2 GPIO 12, D3 GPIO 13, e queste linee richiedono resistenze di pull-up da 10 kΩ. In modalità a 1 bit si usano solo CLK, CMD e D0; è più lenta, ma i GPIO 4, 12 e 13 restano liberi. Lo slot micro SD dell'ESP32-CAM è collegato proprio a questi pin, e usare la modalità a 1 bit evita che il LED flash sul GPIO 4 lampeggi a ogni accesso alla scheda.
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}SD card con il Raspberry Pi Pico (MicroPython)
In MicroPython la SD card si gestisce con il driver sdcard.py di micropython-lib. Se hai mpremote sul computer, installalo con mpremote mip install sdcard, oppure copia il file sul Pico con Thonny. La scheda viene montata come cartella /sd con os.mount() e da lì in poi si usa con i normali comandi Python per i file (open, write). Il codice qui sotto legge il sensore di temperatura interno del Pico e scrive una riga CSV ogni 10 secondi. Se il Pico è una novità per te, leggi prima cos'è il 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 secondsIl Pico non ha un orologio con batteria tampone: quando è collegato a Thonny l'ora viene impostata automaticamente dal computer, ma quando funziona da solo parte dal 1° gennaio 2021. Per timestamp precisi puoi aggiungere un modulo DS3231 oppure, sul Pico W, prendere l'ora da internet via NTP. Se manca la scheda o i collegamenti sono sbagliati, il driver genera OSError: no SD card. Se programmi il Pico con l'IDE di Arduino (core arduino-pico), puoi seguire lo stesso metodo con la libreria SD; i pin SPI0 predefiniti coincidono con la tabella e per il CS basta scrivere SD.begin(17).
Evitare la perdita di dati: alimentazione, frequenza di scrittura e durata della scheda
- Senza close() o flush() sulla scheda non arriva nulla: la libreria accumula prima i dati in un buffer da 512 byte. Se tieni il file sempre aperto, chiama flush() ogni poche righe.
- Non estrarre la scheda mentre scrive: togliere la scheda o staccare l'alimentazione durante una scrittura può corrompere il file system. Aggiungere un pulsante che ferma la registrazione e un LED che indica che è in corso è una buona abitudine.
- Cura l'alimentazione: la scheda assorbe fino a 100 mA in scrittura. Un condensatore da 10–100 µF tra VCC e GND del modulo riduce i cali di tensione e gli errori di scrittura casuali.
- Non aprire e chiudere troppo spesso: se fai decine di letture al secondo, aprire e chiudere il file per ogni riga è lento; tieni le letture in RAM e scrivile a blocchi di 10–20 righe.
- Durata della scheda: le SD distribuiscono internamente le scritture su celle diverse (wear leveling), quindi un datalogger che scrive poche righe al minuto non la consumerà per anni. Scegli comunque una scheda di una marca conosciuta.
- Dividi il file: aprire un file diverso per ogni giorno (ad esempio 20261104.CSV) mantiene i file piccoli e, se qualcosa va storto, perdi solo i dati di quel giorno.
Idee di progetti con il modulo SD card
- Stazione meteo con registrazione: salva ogni ora temperatura, umidità e pressione con un BME280 e crea il grafico di un'intera stagione.
- Diario dell'irrigazione: registra i valori del sensore di umidità del terreno e i momenti in cui si accende la pompa per studiare le tue abitudini di irrigazione.
- Registratore di percorsi GPS: salva in CSV il tuo giro in bici o la tua escursione con un GPS NEO-6M e poi mostralo su una mappa.
- Registro accessi con tessera: scrivi in un file ogni tessera letta con un RFID RC522, insieme a data e ora.
- Monitoraggio dei consumi elettrici: misura e registra la corrente che un apparecchio assorbe durante la giornata con un sensore di corrente ACS712.
- Lettore MP3: il DFPlayer Mini riproduce file audio dal suo slot micro SD; Arduino si limita a inviare comandi.
Errori comuni e come risolverli
| Sintomo | Causa probabile | Soluzione |
|---|---|---|
| "initialization failed" | Scheda assente, collegamenti sbagliati o pin CS diverso da quello nel codice | Controlla che MISO, MOSI e SCK siano sui pin SPI hardware e che il numero di CS in SD.begin() sia corretto |
| "initialization failed" (collegamenti giusti) | Modulo con regolatore alimentato a 3,3 V o alimentazione debole | Alimenta il modulo a 5 V, accorcia i cavi, aggiungi un condensatore tra VCC e GND |
| "Could not find FAT16/FAT32 partition" | Scheda formattata in exFAT o NTFS; SDXC da 64 GB o più | Formatta in FAT32 una scheda fino a 32 GB |
| Il file non si apre ("error opening") | Il nome non rispetta la regola 8.3 o il file precedente non è stato chiuso | Usa un nome breve come VERI.CSV e chiudi ogni file con close() |
| Il file è vuoto o mancano le ultime righe | L'alimentazione è stata tolta prima di close() o flush() | Chiudi il file dopo ogni registrazione o chiama flush() regolarmente |
| La SD smette di funzionare quando aggiungi un altro dispositivo SPI | Il CS dell'altro dispositivo è flottante o il modulo non rilascia la linea MISO | Imposta tutti i pin CS come OUTPUT e HIGH all'inizio di setup(); se serve, usa un modulo che rilascia MISO |
| Uno si blocca o si comporta in modo strano | RAM insufficiente: la libreria SD usa circa 650 byte e il buffer di un display OLED 1 KB | Scrivi i testi con F(); se serve, passa a un Mega o a un ESP32 |
| Sull'ESP32 i vecchi dati vengono cancellati a ogni avvio | Il file viene aperto con FILE_WRITE | Usa FILE_APPEND per aggiungere in fondo |
| "Card Mount Failed" sull'ESP32 | Alimentazione, collegamenti, velocità SPI troppo alta o pull-up mancanti in SD_MMC | Abbassa l'SPI a 1 MHz; con SD_MMC prova la modalità a 1 bit |
Un modulo SD card trasforma un progetto che si limita a misurare in un dispositivo che tiene un registro, e qualche giorno di dati reali racconta molto più di una singola lettura. Nell'app BlueGrays trovi il datalogger di temperatura con ESP32, DHT22, RTC DS1307, micro SD e OLED, orologi digitali con RTC e progetti di misura di temperatura e umidità, tutti con schemi elettrici e codice passo dopo passo.
Domande frequenti
Quanti GB può avere la SD card per Arduino?
La libreria SD standard di Arduino supporta schede SDSC e SDHC formattate in FAT16 o FAT32, cioè fino a 32 GB. Le SDXC da 64 GB in su sono in exFAT e questa libreria non le legge. Per un datalogger una scheda da 4–16 GB è più che sufficiente.
Perché la SD card dà l'errore "initialization failed"?
Le cause più comuni sono un pin CS sbagliato, MISO, MOSI o SCK non collegati ai pin SPI hardware, una scheda formattata in modo diverso da FAT32 e un modulo con regolatore alimentato a 3,3 V. Esegui prima l'esempio CardInfo, poi prova con cavi più corti e alimentando il modulo a 5 V.
Il modulo SD card funziona a 3.3V?
I moduli senza regolatore funzionano direttamente a 3,3 V e vanno bene per ESP32 o Pico. I moduli micro SD con regolatore e traslatore di livello richiedono invece 4,5–5,5 V; alimentati a 3,3 V, la scheda non riceve tensione sufficiente. Puoi alimentarli dal pin VIN sull'ESP32 o VBUS sul Pico.
Come si apre in Excel il file CSV salvato sulla SD card?
Copia il file sul computer e importalo in Excel con Dati > Da testo/CSV scegliendo la virgola come delimitatore. Poiché l'Excel in italiano usa la virgola decimale, i numeri possono apparire sbagliati; in quel caso converti le colonne con le impostazioni locali Inglese (Stati Uniti) oppure usa il punto e virgola come separatore nel codice.
Ogni quanto Arduino può scrivere sulla SD card?
Scrivere qualche riga al secondo non è un problema, ma aprire e chiudere il file per ogni riga richiede tempo. Con misure veloci, accumula i dati in RAM e scrivili a blocchi, oppure tieni il file aperto e chiama flush() regolarmente. Con ritmi lenti, come una registrazione al minuto, aprire-scrivere-chiudere ogni volta è il metodo più sicuro.
Si può usare il modulo SD insieme a un RFID o a un display TFT?
Sì. I dispositivi SPI condividono le linee MISO, MOSI e SCK e ognuno usa il proprio pin CS. Se ci sono problemi, imposta tutti i pin CS come OUTPUT e HIGH all'inizio di setup(). Il traslatore di livello di alcuni moduli micro SD economici non rilascia mai la linea MISO; in quel caso usa un modulo che la rilascia o un secondo bus SPI sull'ESP32.
Progetti da realizzare dopo questo articolo
Vedi tutti i progetti
Temperatura e umidità con DHT11
Quanti gradi ci sono nella tua stanza, e l'aria è umida o secca? Il sensore DHT11 misura temperatura e umidità, e l'Arduino scrive i valori su uno schermo LCD a due righe, aggiornandoli ogni paio di s

Data Logger di Temperatura ESP32 (DHT22 + DS1307 RTC + microSD + OLED)
Costruisci un data logger di temperatura con timestamp usando ESP32! Leggi temperatura/umidità dal DHT22 ogni minuto, ottieni l'ora reale dal DS1307 RTC e registra su scheda microSD in formato CSV. L'OLED mostra dal vivo temperatura (font grande), percentuale di umidità, timestamp e contatore di log. Il file `/temp_log.csv` sulla scheda SD si apre in Excel, Google Sheets o Python pandas per l'analisi — perfetto per il monitoraggio di serre, tracciamento della temperatura domestica, raccolta

Orologio digitale con ESP32 e RTC DS1307 (I2C + LCD)
In questo progetto, utilizziamo il modulo orologio in tempo reale (RTC) DS1307 per visualizzare l'ora e la data su un display LCD 16x2 I2C. Il DS1307 è un RTC con batteria di supporto che mantiene l'ora anche se l'ESP32 si spegne. Entrambi i moduli condividono la stessa linea I2C (SDA/SCL), permettendoci di imparare a controllare più dispositivi utilizzando solo due cavi di segnale. Cosi imparerai il protocollo I2C e il funzionamento dei moduli RTC nella pratica.

ESP32 DHT22 Temperatura e umidità (con display LCD)
Si tratta di un progetto che misura la temperatura e l'umidità dell'ambiente tramite il sensore DHT22 e le visualizza in tempo reale su un display LCD I2C 16x2. I dati vengono letti dal sensore utilizzando il protocollo one-wire tramite la libreria Adafruit DHT. Questo progetto costituisce la base per stazioni meteorologiche IoT, sistemi di automazione domestica intelligente o sistemi di monitoraggio ambientale nelle serre. La comunicazione con il DHT22 avviene tramite il pin GPIO 4 dell'ESP32.

ESP32 Deep Sleep — Risparmio della batteria (OLED + contatore in RTC RAM)
La modalità Deep Sleep dell'ESP32 riduce il consumo di corrente a circa 10 µA spegnendo la CPU e la maggior parte dei dispositivi periferici ed è di fondamentale importanza per i dispositivi IoT alimentati a batteria. In questo progetto utilizziamo tre diverse fonti di risveglio: il timer (15 secondi), un pin esterno (EXT0 — pulsante GPIO 33) e il sensore tattile (T0/GPIO 4). Le variabili contrassegnate con `RTC_DATA_ATTR` vengono preservate durante la modalità Deep Sleep: il contatore di avvio,

ESP32: ora reale da Internet tramite NTP
L'ESP32 si connette al Wi-Fi e recupera l'ora reale con precisione al millisecondo dai server NTP (Network Time Protocol). Grazie a `configTzTime()`, il fuso orario della Turchia (TRT, UTC+3) viene applicato automaticamente e il passaggio all'ora legale è gestito tramite la stringa POSIX TZ. L'ora viene mostrata sul Serial Monitor e su un display LCD I2C opzionale. `configTzTime()` avvia il servizio SNTP; vengono eseguite risincronizzazioni periodiche finché è disponibile l'accesso alla rete, e

Orologio a matrice di punti, calendario e stazione meteo (MAX7219, DS1307)
Un pannello a scritte scorrevoli per la scrivania o la parete che mostra a turno l'ora, la data e il clima della stanza. Sul display LED 8x32 compaiono prima la temperatura in Celsius e Fahrenheit, po

DS1302 Orologio RTC con display LCD
Un piccolo orologio da scrivania che non dimentica l'ora nemmeno se manca la corrente. Il modulo orologio DS1302 tiene il tempo grazie alla sua piccola batteria; ogni secondo l'Arduino lo legge e scri
Altri articoli
App BlueGrays
Costruisci questo circuito passo passo sul telefono
Schema, codice ed elenco componenti in un’unica schermata. Oltre 160 progetti Arduino, ESP32 e Pico da realizzare.
Inquadra con il telefono
Punta la fotocamera sul codice: si apre lo store del tuo telefono.
oppure apri lo store

