SD-карта довольно распространённый тип носителя в наше время. Каждый разработчик рано или поздно сталкивается с необходимостью хранить большой объём данных и\или использовать для каких-либо долгосрочных целей энергонезависимый носитель информации. На рынке существует огромное множество модулей для подключения SD-карт к Arduino или любому другому микроконтроллеру.
Практическое использование одного из таких модулей с разбором кода и схемотехнике предлагаю рассмотреть вам в этой статье.
На днях мне пришёл заказанный модуль для работы с SD-картами. В этом посте я расскажу, как усовершенствовать, сделанный нами в прошлом, датчик для измерения температуры, а именно – мы избавим себя от надобности копирования данных из консоли вывода в Excel для дальнейшего анализа, заставив Arduino сохранять данные на SD-карту в виде csv-файла. Данные будут записываться в файл в два столбца – в первом будут единицы времени (или просто номер строки), а во втором значение напряжения на термисторе или ином датчике, которое, как Вы помните, пропорционально температуре.
Необходимые компоненты
- Необходимые компоненты здесь те же, что и в посте про измеритель температуры
- Модуль для работы с SD-картами
Собираем схему
Описывать схему сборки измерителя температуры я не буду, если Вы забыли или не знаете как его собирать – обратитесь к посту, ссылка на который указана выше.
Рассмотрим схему подключения SD модуля. Каждый модуль имеет следующие контакты: GND, 5V, 3V (3.3V), CS, MOSI, SCLK (SCK), MISO, GND. Подключим некоторые из этих контактов к следующим контактам Arduino:
- GND – к земле с Arduino;
- 5V разъём к 5 вольтовому разъёму Arduino. (Аналогично 3.3V) Подключать оба разъёма одновременно – бессмысленно, я подключаю только 5V;
- CS – к 4 разъёму;
- MOSI – к 11 разъёму;
- SCLK (SCK) – к 13 разъёму;
- MISO – к 12 разъёму.
На этом наше подключение окончено. Для подключения можете использовать макетную плату – просто втыкаете туда SD модуль и в правильном порядке протягиваете провода от соответствующих дорожек к нужным разъёмам.
Подготавливаем SD-карту
SD модуль работает только с SD картами, отформатированными под файловую систему FAT16 или FAT32. Карту необходимо заранее отформатировать на компьютере. БУДЬТЕ ВНИМАТЕЛЬНЫ! При форматировании все данные, находящиеся на носителе, будут уничтожены! Не забудьте переписать их в другое место перед форматированием!
Программируем Arduino
// Подключаем библиотеку для работы с шиной SPI (необходима для работы библиотеки SD)
#include <SPI.h>
// Подключаем библиотеку для работы с SD-картами
#include <SD.h>
File myFile;
// Задаём начальное время (точку отсчёта)
int time = 0;
// Указываем номер аналогового разъёма для считывания данны
int tempPin = 0;
void setup()
{
// Открываем serial порт
Serial.begin(9600);
// Выдаём сообщение о том, что начинается инициализация SD-карты
Serial.print("Initializing SD card...");
pinMode(10, OUTPUT);
// Проверяем готовность SD модуля. Если модуль не готов - выдаём сообщение
if (!SD.begin(4)) {
Serial.println("initialization failed!");
return;
}
// Проверяем, существует ли на карте файл data.csv, если существует, то удаляем его.
if(SD.exists("data.csv")) {
SD.remove("data.csv");
}
// Выводим сообщение о том, что инициализация прошла успешно
Serial.println("initialization done.");
}
void loop()
{
// Считываем данные (напряжение) с нулевого аналогового разъёма.
int temp = analogRead(tempPin);
// Увеличиваем значение времени (номер строки) на единицу. Если вы будете записывать данные раз в минуту, но хотите чтобы время записывалось в секундах - прибавляйте не единицу, а 60.
time = time + 1;
// Открываем файл data.csv для записи
myFile = SD.open("data.csv", FILE_WRITE);
// Если удалось открыть файл для записи, то записываем данные
if (myFile) {
// Выводим данные на экран
Serial.print(time);
Serial.print("; ");
Serial.println(temp);
// Записываем время
myFile.print(time);
// Добавляем точку с запятой
myFile.print(";");
// Добавляем температуру и добавляем перенос строки
myFile.println(temp);
// закрываем файл
myFile.close();
} else {
// Выводим сооб щение о том, что открыть файл не удалось
Serial.println("error opening data.csv");
}
// Повторяем считывание данных с датчика и запись на флэш-карту через одну секунду
delay(1000);
}
Загружаем наш скетч в Arduino, запускаем консоль (ctrl+shift+M) в среде Arduino и видим на экране каждую секунду две пары значений – номер строки (или же время) и значение напряжение, соответствующее данной температуре. Подождите, например, 10 секунд и отключите питание от Arduino. Извлеките карточку и вставьте её в компьютер. На карте у вас будет файл data.csv, открыв который в Excel вы увидите 2 столбика значений, что и в консоли Arduino. Теперь вы можете построить график или рассчитать среднее значение температуры в вашей комнате за какой-то промежуток времени.
ВНИМАНИЕ! Флэш-память имеет ограниченный ресурс записи, поэтому для увеличения срока жизни флэшки, оптимизируйте количество записей в память. Например, в нашем случае, сделайте массив и таймер. Массив будет хранить, допустим, 10 значений и затем записывать их на флэш, либо когда будет накоплено 10 значений, либо когда таймер отсчитает 1 минуту.Таким образом количество записей во флэш будет уменьшено до 10 раз.
На этом всё, задавайте свои вопросы мне в комментариях к этому посту, до скорых встреч!
Подскажите пожалуйста интернет магазин где можно купить плату расширения на SD.
Сам контроллер нашел. А вот платку никак не могу найти, ну или как она точно называется…
Ответ для Сергей: Что значит плату расширения на SD? SD модуль для работы с картами? Я покупал на eBay: http://www.ebay.com/itm/140717254516
Хорошая статья! Спасибо Илья! Как для меня, начинающего, ( Купил год назад Мегу 1280) хороший пример для изучения – как записать в файл данные с Ардуино и потом открыть в Екселе.. А не могли бы Вы показать, как можно прямо в Екселе считывать данные с Ардуины? Или хотя бы на компьютер записать (сохранить) этот файл?
Ответ для Юрий: Мне очень приятно, что статья оказалась полезной для Вас. 🙂
спасибо, оказалось полезно. Правда заработало только после добавления библиотеки #include
Ответ для Дмитрий: не за что!
Добрый день!
Интересует такой момент: как организовать поиск внутри файла на cd карте?
Добрый день! Конкретно сказать не могу, но надо считать файл в оперативную память (массив) и искать в нём перебором.
а как правильно закрывать показания? То есть, просто выдергивать карту из ридера и смотреть файл? Иногда бывает, что в это время как раз шла запись в файл и он оказывается битым…
По хорошему надо в программе предусмотреть возможность остановки, например, по нажатию кнопки. Выдёргивать просто так – точно не вариант. после myFile.close(); файл будет закрыт и можно извлечь, если конечно не начался новый цикл и файл не открыли для записи снова
Приходится каждую секунду открывать файл-записать-закрыть файл. нельзя ли в функции loop только писать данные,а открытие и закрытие вынести за пределы?
А сколько каналов (входов) одновременно можно регистрировать (записывать) на SD. И не затруднит ли вас скейч на несколько вхадов показать???
Для записи на карту нет понятия каналов. Вы записываете данные. Каждое значение датчика – это, по сути, переменная. Вы можете записывать неограниченное число переменных. В моем скетче вы можете видеть, как я записываю время (переменная time), затем ставлю символ точки с запятой и затем записываю данные температуры (переменная temp). Просто добавьте ещё переменных через разделитель (точка с запятой).
Почему не получена библиотека SPI?
Упустил. Спасибо за замечание! Я даже удивлён, что за столько времени с момента публикации статьи, никто не упомянул об этом 😀