Библиотека RTClib
Часы реального времени DS3231 и DS1307: точное время после выключения, будильники, дата и день недели.
Модуль часов с батарейкой хранит время, пока плата обесточена. RTClib читает его по I2C и отдаёт объект DateTime, у которого есть год, месяц, час и всё остальное, плюс арифметика: к дате можно прибавить интервал TimeSpan. Поддерживаются DS3231 (точные, с термокомпенсацией) и DS1307 (старые, дешёвые).
Выставляют часы один раз: adjust() с временем компиляции скетча. Потом эту строку убирают, иначе при каждом включении часы откатятся к моменту прошивки.
Установка и подключение
В менеджере библиотек ищите RTClib автора Adafruit. Если менеджер предложит поставить зависимости — соглашайтесь. Как открыть менеджер и что делать, если библиотека не находится, — в общей статье про библиотеки.
#include <RTClib.h>Создание объекта — обычно до setup():
RTC_DS3231 rtc; // или RTC_DS1307
rtc.begin(); // в setup()
if (rtc.lostPower()) rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));Методы
Только то, что нужно в обычном скетче. Сигнатуры сверены с версией 2.1.4.
begin()- Найти модуль на I2C. false — не найден.
now()- Текущее время как DateTime.
adjust(DateTime dt)- Установить время. DateTime(F(__DATE__), F(__TIME__)) — момент компиляции.
lostPower()- DS3231: true, если часы теряли питание и время недостоверно.
getTemperature()- DS3231: температура чипа, °C — есть бесплатно.
DateTime(y, m, d, hh, mm, ss)- Собрать дату вручную.
dt.year(), month(), day(), hour(), minute(), second()- Компоненты даты.
dt.dayOfTheWeek()- 0 — воскресенье, 6 — суббота.
dt.unixtime()- Секунды с 1970 года — удобно для сравнения и разностей.
dt + TimeSpan(days, hours, minutes, seconds)- Прибавить интервал; разность двух DateTime даёт TimeSpan.
dt.timestamp()- Строка вида 2026-09-07T12:30:00.
setAlarm1(DateTime dt, Ds3231Alarm1Mode mode)- DS3231: будильник; срабатывает на выводе SQW и проверяется alarmFired(1).
Пример
#include <Wire.h>
#include <RTClib.h>
RTC_DS3231 rtc;
const char* days[] = {"вс", "пн", "вт", "ср", "чт", "пт", "сб"};
void setup() {
Serial.begin(9600);
if (!rtc.begin()) { Serial.println("Часы не найдены"); while (1); }
if (rtc.lostPower()) {
// батарейка садилась: ставим время компиляции скетча
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
}
void loop() {
DateTime t = rtc.now();
char buf[32];
snprintf(buf, sizeof(buf), "%02d.%02d.%04d %02d:%02d:%02d %s",
t.day(), t.month(), t.year(), t.hour(), t.minute(), t.second(),
days[t.dayOfTheWeek()]);
Serial.println(buf);
delay(1000);
}Проверка lostPower() — правильный способ ставить время: часы выставятся только тогда, когда действительно сбились.
На чём попадаются
Время каждый раз одно и то же
adjust() вызывается при каждом включении без условия. Уберите его или оберните в lostPower().
Отстают на несколько часов
__TIME__ — время компиляции на компьютере, плюс несколько секунд на заливку. Часовой пояс библиотека не знает: храните локальное и не удивляйтесь.
begin() не находит модуль
Адрес DS3231 — 0x68, тот же, что у MPU6050: два на одной шине не уживутся без смены адреса гироскопа. И проверьте сканером Wire.
Батарейка садится за месяц
На дешёвых модулях стоит цепь зарядки для аккумулятора LIR2032, а вставлена обычная CR2032. Либо LIR, либо выпаять зарядный резистор.