
Видео
Схема

Исходный код
1// ─────────────────────────────────────────
2// BlueGrays · bluegrays.com
3// Настройка модуля часов DS1302 RTC
4// ─────────────────────────────────────────
5// Если время в RTC недействительно (новый модуль, села батарейка), один
6// раз записывает в DS1302 дату и время компиляции, затем каждую секунду
7// выводит дату и время в монитор порта. Батарейка модуля хранит время при
8// выключенном питании; при следующих запусках время заново не ставится.
9//
10// Пины:
11// D6 -> RTC CLK
12// D7 -> RTC DAT
13// D8 -> RTC RST
14// VCC RTC к 5V, GND к GND
15
16#include <virtuabotixRTC.h> // Библиотека DS1302
17
18// Пины: CLK, DAT, RST
19virtuabotixRTC myRTC(6, 7, 8);
20
21void setup() {
22 Serial.begin(9600); // Serial на скорости 9600 бод
23
24 // Сначала прочитать RTC. Год меньше 2024 или месяц вне 1-12 означает, что время ещё не задано;
25 // записать время компиляции. Если время верное, не трогать его, тогда повторная загрузка или
26 // перезапуск питания Arduino сохраняет время.
27 myRTC.updateTime();
28 if (myRTC.year < 2024 || myRTC.month < 1 || myRTC.month > 12) {
29 setFromCompileTime();
30 }
31}
32
33// Записывает в RTC время компиляции (__DATE__ "Oct 28 2026", __TIME__ "13:42:15"). Загрузка
34// занимает несколько секунд, поэтому часы стартуют с таким отставанием.
35void setFromCompileTime() {
36 const char *date = __DATE__;
37 const char *time = __TIME__;
38 const char *months = "JanFebMarAprMayJunJulAugSepOctNovDec";
39 char monthName[4] = {date[0], date[1], date[2], '\0'};
40
41 int month = (strstr(months, monthName) - months) / 3 + 1; // "Oct" -> 10
42 int day = atoi(date + 4);
43 int year = atoi(date + 7);
44 int hour = atoi(time);
45 int minute = atoi(time + 3);
46 int second = atoi(time + 6);
47
48 // День недели (метод Сакамото), 0 = воскресенье
49 int offsets[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
50 int y = year - (month < 3);
51 int weekday = (y + y / 4 - y / 100 + y / 400 + offsets[month - 1] + day) % 7;
52 if (weekday == 0) {
53 weekday = 7; // Понедельник = 1 ... воскресенье = 7
54 }
55
56 // Порядок: с, мин, ч, день недели, день, месяц, год
57 myRTC.setDS1302Time(second, minute, hour, weekday, day, month, year);
58}
59
60void loop() {
61 // Прочитать текущее время из модуля RTC
62 myRTC.updateTime();
63
64 // Вывести время (день/месяц/год ч:м:с)
65 Serial.print("Current Date/Time: ");
66 Serial.print(myRTC.dayofmonth);
67 Serial.print("/");
68 Serial.print(myRTC.month);
69 Serial.print("/");
70 Serial.print(myRTC.year);
71 Serial.print(" ");
72 Serial.print(myRTC.hours);
73 Serial.print(":");
74 Serial.print(myRTC.minutes);
75 Serial.print(":");
76 Serial.println(myRTC.seconds);
77
78 delay(1000); // Ждать 1 с
79}
80
Частые вопросы
Что делает модуль RTC?
Модуль часов реального времени (RTC) хранит время и дату даже при выключенной Arduino благодаря встроенной батарейке. Счётчик millis() у Arduino обнуляется при каждом включении, поэтому для точного времени нужен RTC.
Достаточно ли установить время один раз?
Да. Код сначала читает время из модуля; если оно ни разу не устанавливалось, записывает дату и время, когда код был скомпилирован. Если время корректное, код его не трогает, поэтому повторная загрузка или выключение и включение Arduino часы не сбивают. Комментировать какую-либо строку вручную не нужно.
Часы отстают. Это нормально?
DS1302 работает на кварце и может уходить на несколько секунд в сутки. Для более точных часов рекомендуется модуль DS3231 с температурной компенсацией (около ±1 минуты в год).
Что будет, когда сядет батарейка в модуле?
Часы идут, пока Arduino получает питание; если питание пропало, а батарейка разряжена, часы сбрасываются, и их нужно установить заново. Батарейки CR2032 обычно хватает на несколько лет.
