Главная → Готовые проекты

Готовый проект: логгер температуры на SD-карту с часами DS3231

30 сентября 2026 · Готовые проекты

Постановка задачи

Частая задача: измерять температуру в теплице, гараже или серверном шкафу с записью на карту, чтобы потом строить графики. Вариант «считать в Serial Monitor и переписывать руками» не живёт дольше вечера. Правильное решение стоит около 500 рублей: DS18B20, модуль MicroSD-карты и часы реального времени DS3231. Ниже — вся конструкция: таблица характеристик по паспортам, распиновка, рабочий код и ошибки, на которых новички его губят.

Часы здесь обязательны. Если писать только температуру, после чтения лога получится ломаная без оси времени, а после перезагрузки millis() обнулится. DS3231 хранит точное время на батарейке годами: точность ±2 ppm при 0…+40 °C — примерно минута ошибки за год.

Железо и характеристики по паспортам

В проекте три модуля, все разобраны на сайте по отдельности, ниже — только цифры, которые влияют на сборку.

Параметр Значение
DS18B20 — диапазон измерений −55…+125 °C
DS18B20 — точность ±0,5 °C (−10…+85 °C)
DS18B20 — разрешение / время преобразования 12 бит, 0,0625 °C / до 750 мс
DS18B20 — питание 3,0–5,5 В, подтяжка DQ 4,7 кОм
DS3231 — точность хода ±2 ppm при 0…+40 °C (≈1 мин/год)
DS3231 — питание VCC 2,3–5,5 В; батарейка CR2032 тип. 3,0 В
DS3231 — ток от батарейки тип. 0,84 мкА (ход часов при отсутствии питания)
DS3231 — интерфейс I2C до 400 кГц, адрес 0x68
MicroSD-модуль — карты и файловая система microSD до 2 ГБ, microSDHC до 32 ГБ; FAT16/FAT32
MicroSD-модуль — питание и логика 4,5–5,5 В (буфер 74LVC125A, стабилизатор AMS1117-3.3)
MicroSD-модуль — ток от 0,2 мА в покое до 200 мА пик записи
Питание всей конструкции 5 В от блока питания или powerbank

Схема подключения

Плата — Arduino Uno. SD-модуль сидит на аппаратной SPI (MOSI D11, MISO D12, SCK D13, CS D4), DS3231 — на I2C (A4/A5), DS18B20 — на D2. С ESP32 схема та же по смыслу, различия ниже.

Модуль / вывод Arduino Uno ESP32
DS18B20 DQ (+ 4,7 кОм к питанию) D2 GPIO4
DS3231 SDA / SCL A4 / A5 GPIO21 / GPIO22
MicroSD CS D4 GPIO5
MicroSD MOSI / MISO / SCK D11 / D12 / D13 GPIO23 / GPIO19 / GPIO18
VCC SD-модуля 5V 5V (VIN) или 3V3-версия
VCC DS3231 5 В 3,3 В
VCC DS18B20 5 В 3,3 В

У SD-модуля с буфером 74LVC125A на вход подаётся 5 В. Для ESP32 берут версию модуля без буфера или питают VCC от 3V3. Часы и датчик у ESP32 питаются от 3,3 В. У Uno всё питается от 5 В.

Код: логгер с расписанием

Библиотеки: SD (штатная), OneWire и DallasTemperature (Paul Stoffregen), RTClib (Adafruit). Код одинаков для Uno и ESP32, меняются только номера пинов.

#include <SPI.h>
#include <SD.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <RTClib.h>

const int PIN_DQ  = 2;   // DS18B20 (ESP32: 4)
const int PIN_CS  = 4;   // SD (ESP32: 5)
// Uno: SPI на D11/D12/D13; ESP32: GPIO23/19/18

OneWire oneWire(PIN_DQ);
DallasTemperature sensors(&oneWire);
RTC_DS3231 rtc;

const unsigned long PERIOD = 60000UL;  // период записи, 60 с
unsigned long lastWrite = 0;

void setup() {
  Serial.begin(9600);                  // ESP32: 115200
  sensors.begin();
  sensors.setResolution(12);           // 0,0625 °C, до 750 мс
  if (!SD.begin(PIN_CS)) {             // карта не вставлена или CS не тот
    Serial.println("SD error");
    while (true) delay(1000);
  }
  if (!rtc.begin()) {                  // DS3231 не отвечает
    Serial.println("RTC error");
    while (true) delay(1000);
  }
  if (rtc.lostPower()) {
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
  File f = SD.open("LOG001.CSV", FILE_WRITE);
  if (f) {
    f.println("date;time;tempC");
    f.close();
  }
}

void loop() {
  if (millis() - lastWrite < PERIOD) return;
  lastWrite = millis();
  sensors.requestTemperatures();
  float t = sensors.getTempCByIndex(0);          // первый датчик на шине
  DateTime now = rtc.now();                      // дата и время одним вызовом
  char line[32];
  snprintf(line, sizeof(line), "%04u-%02u-%02u;%02u:%02u:%02u;%.2f",
           now.year(), now.month(), now.day(),
           now.hour(), now.minute(), now.second(), t);
  File f = SD.open("LOG001.CSV", FILE_WRITE);    // дозапись в конец
  if (!f) {
    Serial.println("open failed");
    return;
  }
  f.println(line);
  f.close();
  Serial.println(line);
}

Пары «считать-записать» у Arduino долгие: SD-запись до 200 мА, преобразование DS18B20 до 750 мс. В ESP32 то же делается через deep sleep: проснулся, прочитал, записал, уснул — средний ток падает до десятков микроампер, от powerbank логгер живёт неделями.

Частые ошибки

  1. Подают на SD-модуль 3,3 В от Uno. Стабилизатор AMS1117-3.3 требует входа выше выхода примерно на 1,1 В; с 3,3 В на входе карта получает меньше 3,3 В и не инициализируется. На Uno модуль кормят 5 В, на ESP32 — либо 3V3-версия, либо 5 В на VIN.
  2. Пишут с SD.begin() без проверки. Если карта не вставлена, CS в скетче не тот или карта больше 32 ГБ (exFAT), SD.begin() вернёт false, а код продолжит писать в никуда. Всегда проверяй возврат и выводи ошибку в Serial.
  3. Вешают на шину I2C DS3231 и другие модули без учёта адресов. DS3231 сидит на 0x68, EEPROM AT24C32 на плате — на 0x57, OLED SSD1306 — 0x3C: OLED-дисплей к этому логгеру подключается на ту же шину без конфликтов.
  4. Забывают rtc.adjust() при первом запуске. Без батарейки или после первого включения lostPower() вернёт true, и в лог пойдут 2000-01-01 00:00:00. Проверяй lostPower() в setup() и выставляй время сборки скетча.
  5. Имя файла 8.3 или слишком длинное. SD-библиотека понимает короткие имена, LOG001.CSV — безопасно; длинные имена на некоторых картах не открываются.
  6. Не закрывают файл. Файл закрывается f.close() после каждой строки, иначе данные из буфера не попадут на карту при сбое питания. Не используй журнал долгоживущим: открыл — записал — закрыл.
  7. Ждут от батарейки CR2032 питания логгера. Она держит только часы: 0,84 мкА на ход. Температуру и запись карты кормит основной источник 5 В.

Что дальше

Базовый вариант готов за вечер. Развитие: второй DS18B20 на ту же шину 1-Wire, запись через deep sleep для батарейного режима, выгрузка лога по Bluetooth HC-05. Для улицы берите водонепроницаемую версию DS18B20 — она разобрана в обзоре DS18B20.

Информация собрана из открытых источников и паспортов производителей и не является истиной в последней инстанции. Характеристики, распиновку и совместимость проверяйте по документации конкретной партии модуля перед покупкой и подключением.

Читайте дальше

Питание

Модуль TP4056: зарядка литиевого аккумулятора в проекте на Arduino

Как только устройство перестаёт висеть на USB и переезжает на аккумулятор, появляется вопрос зарядки. Ответ почти всегда один и тот же —…

Читать обзор →
Датчики

Ёмкостный датчик влажности почвы v1.2: почему резистивный датчик сгнивает за месяц

Если у вас когда-то сгнил резистивный датчик влажности почвы — вы не одиноки. Разберёмся, почему это происходит, чем лучше ёмкостный датчик v1.2…

Читать обзор →
Связь

LoRa-модуль Ra-02 (SX1278): связь на километры без интернета — обзор и подключение

Что это за модуль Wi-Fi и Bluetooth работают на десятки метров, сотовой связи в поле нет, а передать показания датчика с дачи…

Читать обзор →