Логер температури на microSD: DHT22, DS3231 і CSV-файл
ESP32 раз на 5 секунд записує час, температуру й вологість у CSV на карту пам'яті — без Wi-Fi і хмар. Модуль microSD по SPI, бібліотека SD, чому шляхи починаються зі «/», навіщо close() і як відкрити дані в Excel.
Про проєкт
Не всі дані треба відправляти в інтернет. Датчик у теплиці, погребі чи дорогою в машині може просто записувати вимірювання на microSD-картку. 8 ГБ вистачить на десятиліття CSV-рядків. Картку потім вставляєте в комп'ютер і відкриваєте в Excel або Google Таблицях. Збираємо логер: DHT22 міряє, DS3231 дає точний час, а кожні 5 секунд у /log.csv додається рядок.
Що знадобиться
- ESP32 DevKit
- Модуль microSD (SPI) + картка до 32 ГБ, відформатована у FAT32
- Датчик DHT22
- Годинник DS3231 з батарейкою
- Бібліотеки: SD (входить в arduino-esp32), RTClib, DHT sensor library
Схема
microSD-модуль (апаратний SPI, VSPI):
| Модуль | ESP32 |
|---|---|
| VCC | 5V (синій модуль зі стабілізатором) |
| GND | GND |
| MISO | GPIO19 |
| MOSI | GPIO23 |
| SCK | GPIO18 |
| CS | GPIO5 |
DS3231: SDA → GPIO21, SCL → GPIO22, VCC → 3V3, GND → GND. DHT22: DATA → GPIO27, VCC → 3V3.
Найпоширеніший синій модуль має стабілізатор AMS1117 і перетворювач рівнів. Від 3.3 В він не працює, живіть його від 5V. Бувають і модулі без стабілізатора: ті, навпаки, живлять лише від 3.3 В.
Правила бібліотеки SD на ESP32
- Шлях завжди починається зі «/»:
"/log.csv". Просто"log.csv"на ESP32 не відкриється. - Режими:
FILE_READ(за замовчуванням),FILE_WRITE— перезаписує файл з нуля,FILE_APPEND— дописує в кінець. Для логера потрібен саме APPEND. if (f)перевіряє, чи файл відкрився. Картку могли вийняти, файлу може не бути.close()обов'язковий. Картка пише секторами по 512 байт, і поки файл не закрито (або не викликаноflush()), дані лежать у буфері. Вимкнули живлення — дані втрачено.- Відкривати й закривати файл на кожен запис — нормально для логера раз на кілька секунд. Для сотень записів на секунду тримайте файл відкритим і робіть
flush()раз на 1–2 секунди.
Код
// Логер на microSD: DHT22 + годинник DS3231 → /log.csv кожні 5 с
#include <SD.h>
#include <RTClib.h>
#include <DHT.h>
const int SD_CS = 5;
const unsigned long PERIOD_MS = 5000;
RTC_DS3231 rtc;
DHT dht(27, DHT22);
unsigned long lastLog = 0;
// шапку CSV пишемо лише в новий (або щойно видалений) файл
void ensureHeader() {
if (SD.exists("/log.csv")) return;
File f = SD.open("/log.csv", FILE_WRITE);
f.println("time,temperature,humidity");
f.close();
}
void logLine() {
float t = dht.readTemperature();
float h = dht.readHumidity();
if (isnan(t) || isnan(h)) return;
DateTime now = rtc.now();
char line[48];
snprintf(line, sizeof line, "%04d-%02d-%02d %02d:%02d:%02d,%.1f,%.0f",
now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second(), t, h);
ensureHeader();
File f = SD.open("/log.csv", FILE_APPEND);
if (!f) {
Serial.println("Не вдалося відкрити /log.csv");
return;
}
f.println(line);
f.close(); // лише close() (або flush()) справді записує дані на картку
Serial.println(line);
}
void setup() {
Serial.begin(115200);
dht.begin();
if (!rtc.begin()) Serial.println("DS3231 не знайдено");
else if (rtc.lostPower()) rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
if (!SD.begin(SD_CS)) {
Serial.println("Картка не монтується: перевірте живлення й підключення");
while (true) delay(1000);
}
ensureHeader();
Serial.println("Запис у /log.csv. Команди: dump — показати файл, clear — видалити");
}
void loop() {
if (millis() - lastLog >= PERIOD_MS) {
lastLog = millis();
logLine();
}
if (Serial.available()) {
String cmd = Serial.readStringUntil('\n');
cmd.trim();
if (cmd == "dump") {
File f = SD.open("/log.csv");
while (f.available()) Serial.write(f.read());
f.close();
} else if (cmd == "clear") {
SD.remove("/log.csv");
Serial.println("Файл видалено");
}
}
}
Як відкрити в Excel
Файл виглядає так:
time,temperature,humidity
2026-09-30 14:05:00,22.4,55
2026-09-30 14:05:05,22.5,55
Excel з українською локаллю чекає крапку з комою як роздільник і кому в дробових числах. Скористайтеся «Дані → З тексту/CSV» і вкажіть роздільник «кома». У Google Таблицях файл відкривається як є.
Корисно знати
- Картка не монтується. Спершу живлення модуля, потім формат: FAT32 (картки на 64 ГБ і більше виходять з exFAT, їх треба переформатувати). Дроти SPI — якомога коротші.
- Струм під час запису стрибає до 80–100 мА. На слабкому живленні запис може перезавантажити ESP32.
- Ресурс. Кожен сектор витримує тисячі–десятки тисяч перезаписів. Рядок раз на 5 секунд — це роки роботи.
- Симулятор зберігає файли картки разом із проєктом (до 256 КБ), тож після перезапуску скетча дані залишаються, як на справжній картці.