Componenti · 14 min di lettura

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".

Modulo micro SD card per Arduino
Modulo micro SD: slot per la scheda, regolatore da 3,3 V, integrato traslatore di livello e 6 pin (GND, VCC, MISO, MOSI, SCK, CS).

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.

CaratteristicaValore
InterfacciaSPI (MISO, MOSI, SCK, CS)
Alimentazione (modulo micro SD con regolatore)4,5–5,5 V, regolatore da 3,3 V sulla scheda
Livello dei segnaliCompatibile con 3,3 V e 5 V (grazie al traslatore di livello)
Schede supportatemicro SD (fino a 2 GB) e micro SDHC (4–32 GB)
File systemFAT16 o FAT32
AssorbimentoPochi 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 moduloAlimentazioneLivello dei segnaliIdeale per
Modulo micro SD con regolatore (74LVC125A)5 V3,3 V e 5 VUno, 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 VQuasi sempre senza vero traslatore di livelloSchede a 3,3 V; poco affidabile con segnali a 5 V
Modulo micro SD senza regolatore (solo slot)Solo 3,3 VSolo 3,3 VESP32, Raspberry Pi Pico
Schede con slot integrato (come l'ESP32-CAM)Dalla scheda3,3 VSi 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.

L'errore più comune è alimentare a 3,3 V un modulo micro SD dotato di regolatore. Il regolatore AMS1117 del modulo fa cadere circa 1 V, quindi alla scheda arrivano solo 2,3 V circa e quasi sempre compare initialization failed. Al contrario, applicare 5 V ai pin di un modulo senza regolatore può danneggiare la scheda in modo permanente. Prima di collegarlo, leggi le scritte sul modulo e controlla se ha un regolatore.

Collegamento del modulo SD card: i pin SPI

Pin del moduloArduino Uno / NanoArduino MegaESP32Raspberry Pi Pico
GNDGNDGNDGNDGND
VCC5V5VVIN (5 V)VBUS (5 V)
MISOD12D50GPIO 19GP16
MOSID11D51GPIO 23GP19
SCKD13D52GPIO 18GP18
CSD10D53GPIO 5GP17

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.
Su Arduino Uno la libreria SD accetta solo nomi brevi nel formato 8.3: un nome di massimo 8 caratteri e un'estensione di 3, senza spazi né lettere accentate. DATI.CSV o LOG01.TXT funzionano, ma un nome lungo come registro-temperatura.csv fa fallire SD.open() senza alcun messaggio. Su ESP32 e Pico puoi usare nomi lunghi senza problemi.

Primo test passo dopo passo: scrivere e leggere sulla SD card

  1. Inserisci la scheda formattata nel modulo e collega il modulo ad Arduino seguendo la tabella qui sopra.
  2. La libreria SD è inclusa nell'IDE di Arduino, quindi non devi installare nulla; basta includere SPI.h e SD.h all'inizio dello sketch.
  3. Carica il codice qui sotto e apri il Monitor seriale a 9600 baud.
  4. 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.
  5. Quando togli la scheda e la inserisci nel computer, puoi aprire TEST.TXT con qualsiasi editor di testo.
Arduino (C++)
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}
FunzioneCosa 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.

Modulo orologio RTC DS1307
Il modulo RTC DS1307 si collega via I2C (SDA, SCL) e, grazie alla batteria a bottone, mantiene l'ora anche con Arduino spento.

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.

Arduino (C++)
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

  1. Togli l'alimentazione ad Arduino, estrai la scheda dal modulo e inseriscila nel computer.
  2. Copia VERI.CSV sul computer; lavorare su una copia è più sicuro che lavorare direttamente sulla scheda.
  3. Apri una cartella di lavoro vuota in Excel e scegli il file con Dati > Da testo/CSV.
  4. Nella finestra di anteprima seleziona Virgola come delimitatore e fai clic su Carica; le colonne vengono separate in data, ora, temperatura e umidità.
  5. Seleziona le colonne di temperatura e umidità e inserisci un grafico a linee dalla scheda Inserisci per vederne l'andamento nel tempo.
Nell'Excel in italiano la virgola è il separatore decimale e il punto separa le migliaia, quindi un valore come 23.5 può non essere riconosciuto come numero e apparire come testo, come data o come numero sbagliato. Ci sono due soluzioni: durante l'importazione fai clic su Trasforma dati e converti le colonne di temperatura e umidità in numeri decimali usando le impostazioni locali Inglese (Stati Uniti), oppure modifica il codice come qui sotto in modo che usi il punto e virgola come separatore e la virgola come segno decimale. Con la seconda soluzione basta fare doppio clic sul file ed Excel separa le colonne da solo.
Arduino (C++)
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_yuzde

Se 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:

Arduino (C++)
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.

Arduino (C++)
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}
Il GPIO 12 è un pin di strapping che, all'avvio dell'ESP32, stabilisce la tensione della memoria flash. In modalità a 4 bit la resistenza di pull-up sulla linea D2 può impedire l'avvio di alcuni moduli; in questo caso usa la modalità a 1 bit. Sui chip più recenti come l'ESP32-S3 puoi scegliere liberamente i pin con SD_MMC.setPins().

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.

MicroPython
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 seconds

Il 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

SintomoCausa probabileSoluzione
"initialization failed"Scheda assente, collegamenti sbagliati o pin CS diverso da quello nel codiceControlla 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 deboleAlimenta 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 chiusoUsa un nome breve come VERI.CSV e chiudi ogni file con close()
Il file è vuoto o mancano le ultime righeL'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 SPIIl CS dell'altro dispositivo è flottante o il modulo non rilascia la linea MISOImposta 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 stranoRAM insufficiente: la libreria SD usa circa 650 byte e il buffer di un display OLED 1 KBScrivi i testi con F(); se serve, passa a un Mega o a un ESP32
Sull'ESP32 i vecchi dati vengono cancellati a ogni avvioIl file viene aperto con FILE_WRITEUsa FILE_APPEND per aggiungere in fondo
"Card Mount Failed" sull'ESP32Alimentazione, collegamenti, velocità SPI troppo alta o pull-up mancanti in SD_MMCAbbassa l'SPI a 1 MHz; con SD_MMC prova la modalità a 1 bit
Il modo più rapido per trovare l'origine del problema è l'esempio File > Esempi > SD > CardInfo dell'IDE di Arduino. Se mostra il tipo di scheda (SD1, SD2 o SDHC) ma non trova la partizione, il problema è la formattazione; se non riesce nemmeno a mostrare il tipo di scheda, controlla collegamenti e alimentazione.

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.

Vedi tutti i progetti
Temperatura e umidità con DHT11
#55Intermedio

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

4.7(47)
64
Data Logger di Temperatura ESP32 (DHT22 + DS1307 RTC + microSD + OLED)
#144Avanzato
Premium

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

4.7(7)
12
Orologio digitale con ESP32 e RTC DS1307 (I2C + LCD)
#120Intermedio
Premium

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.

4.6(26)
40
ESP32 DHT22 Temperatura e umidità (con display LCD)
#117Intermedio

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.

4.8(38)
54
ESP32 Deep Sleep — Risparmio della batteria (OLED + contatore in RTC RAM)
#135Avanzato
Premium

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,

4.3(10)
16
ESP32: ora reale da Internet tramite NTP
#128Avanzato
Premium

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

4.5(13)
21
Orologio a matrice di punti, calendario e stazione meteo (MAX7219, DS1307)
#85Intermedio
Premium

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

5.0(50)
66
DS1302 Orologio RTC con display LCD
#46Intermedio
Premium

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

4.7(41)
51