Зачем SD-карта в проекте
EEPROM у Arduino всего 1 КБ — для логов мало. SD-карта даёт гигабайты: показания датчиков за месяцы, отладочные логи, конфиги, аудио-файлы, прошивки. Модуль SD-ридера для Arduino стоит копейки и подключается по SPI.
Важно: SD-карты работают на 3.3 В. Хорошие модули имеют level shifter на плате; дешёвые без него могут не работать от 5-вольтовых сигналов Uno — берите с преобразователем уровней.
Подключение
SD-модуль VCC ── 5V (модули с level shifter берут 5В, преобразуют сами)
GND ── GND
Arduino D13 (SCK) ── SCK
Arduino D12 (MISO) ── MISO
Arduino D11 (MOSI) ── MOSI
Arduino D10 (CS) ── CS (можно любой, но 10 — стандарт)
SPI-пины на Uno — только эти: 11 (MOSI), 12 (MISO), 13 (SCK). CS можно брать любой, но 10 принято.
Первый код: пишем файл
Встроенная библиотека SD — ничего ставить не нужно:
#include <SPI.h>
#include <SD.h>
const int CS = 10;
void setup() {
Serial.begin(9600);
if (!SD.begin(CS)) {
Serial.println("SD не инициализирована");
while (1); // без карты дальше не идём
}
Serial.println("SD готова");
File f = SD.open("log.txt", FILE_WRITE);
if (f) {
f.println("первая запись");
f.close();
Serial.println("записано");
}
}
FILE_WRITE создаёт файл или дописывает в конец. f.close() обязателен — без него данные могут не сброситься на карту.
Логирование: CSV для Excel
CSV — простейший формат: значения через точку с запятой, Excel и Google Sheets откроют напрямую:
void logData(float temp, float hum) {
File f = SD.open("data.csv", FILE_WRITE);
if (f) {
// разделитель ; — для русской локали Excel
f.print(millis() / 1000); // секунда с старта
f.print(";");
f.print(temp);
f.print(";");
f.println(hum);
f.close();
}
}
Раз в N секунд пишем строку — получается таблица с временными метками.
Чтение файла
File f = SD.open("config.txt");
if (f) {
while (f.available()) {
Serial.write(f.read());
}
f.close();
}
// или посимвольно в строку
String line;
while (f.available()) {
char c = f.read();
if (c == '\n') { processLine(line); line = ""; }
else line += c;
}
Датчик + SD: реальный логгер
DHT22 + SD + часы DS3231 — полноценный логгер температуры:
#include <SD.h>
#include <DHT.h>
#include <RTClib.h>
DHT dht(2, DHT22);
RTC_DS3231 rtc;
void setup() {
SD.begin(10);
dht.begin();
rtc.begin();
}
void loop() {
float t = dht.readTemperature();
DateTime now = rtc.now();
File f = SD.open("log.csv", FILE_WRITE);
if (f) {
f.print(now.timestamp());
f.print(";");
f.println(t);
f.close();
}
delay(60000); // раз в минуту
}
Ограничения файловой системы
- Формат карты — FAT16/FAT32, до 32 ГБ (большие exFAT не поддерживаются стандартной библиотекой).
- Имена файлов — формат 8.3 (
log.txt, неverylongname.csv). Для длинных — библиотекаSdFatс LFN. - Одновременно открытых файлов мало — открывайте, пишите, закрывайте.
- Частые записи изнашивают карту — буферизуйте данные и пишите реже.
Типичные проблемы
SD.beginпадает: нет level shifter на модуле, перепутаны MISO/MOSI, карта не в FAT32, плохой контакт CS.- Записи теряются: забыли
f.close()— буфер не сброшен на карту. - «Файл не открывается»: имя длиннее 8.3 или нет на карте.
- Мусор в файле: питание проседает при записи — конденсатор на модуле.
- Медленно: SPI на Uno медленный; для аудио/видео берите SdFat и ESP32.
Итог
SD-модуль превращает Arduino в самописец: SPI-пины 10–13, SD.begin, File для записи и чтения, CSV для анализа в Excel. Три правила: level shifter для 5В-плат, FAT32 и карта до 32 ГБ, всегда f.close(). С этим делают логгеры, MP3-плееры, конфиги и историю измерений.
Полный пример: логгер температуры
#include <SPI.h>
#include <SD.h>
#include <DHT.h>
const int CS = 10; // chip select модуля
DHT dht(2, DHT22);
File log;
void setup() {
Serial.begin(9600);
dht.begin();
if (!SD.begin(CS)) {
Serial.println("SD не найдена");
while (true);
}
Serial.println("SD готова");
}
void loop() {
float t = dht.readTemperature();
float h = dht.readHumidity();
if (isnan(t)) return;
log = SD.open("log.csv", FILE_WRITE);
if (log) {
log.printf("%lu,%.1f,%.1f\n", millis() / 1000, t, h);
log.close();
}
delay(60000); // раз в минуту
}
Чтение файла
File f = SD.open("log.csv");
while (f.available()) Serial.write(f.read());
f.close();
Полезные операции
SD.exists("file.txt");
SD.remove("old.txt");
SD.mkdir("data");
SD.open("data/2025-10.csv", FILE_WRITE);
Форматирование SD
- Файловая система FAT16 или FAT32 — exFAT не поддерживается стандартной SD.
- Карта 8–32 ГБ — оптимум; большие могут не инициализироваться.
- Форматируйте утилитой SD Memory Card Formatter, а не Windows-форматом.
Уровни сигналов
Модуль SD работает на 3.3 В — у качественных модулей есть стабилизатор и level shifter, у дешёвых нет. Для Uno (5 В логика) берите модуль с преобразователем уровней или добавьте делители напряжения на линиях MOSI/SCK/CS (MISO в обратную сторону можно без делителя).
Частые проблемы
- SD.begin возвращает false: CS-пин не тот, модуль без level shifter, карта в exFAT, плохой контакт.
- Файл пустой: забыли
close()— данные в буфере потеряны при выключении. - Карточка умирает: дешёвые модули без защиты портят карты — качайте логи и используйте
flush()редко. - Медленно: каждый
open/close— милисекунды; открывайте файл раз, пишите, закрывайте по событию.
Проекты
- Метеостанция с логом на месяц.
- Чёрный ящик для машины/дрона.
- Импульсный счётчик с сохранением.
- WAV-плеер (SD + ЦАП).
- Файловый сервер настроек.
Полный пример: логгер с датой
#include <SPI.h>
#include <SD.h>
#include <RTClib.h>
RTC_DS3231 rtc;
File log;
void setup() {
SD.begin(10);
rtc.begin();
}
void loop() {
DateTime now = rtc.now();
log = SD.open("log.csv", FILE_WRITE);
if (log) {
log.printf("%04d-%02d-%02d %02d:%02d:%02d,%.1f\n",
now.year(), now.month(), now.day(),
now.hour(), now.minute(), now.second(),
dht.readTemperature());
log.close();
}
delay(60000);
}
Полезные операции
SD.exists("file.txt");
SD.remove("old.txt");
SD.mkdir("data");
SD.open("data/2025.csv", FILE_WRITE);
Форматирование
- FAT16 или FAT32 — exFAT не поддерживается.
- Карта 8–32 ГБ — оптимум.
- Форматируйте SD Memory Card Formatter, не Windows.
Частые проблемы
- SD.begin false: CS-пин, level shifter, exFAT.
- Файл пустой: забыли
close()— данные в буфере потеряны. - Медленно:
open/closeдороги — открывайте раз, пишите, закрывайте по событию.