Arduino: работаем с SD картами

SD-карта довольно распространённый тип носителя в наше время. Каждый разработчик рано или поздно сталкивается с необходимостью хранить большой объём данных и\или использовать для каких-либо долгосрочных целей энергонезависимый носитель информации. На рынке существует огромное множество модулей для подключения SD-карт к Arduino или любому другому микроконтроллеру.
Практическое использование одного из таких модулей с разбором кода и схемотехнике предлагаю рассмотреть вам в этой статье.

На днях мне пришёл заказанный модуль для работы с SD-картами. В этом посте я расскажу, как усовершенствовать, сделанный нами в прошлом, датчик для измерения температуры, а именно – мы избавим себя от надобности копирования данных из консоли вывода в Excel для дальнейшего анализа, заставив Arduino сохранять данные на SD-карту в виде csv-файла.  Данные будут записываться в файл в два столбца – в первом будут единицы времени (или просто номер строки), а во втором значение напряжения на термисторе или ином датчике, которое, как Вы помните, пропорционально температуре.

Описывать схему сборки измерителя температуры я не буду, если Вы забыли или не знаете как его собирать – обратитесь к посту, ссылка на который указана выше.

 

Схема подключения модуля SD-карт к Arduino

Рассмотрим схему подключения 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 картами, отформатированными под файловую систему FAT16 или FAT32. Карту необходимо заранее отформатировать на компьютере. БУДЬТЕ ВНИМАТЕЛЬНЫ! При форматировании все данные, находящиеся на носителе, будут уничтожены! Не забудьте переписать их в другое место перед форматированием!

// Подключаем библиотеку для работы с шиной 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 раз. 

На этом всё, задавайте свои вопросы мне в комментариях к этому посту, до скорых встреч!

15 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Сергей
11 лет назад

Подскажите пожалуйста интернет магазин где можно купить плату расширения на SD.
Сам контроллер нашел. А вот платку никак не могу найти, ну или как она точно называется…

Юрий
11 лет назад

Хорошая статья! Спасибо Илья! Как для меня, начинающего, ( Купил год назад Мегу 1280) хороший пример для изучения – как записать в файл данные с Ардуино и потом открыть в Екселе.. А не могли бы Вы показать, как можно прямо в Екселе считывать данные с Ардуины? Или хотя бы на компьютер записать (сохранить) этот файл?

Дмитрий
10 лет назад

спасибо, оказалось полезно. Правда заработало только после добавления библиотеки #include

Илья
7 лет назад

Добрый день!
Интересует такой момент: как организовать поиск внутри файла на cd карте?

Евгений
7 лет назад

а как правильно закрывать показания? То есть, просто выдергивать карту из ридера и смотреть файл? Иногда бывает, что в это время как раз шла запись в файл и он оказывается битым…

Линар
7 лет назад

Приходится каждую секунду открывать файл-записать-закрыть файл. нельзя ли в функции loop только писать данные,а открытие и закрытие вынести за пределы?

Виктор
7 лет назад

А сколько каналов (входов) одновременно можно регистрировать (записывать) на SD. И не затруднит ли вас скейч на несколько вхадов показать???

Sts
6 лет назад

Почему не получена библиотека SPI?