Постоянная память, доступная пользователю на самой «навороченной» плате Arduino Mega всего 4 килобайта. Arduino Nano имеет всего 1 килобайт памяти. Этого хватит для запоминания нескольких переменных. А что если возникает задача, в которой необходимо хранить большие объёмы данных? Например, историю изменения температуры или телеметрию квадрокоптера? Идеальное решение проблемы — подключение к контроллеру SD карты. Вы получаете практически неограниченный объём для хранения любой информации. SD карту можно подключить к Arduino напрямую, припаяв провода прямо к контактам карты. Однако, проще и удобнее воспользоваться специальным модулем для работы с SD картой. В статье рассказано о подключении такого модуля к различным платам Arduino и работе с самой SD картой. Заказать модуль у проверенного мной продавца вы можете здесь по ссылке доступны модули и для полноразмерной SD карты и для microSD.
Подключение модуля SD карты к Arduino
Модуль располагает двухрядной гребёнкой штырьковых контактов. Однако, для подключения используются всего 6 контактов. Работа с модулем осуществляется по интерфейсу SPI. Вы могли заметить на платах Arduino небольшой разъём, состоящий из 6 штырьков на лицевой части платы. Это и есть SPI разъём. Правильное его название — ICSP. Он есть на большинстве плат. Для подключения к этому разъёму удобно использовать провода мама-мама. На некоторых моделях (Mega2560, Nano, Uno) SPI пины продублированы на цифровых пинах платы. В таблице ниже приведено соответствие SPI контактам цифровых выводов:
Плата Arduino | MOSI | MISO | SCK |
Nano, Uno | 11 | 12 | 13 |
Mega2560 | 51 | 50 | 52 |
Leonardo | ICSP-4 | ICSP-1 | ICSP-3 |
В Arduino Leonardo пины SPI разъёма не дублируются на цифровые пины и подключить модуль можно только к SPI разъёму по следующей схеме:
Итак, выводы модуля подключаем к выводам платы в соответствии с таблицей. MOSI модуля к MOSI платы и т.д. Вывод модуля CS можно подключить к любому свободному цифровому выводу платы. Для удобства, подключаем его к 10 цифровому выводу. Именно этот вывод используется в стандартных примерах и нам не придётся править программу перед загрузкой в плату. SD модуль оборудован стабилизатором напряжения, поэтому, для питания модуля можно использовать как напряжение 5В, так и 3,3В. Мы рекомендуем использовать 5В. Внимание — не рекомендуется подключать к плате одновременно 3,3 и 5В!
Установите в модуль SD карту, отформатированную в файловую систему FAT32 или FAT16 и загрузите в плату следующий скетч:
/* * SD карта подключается так: ** MOSI - пин 11 ** MISO - пин 12 ** CLK - пин 13 ** CS - пин 4 */ #include <SD.h>; File myFile; void setup() { Serial.begin(9600); while (!Serial) { ; //Ждём инициализации серийного порта. Нужно для Leonardo } Serial.print("Initializing SD card..."); // Магия. Этот вывод должен быть настроен как выход. // Иначе, некоторые функции могут не работать. pinMode(10, OUTPUT); if (!SD.begin(4)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done."); if (SD.exists("example.txt")) { Serial.println("example.txt exists."); } else { Serial.println("example.txt doesn't exist."); } //Откроем новый файл и сразу же закроем его: Serial.println("Creating example.txt..."); myFile = SD.open("example.txt", FILE_WRITE); myFile.close(); //Проверяем, создан ли файл: if (SD.exists("example.txt")) { Serial.println("example.txt exists."); } else { Serial.println("example.txt doesn't exist."); } //Удаляем файл: Serial.println("Removing example.txt..."); SD.remove("example.txt"); if (SD.exists("example.txt")){ Serial.println("example.txt exists."); } else { Serial.println("example.txt doesn't exist."); } } void loop() { //Тут ничего не происходит }
Этот скетч проверяет, создан ли файл example.txt на карте памяти. Если не создан — создаёт его.
Другой скетч. Пример записи и чтения данных с карты:
/* * SD карта подключается так: ** MOSI - пин 11 ** MISO - пин 12 ** CLK - пин 13 ** CS - пин 4 */ #include <SD.h>; File myFile; void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { ; //Ждём инициализации серийного порта. Нужно для Leonardo } Serial.print("Initializing SD card..."); // Магия. Этот вывод должен быть настроен как выход. // Иначе, некоторые функции могут не работать. pinMode(10, OUTPUT); if (!SD.begin(4)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done."); // Открываем файл для записи. Только один файл // может быть открыт одновременно // вы можете закрыть файл, что бы открыть другой. myFile = SD.open("test.txt", FILE_WRITE); // Если файл открылся, пишем в него: if (myFile) { Serial.print("Writing to test.txt..."); myFile.println("testing 1, 2, 3."); // Закрываем файл: myFile.close(); Serial.println("done."); } else { // если файл не открылся, сообщает об ошибке: Serial.println("error opening test.txt"); } // открываем файл только для чтения myFile = SD.open("test.txt"); if (myFile) { Serial.println("test.txt:"); // читаем файл посимвольно до конца: while (myFile.available()) { Serial.write(myFile.read()); } // закрываем файл: myFile.close(); } else { // если файл не открылся, сообщает об ошибке: Serial.println("error opening test.txt"); } } void loop() { //Тут ничего не происходит }
Скетч довольно понятный сам по себе и не требует подробных объяснений. Всё не намного сложнее, чем работа с серийным портом.
Оба эти скетча доступны среди стандартных примеров среды разработки Arduino IDE (Файл->Примеры->SD). В стандартных примерах есть и другие скетчи, раскрывающие некоторые приёмы работы с SD картой.
Вот список стандартных примеров с описанием:
Datalogger: Пример сохранения значений с 3х аналоговых датчиков, подключённых к Arduino
DumpFile: Чтение файла с SD карты и передача содержимого файла в серийный порт
Files: Создание и удаление файла на SD карте
listfiles: Выводит список файлов на SD карте
ReadWrite: Чтение и запись в файл
CardInfo: Выводит некоторую информацию о подключённой SD карте
Напоминаю, модуль у проверенного продавца вы можете заказать здесь. Полный список товаров, которые я заказал и протестировал здесь.