ELECTRONICS

DS3231 и Arduino: подключение модуля часов по I2C, установка времени, библиотека RTClib

Часы реального времениСкетч проверен компиляцией

DS3231 — модуль часов, который не уходит: генератор с термокомпенсацией внутри микросхемы держит точность в две минуты в год. Подключается четырьмя проводами по I2C и работает от батарейки, пока плата выключена.

На плате ZS-042 рядом стоит микросхема памяти AT24C32 на 4 килобайта — по той же шине, под другим адресом. В ней можно хранить настройки или лог, но обычно она просто есть.

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

HW-08432KSQWSCLSDAVCCGNDPOWER102741741DS3231SN2024A4917AD201SCLSDAVCCGNDA0A1A2
Наведите на провод или нажмите на него — расскажу, зачем он нужен.

Распиновка

ПроводКуда и зачем
SCLТакт I2C, A5 на UNO.
SDAДанные I2C, A4 на UNO.
VCC3,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 из коробки часто разряжен — ему нужно несколько часов под питанием.

Что понадобится