Arduino и SD-карта: логируем данные датчиков на microSD

Пошаговое руководство по созданию автономного логгера данных на Arduino. Узнайте, как подключить SD-модуль, записывать показания датчиков в файл и избегать типичных ошибок. Практический DIY проект для умного дома.
Приветствую всех любителей электроники и домашней автоматизации! Сегодня мы разберём одну из фундаментальных, но очень полезных задач: как заставить Arduino записывать показания датчиков на карту памяти microSD. Зачем это нужно? Представьте, вы собрали метеостанцию, датчик протечки воды или систему мониторинга качества воздуха. Данные снимаются, но Arduino не подключена к интернету постоянно, или вам нужна долговременная, независимая запись для последующего анализа. Вот тут-то на помощь и приходит связка Arduino + SD-модуль — ваш личный, автономный регистратор данных (data logger).
В этой статье мы не просто подключим модуль, а создадим полноценный логгер для датчика температуры и влажности DHT22. Мы разберём выбор компонентов, тонкости подключения, напишем надёжный скетч, а также обсудим типичные ошибки, которые могут свести на нет все усилия. Поехали!
Что нам понадобится?
Для повторения проекта приготовьте следующие компоненты:
- Arduino Uno / Nano / Mega (в примере используем Uno).
- Модуль карты памяти microSD (обычно на чипе
SPI). - Карта памяти microSD (рекомендую от 2 до 16 Гб, отформатированная в
FAT16илиFAT32). - Датчик DHT22 (или более дешёвый DHT11).
- Макетная плата и провода «папа-папа».
- USB-кабель для подключения к компьютеру.
Подключаем компоненты
Давайте соберём схему. Главное правило — не путать выводы питания. Модуль SD-карты и датчик DHT22 работают от 5В.
Схема подключения
Модуль microSD (SPI) к Arduino Uno: * VCC -> 5V на Arduino * GND -> GND на Arduino * CS (Chip Select) -> пин 10 (можно выбрать другой, но в коде нужно будет изменить) * MOSI -> пин 11 * MISO -> пин 12 * SCK -> пин 13
Датчик DHT22 к Arduino Uno: * VCC (1-й пин) -> 5V на Arduino * DATA (2-й пин) -> цифровой пин 2 (через подтягивающий резистор 4.7-10 кОм к VCC) * GND (4-й пин) -> GND на Arduino (3-й пин не используется).
Важный момент: Если вы используете Arduino Mega, SPI-пины другие: MOSI - 51, MISO - 50, SCK - 52. Пин CS можно выбрать любым (например, 53).
Подготовка среды и библиотек
Прежде чем писать код, установим необходимые библиотеки через Менеджер библиотек в Arduino IDE: 1. SD — стандартная библиотека для работы с картой (обычно уже установлена). 2. DHT sensor library by Adafruit — для работы с датчиками DHT. 3. Adafruit Unified Sensor — зависимость для библиотеки DHT.
Идём в Скетч → Подключить библиотеку → Управлять библиотеками.... В поиске вводим «DHT sensor», находим библиотеку от Adafruit и устанавливаем. Система автоматически предложит установить и зависимую библиотеку «Adafruit Unified Sensor».
Пишем скетч для логирования
Теперь создадим скетч, который будет каждые 5 секунд считывать данные с датчика и записывать их в файл datalog.txt на карте. Каждая запись будет содержать метку времени (в миллисекундах с момента старта), температуру и влажность.
// Подключаем необходимые библиотеки
#include <SPI.h>
#include <SD.h>
#include <DHT.h>
// Определяем константы
#define DHTPIN 2 // Пин, к которому подключен DHT
#define DHTTYPE DHT22 // Тип датчика (DHT22 или DHT11)
#define CHIP_SELECT_PIN 10 // Пин CS для SD-модуля
// Создаём объект для работы с датчиком
DHT dht(DHTPIN, DHTTYPE);
// Объект для работы с файлом на SD-карте
File dataFile;
void setup() {
// Инициализируем последовательный порт для отладки
Serial.begin(9600);
while (!Serial) {
; // Ждём, пока откроется последовательный порт (нужно для Leonardo)
}
Serial.println("Инициализация DHT22...");
dht.begin();
Serial.println("Инициализация SD-карты...");
// Проверяем наличие и доступность SD-карты
if (!SD.begin(CHIP_SELECT_PIN)) {
Serial.println("Ошибка инициализации SD-карты!");
// Загораем встроенный светодиод при ошибке
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
while (1); // Останавливаем выполнение скетча
}
Serial.println("SD-карта инициализирована.");
// Пробуем открыть файл для записи (файл будет создан, если его нет)
dataFile = SD.open("datalog.txt", FILE_WRITE);
// Если файл успешно открыт, записываем в него заголовок
if (dataFile) {
Serial.println("Файл datalog.txt открыт для записи.");
dataFile.println("Время(мс), Температура(C), Влажность(%)"); // Заголовок CSV
dataFile.close(); // Закрываем файл после записи заголовка
Serial.println("Заголовок записан.");
} else {
// Если файл не открылся, выводим ошибку
Serial.println("Ошибка открытия файла datalog.txt!");
}
}
void loop() {
// Ждём 5 секунд между измерениями
delay(5000);
// Считываем данные с датчика
float humidity = dht.readHumidity();
float temperature = dht.readTemperature(); // Чтение температуры в Цельсиях
// Проверяем, удалось ли считать данные (isnan - "is not a number")
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Ошибка чтения с датчика DHT!");
return; // Пропускаем эту итерацию цикла
}
// Выводим данные в Serial-монитор для отладки
Serial.print("Температура: ");
Serial.print(temperature);
Serial.print(" C, Влажность: ");
Serial.print(humidity);
Serial.println(" %");
// --- ЗАПИСЬ НА SD-КАРТУ ---
// Открываем файл в режиме добавления (данные не стираются)
dataFile = SD.open("datalog.txt", FILE_WRITE);
if (dataFile) {
// Записываем строку в формате CSV: время, температура, влажность
dataFile.print(millis()); // Метка времени
dataFile.print(",");
dataFile.print(temperature);
dataFile.print(",");
dataFile.println(humidity);
dataFile.close(); // ВАЖНО: Закрываем файл после записи!
Serial.println("Данные записаны на карту.");
} else {
Serial.println("Ошибка открытия файла для записи!");
}
}
Разбор ключевых моментов кода
SD.begin(CHIP_SELECT_PIN)— инициализация SD-карты. Указываем номер пина CS. Если карта не найдена, программа останавливается.SD.open("datalog.txt", FILE_WRITE)— открытие файла.FILE_WRITEозначает режим записи с добавлением в конец файла.dataFile.close()— КРИТИЧЕСКИ ВАЖНЫЙ МОМЕНТ. После каждой операции записи файл обязательно нужно закрывать. Если этого не делать, данные могут не сохраниться на карту, а остаться в буфере, и вы потеряете их при отключении питания.millis()— используется как простая метка времени. Для реальных часов потребуется модульRTC(Real Time Clock), например, DS3231.- Проверка
isnan()— защита от «мусора» с датчика. Всегда обрабатывайте возможные ошибки чтения.
Типичные ошибки и их решение
-
«Ошибка инициализации SD-карты!»
- Проверьте форматирование. Отформатируйте карту в
FAT16илиFAT32(для карт до 32 Гб). Не используйте exFAT или NTFS. - Проверьте соединения. 95% проблем — в плохом контакте. Особенно часто «отходит» провод CS (Chip Select).
- Попробуйте другой пин CS. Иногда помогает смена пина CS с 10-го на 4-й (для некоторых клонов модулей).
- Проверьте карту и модуль. Вставьте карту в компьютер, попробуйте другой модуль или другую карту (желательно не самого высокого класса скорости).
- Проверьте форматирование. Отформатируйте карту в
-
Данные в файле отображаются «кракозябрами» или запись происходит один раз.
- Не забывайте
dataFile.close(). Это самая распространённая ошибка. - Открывайте и закрывайте файл в каждом цикле
loop(), как показано в примере. Долгое удержание файла открытым может привести к ошибкам.
- Не забывайте
-
Датчик DHT22 показывает
NaN(Not a Number).- Проверьте схему подключения датчика и наличие подтягивающего резистора (4.7-10 кОм) между пином DATA и VCC.
- Дайте датчику время на инициализацию. Не опрашивайте его чаще, чем раз в 2 секунды для DHT22.
Проверка результата
После загрузки скетча откройте Serial Monitor (Ctrl+Shift+M). Вы должны увидеть процесс инициализации и затем регулярный вывод показаний с пометкой «Данные записаны на карту».
Чтобы убедиться, что данные действительно записались:
- Безопасно отключите питание Arduino.
- Достаньте microSD-карту из модуля.
- Вставьте её в компьютер через кард-ридер.
- Найдите файл
datalog.txtв корне карты и откройте его любым текстовым редактором или, что лучше, программой для работы с таблицами (Excel, LibreOffice Calc).
Вы увидите данные в удобном CSV-формате, которые легко импортировать для построения графиков и анализа.
Время(мс), Температура(C), Влажность(%)
5000, 23.50, 45.80
10000, 23.60, 45.70
15000, 23.55, 45.75
Куда двигаться дальше?
Наш простой логгер готов! Но это только начало. Экспериментируйте:
- Добавьте модуль реального времени (RTC), чтобы записывать не миллисекунды, а точную дату и время.
- Настройте автоматическое создание нового файла каждый день (например,
2024-05-20_log.txt). - Реализуйте управление через кнопку — начало и остановку записи.
- Добавьте светодиодную индикацию статуса записи.
Если ваш логгер — часть более крупной системы умного дома, собранные данные можно отправлять, например, в Home Assistant для визуализации и создания сложных автоматизаций. В этом вам помогут другие мои статьи:
- Node-RED + Home Assistant: Визуальная автоматизация умного дома без единой строчки кода — чтобы красиво обработать и визуализировать собранные данные.
- ESP32 Deep Sleep: как сделать датчик на батарейках, работающий месяцами — если вы захотите создать полностью автономный, энергоэффективный логгер на базе ESP32.
- Home Assistant Energy: превращаем данные в экономию и контроль — логирование данных с датчиков может стать первым шагом к анализу энергопотребления в вашем доме.
Надеюсь, этот материал был полезен. Удачи в экспериментах, и помните: самый ценный опыт — это опыт, полученный на практике, даже через ошибки. Делитесь вашими успехами и находками в комментариях!
Понравилась статья?
Поставьте лайк и сохраните полезный материал в закладки.
Сборник полезных скетчей для Arduino: 7 прошивок, которые реально пригодятся
Arduino для начинающих: первый скетч и основы программирования
Arduino и OLED дисплей SSD1306: выводим данные красиво
Arduino и сервоприводы: от мигания светодиода до роборуки
Пишем скетчи своими руками для Arduino — с нуля
Arduino таймер полива: автоматический полив огорода своими руками