Микроконтроллеры и электроника

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

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

Необходимые компоненты

Собираем схему

Описывать схему сборки измерителя температуры я не буду, если Вы забыли или не знаете как его собирать – обратитесь к посту, ссылка на который указана в предыдущем разделе этого поста. (Картинка) Рассмотрим схему подключения SD модуля. Каждый модуль имеет следующие контакты: GND, 5V, 3V (3.3V), CS, MOSI, SCLK (SCK), MISO, GND. Подключим некоторые из этих контактов к следующим контактам Arduino:

  • GND – к земле с Arduino
  • 5V разъём к 5 вольтовому разъёму Arduino. (Аналогично 3.3V) Подключать оба разъёма одновременно – бессмысленно, я подключаю только 5V.
  • CS – к 4 разъёму (все разъёмы SD модуля подключаются ТОЛЬКО к цифровым выходам – никаких аналоговых здесь быть не должно!)
  • MOSI – к 11 разъёму
  • SCLK (SCK) – к 13 разъёму
  • MISO – к 12 разъёму
  • Ещё один GND – никуда не подключаем

На этом наше подключение окончено. Для подключения можете использовать макетную плату – просто втыкаете туда 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. Теперь вы можете построить график или рассчитать среднее значение температуры в вашей комнате за какой-то промежуток времени.

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

  • Сергей

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

  • Юрий

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

    • Ответ для Юрий: Мне очень приятно, что статья оказалась полезной для Вас. 🙂

  • Дмитрий

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

  • Илья

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

    • Добрый день! Конкретно сказать не могу, но надо считать файл в оперативную память (массив) и искать в нём перебором.

  • Евгений

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

    • По хорошему надо в программе предусмотреть возможность остановки, например, по нажатию кнопки. Выдёргивать просто так — точно не вариант. после myFile.close(); файл будет закрыт и можно извлечь, если конечно не начался новый цикл и файл не открыли для записи снова

  • Линар

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

  • Виктор

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

    • Для записи на карту нет понятия каналов. Вы записываете данные. Каждое значение датчика — это, по сути, переменная. Вы можете записывать неограниченное число переменных. В моем скетче вы можете видеть, как я записываю время (переменная time), затем ставлю символ точки с запятой и затем записываю данные температуры (переменная temp). Просто добавьте ещё переменных через разделитель (точка с запятой).

  • Sts

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

    • Упустил. Спасибо за замечание! Я даже удивлён, что за столько времени с момента публикации статьи, никто не упомянул об этом 😀