Модуль SD-карты для Arduino: регистратор данных в CSV с метками времени от RTC
Модуль SD-карты для Arduino: подключение по SPI, форматирование в FAT32, запись данных датчиков в CSV с метками времени от RTC, SD_MMC на ESP32, Pico и решение ошибки initialization failed.
Модуль SD-карты для Arduino — маленькая недорогая плата, которая позволяет сохранять показания датчиков (температуру, влажность, расстояние или координаты) в виде файлов на карте micro SD. Это самый простой способ собрать регистратор данных, который ведёт измерения днями и даже месяцами без подключённого компьютера: Arduino снимает показания, модуль записывает каждое из них новой строкой в CSV-файл на карте, а потом карта вставляется в компьютер, и данные превращаются в график в Excel. Модуль подключается по SPI и работает всего с несколькими строками кода на библиотеке SD, которая входит в состав Arduino IDE.
В этом руководстве пошагово разберём, как работает модуль, чем отличаются модули на 5 V и 3,3 V, как подключить его по SPI к Arduino Uno, Mega, ESP32 и Raspberry Pi Pico, как отформатировать карту в FAT32, как записывать и читать файлы и как вести CSV-журнал с датой и временем с помощью модуля RTC. Также рассмотрим быстрый интерфейс SD_MMC на ESP32, работу с SD-картой на Pico в MicroPython и способы исправить слишком частую ошибку «initialization failed» (ошибка инициализации).

Что такое модуль SD-карты и как он работает?
SD-карты работают от 3,3 V и умеют общаться двумя способами: в быстром собственном режиме SD и в более простом режиме SPI. Микроконтроллеры вроде Arduino общаются с картой по SPI. Задача модуля — сделать их электрически совместимыми: стабилизатор понижает 5 V до нужных карте 3,3 V, а микросхема преобразователя уровней (обычно 74LVC125A) переводит 5-вольтовые сигналы Arduino в безопасные для карты 3,3 V. Внутри карта состоит из блоков по 512 байт, а такими понятиями, как файлы, папки и имена файлов, занимается файловая система FAT. Всю тяжёлую работу берёт на себя библиотека SD: остаётся только открыть файл, записать в него и закрыть.
| Параметр | Значение |
|---|---|
| Интерфейс | SPI (линии MISO, MOSI, SCK, CS) |
| Питание (модуль micro SD со стабилизатором) | 4,5–5,5 V, стабилизатор 3,3 V на плате |
| Уровень сигналов | Совместим с 3,3 V и 5 V (благодаря преобразователю уровней) |
| Поддерживаемые карты | micro SD (до 2 ГБ) и micro SDHC (4–32 ГБ) |
| Файловая система | FAT16 или FAT32 |
| Ток | Несколько mA в простое, до 100 mA при записи |
| Имя файла (библиотека SD для Arduino) | Формат 8.3: до 8 символов в имени + 3 в расширении |
Модули SD-карт на 5 V и 3,3 V: какой выбрать?
| Тип модуля | Питание | Уровень сигналов | Подходит для |
|---|---|---|---|
| Модуль micro SD со стабилизатором (74LVC125A) | 5 V | 3,3 V и 5 V | Uno, Nano, Mega; ESP32 и Pico при питании от 5 V |
| Полноразмерный модуль SD-карты (пины +5 и +3.3) | 5 V или 3,3 V | У большинства нет настоящего преобразователя уровней | Платы на 3,3 V; с 5-вольтовыми сигналами работает ненадёжно |
| Модуль micro SD без стабилизатора (просто слот) | Только 3,3 V | Только 3,3 V | ESP32, Raspberry Pi Pico |
| Платы со встроенным слотом (например, ESP32-CAM) | От платы | 3,3 V | Используются напрямую с SD_MMC |
Для Arduino Uno, Nano или Mega выбирай модуль micro SD со стабилизатором и преобразователем уровней, как на фото, и подключай VCC к пину 5V. ESP32 и Pico работают от 3,3 V; с ними тоже можно использовать этот модуль, но питать его всё равно нужно от 5 V (VIN на ESP32, VBUS на Pico при питании по USB). Поскольку преобразователь уровней питается от 3,3 V, сигнал MISO, идущий обратно к микроконтроллеру, уже имеет уровень 3,3 V. Модули без стабилизатора подключаются прямо к пину 3V3; если такой модуль приходится использовать с 5-вольтовой Arduino, поставь делитель напряжения 1 kΩ + 2 kΩ на каждую из линий MOSI, SCK и CS или используй преобразователь логических уровней. Номиналы резисторов можно проверить в утилите делителя напряжения.
Подключение модуля SD-карты: пины SPI
| Пин модуля | 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 и SCK на любой плате должны идти к аппаратным пинам SPI; CS (выбор микросхемы, chip select) может быть любым цифровым пином, лишь бы в коде в SD.begin() передавался тот же номер. На готовых шилдах CS обычно D4 или D10. К одной шине SPI можно подключить несколько устройств: все они делят MISO, MOSI и SCK, а у каждого свой пин CS. Как устроен SPI, подробно объясняем в статье Интерфейс SPI. Где находятся пины на твоей плате, покажет утилита распиновки.
Подготовка SD-карты: форматирование в FAT32
- Объём карты: бери карту micro SDHC на 4–32 ГБ. Библиотека SD для Arduino поддерживает карты SDSC (до 2 ГБ) и SDHC; карты SDXC на 64 ГБ и больше продаются отформатированными в exFAT, а эту систему библиотека прочитать не может.
- Файловая система: отформатируй карту в FAT32 (на картах до 2 ГБ подойдёт и FAT16). NTFS и exFAT работать не будут.
- Windows: щёлкни по карте правой кнопкой в Проводнике, выбери «Форматировать» (Format), затем укажи файловую систему FAT32 и размер единицы распределения по умолчанию. Для карт больше 32 ГБ Windows не предлагает FAT32.
- macOS: выбери карту в «Дисковой утилите», нажми «Стереть» (Erase) и укажи формат MS-DOS (FAT) и схему «Основная загрузочная запись» (Master Boot Record).
- Самый надёжный вариант: бесплатная программа SD Card Formatter от SD Association форматирует карту по официальному стандарту и избавляет от большинства странных ошибок.
- Один раздел: на карте должен быть только один раздел. На картах, которые раньше стояли в Raspberry Pi или фотоаппарате, может остаться несколько разделов; удали их перед форматированием.
Первый тест по шагам: запись на SD-карту и чтение с неё
- Вставь отформатированную карту в модуль и подключи модуль к Arduino по таблице выше.
- Библиотека SD входит в Arduino IDE, устанавливать ничего не нужно: достаточно подключить SPI.h и SD.h в начале скетча.
- Загрузи код ниже и открой монитор порта на скорости 9600 бод.
- Если видны «tamam» (ОК) и содержимое файла, карта и подключение в порядке. При каждом запуске платы в TEST.TXT добавляется новая строка.
- Если вынуть карту и вставить её в компьютер, TEST.TXT откроется в любом текстовом редакторе.
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}| Функция | Что делает |
|---|---|
| SD.begin(cs) | Инициализирует карту; при успехе возвращает true |
| SD.open("NAME.TXT", FILE_WRITE) | Открывает файл для записи; если файла нет, создаёт его, если есть — дописывает в конец |
| SD.open("NAME.TXT") | Открывает файл для чтения (FILE_READ) |
| file.print() / println() (запись) | Записывает в файл текст или число |
| file.flush() | Записывает буферизованные данные на карту, не закрывая файл |
| file.close() | Записывает на карту оставшиеся данные и закрывает файл |
| file.available() / read() (чтение) | Проверяет, остались ли байты для чтения / читает один байт |
| SD.exists() / SD.remove() / SD.mkdir() (файлы и папки) | Проверяет, существует ли файл / удаляет файл / создаёт папку |
Запись данных датчиков в CSV с метками времени от RTC
Самый практичный формат файла для регистратора данных — CSV (comma-separated values, значения через запятую): каждая строка — одно измерение, каждый столбец — одно значение, а в первой строке стоят заголовки столбцов. Чтобы знать, когда снято каждое показание, в каждую строку стоит добавлять дату и время. millis() показывает только, сколько времени работает Arduino, и обнуляется при каждом перезапуске, поэтому используем модуль RTC (часы реального времени) с батарейкой-таблеткой. RTC продолжает отсчитывать время, даже когда Arduino выключена. DS1307 дешёвый, но может уходить на несколько секунд в сутки, а DS3231 благодаря кварцу с термокомпенсацией уходит всего примерно на минуту в год. Сравниваем их в статье Модули часов RTC.

Схема: модуль SD подключается к пинам SPI по таблице выше, модуль RTC — к шине I2C (на Uno SDA = A4, SCL = A5, VCC = 5V), а пин данных датчика DHT22 — к D2; если датчик без платы-модуля, добавь резистор 10 kΩ между пином данных и VCC. Установи библиотеки RTClib (Adafruit) и DHT sensor library через «Менеджер библиотек» (Library Manager). Подробнее о подключении датчика — в статье Датчики температуры и влажности DHT11 и 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}Каждые 10 секунд код считывает температуру и влажность, берёт дату и время из RTC и дописывает в конец VERI.CSV строку вида 2026-11-04,14:05:30,23.5,45.2. Поскольку файл закрывается после каждой записи, уже сохранённые данные переживут даже отключение питания. На платах AVR функция sprintf() не поддерживает числа с плавающей точкой (%f), поэтому значения сначала переводятся в текст функцией dtostrf(). Так как для отсчёта времени используется millis() вместо delay(), в loop() можно делать и другие дела. Если время в RTC ещё не задано, часы выставляются на момент компиляции кода. Для DS3231 достаточно написать RTC_DS3231 вместо RTC_DS1307 и проверять lostPower() вместо isrunning().
Сколько места это занимает? Одна строка — около 31 байта. При записи каждые 10 секунд получается 8640 строк в сутки, или около 260 КБ; за год — примерно 95 МБ. Так что при таком темпе карты на 8 ГБ хватит на десятилетия. Настоящее ограничение — не карта, а питание: если проект будет работать от батарей, заранее посчитай, на сколько их хватит, в калькуляторе времени работы от батареи.
Открываем данные с SD-карты в Excel
- Отключи питание Arduino, вынь карту из модуля и вставь её в компьютер.
- Скопируй VERI.CSV на компьютер: работать с копией безопаснее, чем прямо с картой.
- Открой в Excel пустую книгу и выбери файл через Данные › Из текстового/CSV-файла (Data › From Text/CSV).
- В окне предпросмотра выбери разделитель «Запятая» и нажми «Загрузить»: столбцы разделятся на дату, время, температуру и влажность.
- Выдели столбцы температуры и влажности и добавь линейный график на вкладке Вставка (Insert), чтобы увидеть, как они меняются со временем.
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Если удобнее передавать показания в Excel в реальном времени, пока Arduino подключена к компьютеру, и не вынимать карту, загляни в методы Data Streamer и PLX-DAQ в статье Передача данных с Arduino в Excel. А вот для проектов, которые работают в поле, вдали от компьютера, SD-карта незаменима.
SD-карта с ESP32 (SPI)
В ядре ESP32 для Arduino есть своя библиотека SD, и работает она почти так же, но с тремя важными отличиями: пути к файлам начинаются с / («/olcumler.csv»), длинные имена файлов разрешены, а FILE_WRITE перезаписывает файл с нуля. Для дописывания нужен FILE_APPEND; если перенести код для Uno без изменений, старые данные будут стираться при каждом запуске платы. Пины SPI по умолчанию: SCK 18, MISO 19 и MOSI 23, а для CS обычно используется GPIO 5. Тип и объём карты тоже можно прочитать одной строкой:
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}Код каждые 5 секунд записывает «сырое» значение (0–4095) фоторезистора (LDR), подключённого к GPIO 34. На ESP32 для точного времени даже не нужен модуль RTC: можно подключиться к Wi-Fi, получить время с NTP-сервера и добавлять метку времени в каждую строку через getLocalTime(). Если провода длинные или карта работает ненадёжно, снизь скорость SPI: SD.begin(5, SPI, 1000000) запускает карту на 1 MHz. В регистраторе с батарейным питанием глубокий сон между измерениями увеличивает время работы от батареи в разы.
ESP32 SD_MMC: быстрый интерфейс SD и ESP32-CAM
Помимо SPI, у ESP32 есть контроллер SDMMC, который говорит на собственном быстром протоколе карты. В 4-битном режиме библиотека SD_MMC в несколько раз быстрее SPI, поэтому идеально подходит для больших файлов вроде фотографий или звука. На классической ESP32 пины фиксированы: CLK GPIO 14, CMD GPIO 15, D0 GPIO 2, D1 GPIO 4, D2 GPIO 12, D3 GPIO 13, и этим линиям нужны подтягивающие резисторы 10 kΩ. В 1-битном режиме используются только CLK, CMD и D0; он медленнее, зато освобождает GPIO 4, 12 и 13. Слот micro SD на плате ESP32-CAM подключён именно к этим пинам, а 1-битный режим не даёт вспышке на GPIO 4 мигать при каждом обращении к карте.
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-карта с Raspberry Pi Pico (MicroPython)
В MicroPython SD-карты обслуживает драйвер sdcard.py из micropython-lib. Если на компьютере есть mpremote, установи драйвер командой mpremote mip install sdcard или скопируй файл на Pico через Thonny. Карта монтируется как папка /sd с помощью os.mount(), а дальше с ней работают обычными файловыми командами Python (open, write). Код ниже считывает встроенный датчик температуры Pico и каждые 10 секунд записывает строку CSV. Если Pico для тебя в новинку, сначала прочитай Что такое 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 secondsУ Pico нет часов с батарейным питанием: при подключении к Thonny её часы автоматически выставляются по компьютеру, а при автономной работе отсчёт начинается с 1 января 2021 года. Для точных меток времени можно добавить модуль DS3231 или на Pico W получать время из интернета по NTP. Если карта не вставлена или подключение неверное, драйвер выдаёт OSError: no SD card (карта не найдена). Если программировать Pico в Arduino IDE (ядро arduino-pico), подойдёт тот же подход с библиотекой SD: пины SPI0 по умолчанию совпадают с таблицей, а для CS достаточно написать SD.begin(17).
Как не потерять данные: питание, частота записи и ресурс карты
- Без close() или flush() на карту ничего не попадает: библиотека сначала собирает данные в 512-байтном буфере. Если файл всё время открыт, вызывай flush() каждые несколько строк.
- Не вынимай карту во время записи: если выдернуть карту или отключить питание посреди записи, файловая система может повредиться. Хорошая привычка — кнопка, которая останавливает запись, и светодиод, который показывает, что запись идёт.
- Обеспечь стабильное питание: при записи карта потребляет до 100 mA. Конденсатор 10–100 µF между VCC и GND модуля уменьшает просадки напряжения и случайные ошибки записи.
- Не открывай и не закрывай файл слишком часто: если снимать десятки показаний в секунду, открывать и закрывать файл ради каждой строки слишком медленно; накапливай показания в ОЗУ и записывай пачками по 10–20 строк.
- Ресурс карты: SD-карта внутри распределяет запись по разным ячейкам (выравнивание износа, wear leveling), поэтому регистратор, который пишет несколько строк в минуту, годами не износит карту. И всё же выбирай карту известного производителя.
- Дели данные на файлы: отдельный файл на каждый день (например, 20261104.CSV) сохраняет файлы небольшими, а если что-то пойдёт не так, теряются данные только за этот день.
Идеи проектов с модулем SD-карты
- Регистратор метеостанции: записывай температуру, влажность и давление каждый час с помощью BME280 и строй график за целый сезон.
- Журнал полива растений: записывай показания датчика влажности почвы и моменты включения насоса, чтобы изучить свой режим полива.
- Регистратор GPS-маршрута: сохраняй маршрут велопрогулки или похода в CSV с помощью NEO-6M GPS, а потом показывай его на карте.
- Журнал прохода по картам: записывай в файл каждую карту, считанную RFID RC522, вместе с датой и временем.
- Учёт энергопотребления: измеряй и записывай ток, который устройство потребляет в течение дня, с помощью датчика тока ACS712.
- MP3-плеер: DFPlayer Mini воспроизводит аудиофайлы со своего слота micro SD, а Arduino только отправляет команды.
Частые ошибки и их решение
| Симптом | Вероятная причина | Решение |
|---|---|---|
| «initialization failed» (ошибка инициализации) | Карта не вставлена, подключение неверное или пин CS не совпадает с кодом | Проверь, что MISO, MOSI и SCK подключены к аппаратным пинам SPI, а номер CS в SD.begin() указан верно |
| «initialization failed» (подключение верное) | Модуль со стабилизатором питается от 3,3 V или питание слабое | Питай модуль от 5 V, укороти провода, добавь конденсатор между VCC и GND |
| «Could not find FAT16/FAT32 partition» (раздел FAT16/FAT32 не найден) | Карта отформатирована в exFAT или NTFS; карта SDXC на 64 ГБ и больше | Отформатируй в FAT32 карту объёмом до 32 ГБ |
| Файл не открывается («error opening») | Имя файла нарушает правило 8.3 или предыдущий файл не закрыт | Используй короткое имя вроде VERI.CSV и закрывай каждый файл через close() |
| Файл пустой или в нём нет последних строк | Питание пропало до вызова close() или flush() | Закрывай файл после каждой записи или регулярно вызывай flush() |
| SD-карта перестаёт работать после добавления другого SPI-устройства | CS другого устройства «висит в воздухе» или модуль не отпускает линию MISO | В начале setup() установи все пины CS в OUTPUT и HIGH; при необходимости используй модуль, который отпускает MISO |
| Uno зависает или ведёт себя странно | Не хватает ОЗУ: библиотека SD занимает около 650 байт, а буфер OLED-дисплея 1 КБ | Оборачивай текст в F(); при необходимости переходи на Mega или ESP32 |
| На ESP32 старые данные стираются при каждой загрузке | Файл открывается с FILE_WRITE | Используй FILE_APPEND, чтобы дописывать в конец |
| «Card Mount Failed» (не удалось смонтировать карту) на ESP32 | Питание, подключение, высокая скорость SPI или нет подтяжек при SD_MMC | Снизь скорость SPI до 1 MHz; с SD_MMC попробуй 1-битный режим |
Модуль SD-карты превращает проект, который только измеряет, в устройство, которое ведёт записи, а несколько дней реальных данных расскажут гораздо больше, чем одно показание. В приложении BlueGrays есть регистратор температуры на ESP32 с DHT22, DS1307 RTC, micro SD и OLED, цифровые часы на основе RTC и проекты для измерения температуры и влажности — всё с пошаговыми схемами подключения и кодом.
Частые вопросы
Карту какого объёма может использовать Arduino?
Стандартная библиотека SD для Arduino поддерживает карты SDSC и SDHC, отформатированные в FAT16 или FAT32, то есть карты до 32 ГБ. Карты SDXC на 64 ГБ и больше поставляются с exFAT, и эта библиотека их не читает. Для регистратора данных карты на 4–16 ГБ более чем достаточно.
Почему SD-карта выдаёт «initialization failed»?
Самые частые причины: неверный пин CS, MISO, MOSI или SCK не подключены к аппаратным пинам SPI, карта отформатирована не в FAT32 или модуль со стабилизатором питается от 3,3 V. Сначала запусти пример CardInfo, затем попробуй провода покороче и питание модуля от 5 V.
Работает ли модуль SD-карты от 3,3 V?
Модули без стабилизатора работают прямо от 3,3 V и подходят для ESP32 или Pico. Модулям micro SD со стабилизатором и преобразователем уровней нужно 4,5–5,5 V; при питании от 3,3 V карте не хватает напряжения. Такие модули можно питать от VIN на ESP32 или VBUS на Pico.
Как открыть CSV-файл Arduino с SD-карты в Excel?
Скопируй файл на компьютер и импортируй его в Excel через «Данные › Из текстового/CSV-файла», выбрав разделитель «Запятая». Если в твоём Excel десятичный разделитель — запятая, числа могут выглядеть неправильно; тогда преобразуй столбцы с языковым стандартом «английский (США)» или используй в коде точку с запятой как разделитель.
Как часто Arduino может записывать на SD-карту?
Несколько строк в секунду — не проблема, но открывать и закрывать файл ради каждой строки долго. Для быстрых измерений накапливай данные в ОЗУ и записывай пачками или держи файл открытым и регулярно вызывай flush(). При медленном темпе, например одна запись в минуту, самый надёжный способ — каждый раз открыть, записать и закрыть.
Можно ли одновременно использовать модуль SD-карты с RFID или TFT-дисплеем?
Да. Устройства SPI делят линии MISO, MOSI и SCK, а каждое использует свой пин CS. При проблемах установи все пины CS в OUTPUT и HIGH в начале setup(). Преобразователь уровней на некоторых дешёвых модулях micro SD никогда не отпускает линию MISO; в таком случае используй модуль, который её отпускает, или вторую шину SPI на ESP32.
Что собрать после прочтения
Все проекты
Температура и влажность с DHT11
Насколько тепло в твоей комнате и влажный ли воздух или сухой? Датчик DHT11 измеряет температуру и влажность, а Arduino выводит значения на двухстрочный LCD-экран и обновляет их каждые пару секунд. Ес

Регистратор температуры на ESP32 (DHT22 + DS1307 RTC + microSD + OLED)
Собери на ESP32 регистратор температуры с отметками времени! Каждую минуту читай температуру и влажность с DHT22, бери реальное время из DS1307 RTC и записывай всё на карту microSD в формате CSV. OLED показывает текущую температуру (крупным шрифтом), влажность в процентах, время и счётчик записей. Файл /temp_log.csv на SD-карте открывается в Excel, Google Sheets или Python pandas — идеально для теплиц, комнат, лабораторий и хранения продуктов.

Цифровые часы на ESP32 и DS1307 RTC (I2C + LCD)
В этом проекте время и дата из модуля часов реального времени (RTC) DS1307 выводятся на I2C LCD-экран 16x2. DS1307 — RTC с резервной батарейкой, который хранит время даже при выключенной ESP32. Оба модуля делят одну шину I2C (SDA/SCL), и ты узнаёшь, как управлять несколькими устройствами всего по двум сигнальным проводам. Проект даёт практические знания о протоколе I2C, работе модуля RTC и динамическом выводе данных на LCD-экран.

Температура и влажность с DHT22 на ESP32 (с LCD-дисплеем)
Этот проект измеряет температуру и влажность воздуха датчиком DHT22 и в реальном времени показывает данные на I2C LCD 16x2. Данные читаются с датчика по однопроводному протоколу через библиотеку Adafruit DHT. Проект служит основой для IoT-метеостанций, умного дома или систем мониторинга среды в теплицах. Связь с DHT22 идёт через пин GPIO 4 у ESP32.

Глубокий сон ESP32: экономия батареи (OLED + счётчик в RTC RAM)
Режим глубокого сна (Deep Sleep) у ESP32 снижает потребление до ~10 µA, выключая процессор и большую часть периферии, — это важно для IoT-устройств на батарейках. В этом проекте используются три источника пробуждения: таймер (15 секунд), внешний пин (EXT0 — кнопка GPIO 33) и касание (T0/GPIO 4). Переменные с RTC_DATA_ATTR сохраняются во время глубокого сна — счётчики загрузок, пробуждений по таймеру и по кнопке ведутся непрерывно.

Точное время из интернета через NTP на ESP32
ESP32 подключается к Wi-Fi и получает точное время с точностью до миллисекунд от серверов NTP (Network Time Protocol). Благодаря функции configTzTime() автоматически применяется часовой пояс Турции (TRT, UTC+3), а в странах с летним временем переходы обрабатываются автоматически по строке POSIX TZ. Время выводится в монитор порта и на необязательный I2C LCD. configTzTime() запускает службу SNTP, которая периодически пересинхронизирует часы.

Часы, календарь и метеостанция на матрице (MAX7219, DS1307)
Табло с бегущей строкой для стола или стены, которое по очереди показывает время, дату и погоду в комнате. На светодиодном дисплее 8x32 сначала видна температура в градусах Цельсия и Фаренгейта, затем

Часы на DS1302 RTC с LCD-дисплеем
Маленькие настольные часы, которые помнят время даже при отключении питания. Модуль часов DS1302 считает время благодаря своей крошечной батарейке; каждую секунду Arduino читает его и выводит время и
Другие статьи
Приложение BlueGrays
Собери эту схему шаг за шагом в телефоне
Схема подключения, код и список деталей на одном экране. 200+ проектов на Arduino, ESP32 и Pico готовы к сборке.
Наведи камеру телефона
Наведи камеру на код — откроется магазин приложений на телефоне.
или открыть магазин

