Добавить в избранное

SD-карта с Arduino: логирование данных и файловый модуль

Чтение ≈ 4 мин

Подключение SD-карточки к Arduino по SPI: модуль с level shifter, библиотека SD, запись показаний датчиков в CSV, чтение файлов, ограничения FAT и практический проект логгера температуры.

Зачем 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 дороги — открывайте раз, пишите, закрывайте по событию.
Поделиться
Понравился материал?

Комментарии

Добавить комментарий