Если вы профессионально или на любительском уровне занимаетесь изучением микроконтроллеров, то наверняка вы сталкивались с ситуацией когда памяти вашего микроконтроллера не хватает для сохранения необходимого вам объема данных. Наиболее часто эта проблема возникает в логгерах каких-нибудь данных: частоты сердечных сокращений, температуры, влажности и т.д. Хорошим решением в данном случае для увеличения объема сохраняемых данных является использование SD карты. Поэтому в данной статье мы рассмотрим принципы работы модуля чтения и записи SD карт и как его правильно подключить к плате Arduino.
Ранее на нашем сайте мы уже рассматривали подключение модуля чтения SD карт к плате Arduino в статьях про логгер данных температуры и влажности и бесконтактный термометр с креплением на стену, но в этой статье мы более подробно рассмотрим вопросы взаимодействия с данным модулем.
Необходимые компоненты
- Плата Arduino Uno (купить на AliExpress).
- Модуль чтения SD карт (купить на AliExpress).
Принципы работы модуля чтения SD карт
Распиновка модуля чтения SD карт
Модуль чтения Micro SD карт имеет 6 контактов: GND, VCC, MISO, MOSI, SCK и CS. Все эти контакты являются цифровыми, за исключением контактов VCC и Ground. Распиновка модуля чтения SD карт показана на следующем рисунке.
Назначение контактов модуля следующее:
GND – общий провод (земля) модуля, в нашем проекте его необходимо подключить к контакту земли (ground) платы Arduino.
VCC – контакт для подачи питания на модуль, его необходимо подключать к напряжению 5V или 3.3V.
MISO (Master In Slave Out) – контакт передачи данных по интерфейсу SPI от модуля.
MOSI (Master Out Slave In) – контакт передачи данных по интерфейсу SPI в модуль.
SCK – линия синхронизации в интерфейсе SPI, в нашем проекте источником тактовых импульсов будет плата Arduino.
CS (Chip Select) – линия для выбора ведомого устройства в интерфейсе SPI. В нашем проекте плата Arduino, управляя данным контактом, может включать/выключать работу модуля.
Компоненты модуля чтения SD карт
Это дешевый и простой в использовании модуль, который может быть использован во множестве различных приложений. Его составные части (компоненты) показаны на следующем рисунке.
Как видите из представленного рисунка, у модуля чтения SD карт всего три наиболее значимых компонента. Первый – это держатель карт формата Micro SD, он обеспечивает возможность легкой перестановки SD карты из одного модуля в другой. Второй – микросхема преобразователя уровня (level shifter IC). Поскольку сам модуль работает от питающего напряжения 3.3V, а его максимальное рабочее напряжение составляет 3.6V, то если мы непосредственно подключим его к 5V, то это с большой вероятностью выведет из строя SD карту. Кроме микросхемы преобразователя уровня модуль также содержит понижающий регулятор напряжения, который преобразует напряжение из 5V в 3.3V.
Наиболее часто задаваемые вопросы о модуле чтения SD карт
Какой стандарт форматирования лучшего всего подходит для SD карт?
При форматировании SD карт наиболее предпочтительным является формат exFAT.
Имеют ли SD карты прошивку (программное обеспечение)?
SD карты поставляются с записанной в них прошивкой, которая содержит инструкции для работы с ROM (read-only memory) и позволяют устройству «загружаться».
Уменьшает ли форматирование время жизни SD карт?
Прямого и точного ответа на этот вопрос нет. Но поскольку процесс форматирования работает со всей памятью SD карты, очищает на ней данные и помечает блоки как доступные, то, поскольку количество циклов чтения/записи для SD карты ограничено, скорее всего, он немного может уменьшать время жизни SD карты.
Что такое exFAT для SD карты?
exFAT (Extensible File Allocation Table) – это файловая система, разработанная компанией Microsoft в 2006 году и оптимизированная для различных типов флэш памяти, таких как USB носители и SD карты. exFAT была проприетарной системой до 28 августа 2019, когда Microsoft опубликовала ее спецификацию. Компания Microsoft владеет патентами над несколькими элементами ее дизайна.
Схема модуля чтения SD карт
Схема модуля чтения SD карт представлена на следующем рисунке. Как видите, она состоит из легко доступных компонентов общего назначения.
Схема проекта
Схема подключения модуля чтения SD карт к плате Arduino представлена на следующем рисунке.
Как видите, подключение модуля чтения Micro SD карт к плате Arduino UNO достаточно простое – необходимо всего лишь подключить контакты SPI модуля SCK, MISO и MOSI к аналогичным SPI контактам платы Arduino SCK (D13), MOSI (D12) и MISO(D11). Если же у нас к шине SPI будет подключено несколько устройств, то в этом случае необходимо подключить и линию CS (выбор ведомого) к плате Arduino. Более подробно об использовании интерфейса SPI в плате Arduino вы можете прочитать в этой статье.
Контакты VCC и Ground модуля чтения SD карт используются для подачи на него питания.
Внешний вид собранной конструкции проекта представлен на следующем рисунке.
Подготовка модуля чтения SD карт
Перед тем как вставлять SD карту в модуль чтения SD карт вам необходимо правильно ее отформатировать, иначе могут возникнуть проблемы с ее работой. Это связано с тем, что модуль чтения SD карт может работать только с файловыми системами FAT16 или FAT32. А при изготовлении SD карта могла быть предварительно отформатирована в другом формате. В этих случаях иногда даже проще использовать старую SD карту чем новую для уменьшения риска проблем совместимости.
Объяснение программы для Arduino
Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
В коде программы мы будем проверять наличие файла с именем “data_log.txt”. Если этот файл существует, то мы будем записывать в него информацию. Если файл не существует, мы будем создавать на SD карте этот файл и затем записывать в него информацию. Мы потом можем открыть этот файл на компьютере и проверить действительно ли в нем содержится информация, которую мы туда записали.
Первым делом в коде программы мы подключим библиотеку для работы с SD картами, объявим контакт chipSelect модуля и объявим файловую переменную myFile.
1 2 3 |
#include <SD.h> const int chipSelect = 10; File myFile; |
Далее, в функции setup, мы инициализируем последовательную связь для целей отладки. Также мы проверим корректно ли подключен модуль чтения SD карт к контактам интерфейса SPI платы Arduino.
1 2 3 4 |
// Open serial communications and wait for port to open: Serial.begin(9600); // wait for Serial Monitor to connect. Needed for native USB port boards only: while (!Serial); |
После этого мы запрограммируем функцию “check_and_create_file()”. В этой функции мы будем проверять существует ли на SD карте файл с именем data_log.txt. Если существует, то мы будем продолжать исполнение команды, если не существует, то мы будем создавать этот файл. Чтобы создать файл на SD карте вам необходимо быстро (без задержки) открыть и закрыть его – после этого файл будет создан.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
void check_and_create_file() { Serial.print("Initializing SD card..."); /*Check if the SD card exist or not*/ if (!SD.begin(chipSelect)) { Serial.println("initialization failed!"); while (1); } Serial.println("initialization done."); if (SD.exists("data_log.txt")) Serial.println("data_log.txt exists."); else { Serial.println("data_log.txt doesn't exist."); /* open a new file and immediately close it: this will create a new file */ Serial.println("Creating data_log.txt..."); myFile = SD.open("data_log.txt", FILE_WRITE); myFile.close(); /* Now Check again if the file exists in the SD card or not */ if (SD.exists("data_log.txt")) Serial.println("data_log.txt exists."); else Serial.println("data_log.txt doesn't exist."); } } |
Затем мы запишем немного текста на SD карту и параллельно передадим этот же текст в окно монитора последовательной связи. Благодаря этому мы будем знать что текст успешно записался на SD карту. Мы запрограммируем функцию read_write_sd_text(), которая будет делать это автоматически. Затем в основном цикле программы нам необходимо будет всего лишь вызывать эту функцию.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
void read_write_sd_text() { myFile = SD.open("data_log.txt", FILE_WRITE); // if the file opened okay, write to it: if (myFile) { Serial.print("Writing to data_log.txt..."); myFile.println("Testing Data Write 1, 2, 3."); // close the file: myFile.close(); Serial.println("done."); } else { // if the file didn't open, print an error: Serial.println("error opening data_log.txt"); } // re-open the file for reading: myFile = SD.open("data_log.txt"); if (myFile) { Serial.println("data_log.txt:"); // read from the file until there's nothing else in it: while (myFile.available()) { Serial.write(myFile.read()); } // close the file: myFile.close(); } else { // if the file didn't open, print an error: Serial.println("error opening data_log.txt"); } } |
Тестирование работы проекта
Представленное ниже видео подробно показывает работу нашего проекта. После запуска программы плата Arduino проверяет обнаружена ли SD карта или нет. Если она находит SD карту то она проверяет существует ли на ней текстовый файл или нет. Если существует, то программа продолжается дальше, если не существует – то создается новый текстовый файл. После этого в данный файл записывается небольшой фрагмент текстовой информации. Также этот текстовый фрагмент передается в окно монитора последовательной связи.
Возможные проблемы при работе с модулем чтения SD карт
- проверьте корректно ли на модуль подается питание или нет. Проверьте корректно ли работает встроенный на плате модуля регулятор напряжения LM1117-3.3V;
- отформатируйте Micro SD карту прежде чем вставлять ее в модуль чтения SD карт;
- быстрое форматирование в операционной системе Windows может некорректно сработать, поэтому SD карту нужно форматировать обычным способом (не быстрым), либо же вы можете запустить форматирование карты их командной строки (CMD) Windows;
- если вы используете старую micro sd карту убедитесь в чистоте ее контактов.
Исходный код программы (скетча)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
#include <SD.h> const int chipSelect = 10; File myFile; void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); // wait for Serial Monitor to connect. Needed for native USB port boards only: while (!Serial); check_and_create_file(); write_text(); } void loop() { // nothing happens after setup finishes. } void check_and_create_file() { Serial.print("Initializing SD card..."); /*Проверяем существует ли SD карта или нет*/ if (!SD.begin(chipSelect)) { Serial.println("initialization failed!"); while (1); } Serial.println("initialization done."); if (SD.exists("data_log.txt")) Serial.println("data_log.txt exists."); else { Serial.println("data_log.txt doesn't exist."); /* открываем новый файл и немедленно закрываем его – таким образом создастся новый файл */ Serial.println("Creating data_log.txt..."); myFile = SD.open("data_log.txt", FILE_WRITE); myFile.close(); /*Снова проверяем существует ли файл на SD карте или нет */ if (SD.exists("data_log.txt")) Serial.println("data_log.txt exists."); else Serial.println("data_log.txt doesn't exist."); } } void write_text() { myFile = SD.open("data_log.txt", FILE_WRITE); // если файл корректно открылся, записываем в него текст if (myFile) { Serial.print("Writing to data_log.txt..."); myFile.println("testing 1, 2, 3."); // закрываем файл: myFile.close(); Serial.println("done."); } else { // если файл не открылся, выводим сообщение об ошибке: Serial.println("error opening data_log.txt"); } // заново открываем файл для чтения: myFile = SD.open("data_log.txt"); if (myFile) { Serial.println("data_log.txt:"); // считываем из файла всю информацию до тех пор пока не достигнем конца файла // и передаем эту информацию в последовательный порт связи read from the file until there's nothing else in it: while (myFile.available()) { Serial.write(myFile.read()); } // закрываем файл: myFile.close(); } else { // если файл не открылся выводим сообщение об ошибке: Serial.println("error opening data_log.txt"); } } |
Все необходимые файлы для работы проекта можно скачать по следующей ссылке.