DS3231 и Arduino: подключение модуля часов по I2C, установка времени, библиотека RTClib
DS3231 — модуль часов, который не уходит: генератор с термокомпенсацией внутри микросхемы держит точность в две минуты в год. Подключается четырьмя проводами по I2C и работает от батарейки, пока плата выключена.
На плате ZS-042 рядом стоит микросхема памяти AT24C32 на 4 килобайта — по той же шине, под другим адресом. В ней можно хранить настройки или лог, но обычно она просто есть.
Схема подключения
Распиновка
| Провод | Куда и зачем |
|---|---|
| SCL | Такт I2C, A5 на UNO. |
| SDA | Данные I2C, A4 на UNO. |
| VCC | 3,3–5 В. |
| GND | Земля. |
| SQW | Программируемый выход: меандр 1 Гц или сигнал будильника. Для будильника соединяют с выводом прерывания. |
| 32K | Выход 32 768 Гц с кварца. В проектах почти не нужен. |
Характеристики
- Точность
- ±2 ppm, около 1 минуты в год
- Интерфейс
- I2C, адрес 0x68
- Память на плате
- AT24C32, 4 КБ, адрес 0x57
- Будильники
- два
- Датчик температуры
- встроенный, ±3 °C
- Батарейка
- LIR2032 (аккумулятор) или CR2032
- Питание
- 2,3–5,5 В
Батарейка и цепь подзарядки
На ZS-042 стоит цепь подзарядки для аккумулятора LIR2032: резистор и диод от VCC к батарейке. Если поставить обычную CR2032, цепь будет её заряжать — батарейка греется и со временем вздувается. Варианта два: ставить именно LIR2032, либо выпаять резистор подзарядки, он рядом с диодом, и тогда подойдёт любая CR2032.
При питании 3,3 В аккумулятор не заряжается полностью, но и не разряжается: модуль берёт ток от VCC, пока он есть.
Библиотека
RTClib (Adafruit)— Ставится из менеджера. Умеет DS3231, DS1307 и PCF8523 одним интерфейсом.
Готовый скетч
#include <Wire.h>
#include <RTClib.h>
RTC_DS3231 rtc;
const char* DAYS[] = {"вс", "пн", "вт", "ср", "чт", "пт", "сб"};
void setup() {
Serial.begin(9600);
if (!rtc.begin()) {
Serial.println("DS3231 не найден — проверьте SDA и SCL");
while (true) {}
}
if (rtc.lostPower()) {
// время слетело (батарейки не было) — ставим время компиляции скетча
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
}
void loop() {
DateTime now = rtc.now();
char line[32];
snprintf(line, sizeof(line), "%02d.%02d.%04d %s %02d:%02d:%02d",
now.day(), now.month(), now.year(), DAYS[now.dayOfTheWeek()],
now.hour(), now.minute(), now.second());
Serial.println(line);
Serial.print("Температура: ");
Serial.println(rtc.getTemperature());
delay(1000);
}Скетч собирается arduino-cli под Arduino UNO
Время выставляется один раз временем компиляции. Оно отстаёт на несколько секунд — столько идёт загрузка; для точности можно прибавить их вручную.
Частые ошибки
Каждый запуск время сбрасывается
Строка rtc.adjust стоит без условия lostPower — и при каждом включении ставит время компиляции. Оставьте её только под условием или закомментируйте после первой прошивки.
Время идёт, но врёт на часы
Часовой пояс. DS3231 хранит то, что вы записали; если записали UTC — читайте UTC и прибавляйте свои часы в коде.
Батарейка вздулась
Поставили CR2032 в модуль с цепью подзарядки. Либо LIR2032, либо выпаять резистор.
Не найден по I2C
Перепутаны SDA и SCL или модуль висит на другом адресе — прогоните сканер I2C с нашей страницы про интерфейсы. DS3231 всегда 0x68, память рядом — 0x57.
Время слетает при выключении
Батарейка села или не вставлена. Новый аккумулятор LIR2032 из коробки часто разряжен — ему нужно несколько часов под питанием.
Что понадобится
- Модуль DS3231 (ZS-042)
- Аккумулятор LIR2032
- Arduino UNO
- Провода «папа-мама»