Модуль microSD: подключение к ESP32 и Arduino

Карта памяти по SPI

Гигабайты для журналов, настроек и картинок. Файлы в FAT32 читаются на любом компьютере.

Как работает

Карта работает по SPI: MOSI (данные к карте), MISO (от карты), SCK (такт) и CS (выбор). Библиотека SD (встроена в ядра Arduino и ESP32): SD.begin(CS), SD.open("/log.txt", FILE_APPEND), file.println(...), file.close().

Карта — устройство на 3,3 В. Модули для Arduino имеют стабилизатор и преобразователь уровней, для ESP32 подходят и простые модули без них.

Выводы

ВыводНазначение
CSвыбор карты
MISOданные от карты
MOSIданные к карте
SCKтактовый сигнал
VCCпитание
GNDобщий провод

Подключение к ESP32

Модуль microSDESP32
CSGPIO5
MISOGPIO19
MOSIGPIO23
SCKGPIO18
VCC3V3
GNDGND

Схема из примера «Карта SD: чтение и запись файлов».

Карта SD: чтение и запись файлов

Открыть пример целиком
Код скетча
#include <SD.h>
#include <SPI.h>

const int CS = 5;

void setup() {
  Serial.begin(115200);
  delay(200);

  if (!SD.begin(CS)) {
    Serial.println("карта не найдена: проверьте CS, MISO и питание");
    return;
  }
  Serial.printf("карта на месте, размер %llu МБ\n", SD.cardSize() / (1024 * 1024));

  // Что уже лежит на карте.
  File root = SD.open("/");
  for (File f = root.openNextFile(); f; f = root.openNextFile()) {
    Serial.printf("  %s  %u байт\n", f.name(), f.size());
    f.close();
  }

  // Читаем готовый файл.
  File readme = SD.open("/README.TXT");
  if (readme) {
    while (readme.available()) Serial.write(readme.read());
    readme.close();
  }

  // И пишем свой.
  File log = SD.open("/LOG.TXT", FILE_WRITE);
  if (log) {
    log.println("первая запись с платы");
    log.close();
    Serial.println("записано в /LOG.TXT");
  }
}

void loop() {
  delay(1000);
}

Подключение к Arduino Uno

Модуль microSDArduino Uno
CSD10
MISOD12
MOSID11
SCKD13
VCC5V
GNDGND

Схема из примера «Arduino Uno: журнал на карту SD».

Arduino Uno: журнал на карту SD

Открыть пример целиком
Код скетча
#include <SPI.h>
#include <SD.h>

// Карта SD на аппаратном SPI: 11, 12, 13 и выбор на 10.
//
// Три отличия от ESP32, о которые спотыкаются при переносе.
//
// **Выводы шины другие** и не выбираются: у Uno это 11 и 13, MISO на
// 12. На ESP32 те же роли на 23, 19 и 18.
//
// **Имена файлов только короткие**, восемь знаков плюс три на
// расширение. Библиотека для AVR длинных не знает: SD.open("data.log")
// откроет не то, что вы думаете, а SD.open("измерения.txt") не откроет
// ничего. Только латиница и только 8.3.
//
// **Памяти впритык.** Библиотека держит буфер сектора — 512 байт, ещё
// четверть оперативной памяти платы. Вместе с экраном OLED они на Uno
// уже не помещаются.
//
// На карте в модели уже лежит README.TXT — с него и начнём.

const int CS = 10;

void setup() {
  Serial.begin(9600);
  delay(200);

  if (!SD.begin(CS)) {
    Serial.println(F("карта не найдена: проверьте CS, MISO и питание"));
    return;
  }
  Serial.println(F("карта на месте"));

  // Что на ней лежит.
  File root = SD.open("/");
  for (File f = root.openNextFile(); f; f = root.openNextFile()) {
    Serial.print(F("  "));
    Serial.print(f.name());
    Serial.print(F("  "));
    Serial.print(f.size());
    Serial.println(F(" байт"));
    f.close();
  }

  // Читаем готовый файл.
  File readme = SD.open("README.TXT");
  if (readme) {
    while (readme.available()) Serial.write(readme.read());
    readme.close();
  }
}

void loop() {
  // Дописываем строку в журнал. Файл открывается и закрывается на
  // каждую запись намеренно: карту вынимают без предупреждения, а
  // закрытый файл переживёт это, незакрытый — нет.
  File log = SD.open("LOG.TXT", FILE_WRITE);
  if (log) {
    log.print(millis() / 1000);
    log.println(F(" c работы"));
    log.close();
    Serial.println(F("строка записана в LOG.TXT"));
  } else {
    Serial.println(F("не открылся LOG.TXT"));
  }

  delay(5000);
}

В железе

SPI по умолчанию: ESP32 (VSPI) — SCK GPIO18, MISO GPIO19, MOSI GPIO23, CS GPIO5; Arduino Uno — SCK D13, MISO D12, MOSI D11, CS обычно D10 (или D4).

Частые ошибки

Другие детали