ПроектОпубликовано 12 марта 2025 · обновлено 9 октября 2026

Часы на Arduino с модулем DS3231 и индикатором TM1637

DS3231 сам считает время с точностью до минуты в год, Arduino лишь выводит его на индикатор. Плюс три кнопки для установки и двоеточие, мигающее от секундного сигнала модуля.

Уровень
Есть опыт
Понадобится
Паяльник
Время сборки: вечерСложность: простаяДеталей: 7Питание: 5 В от Arduino
Содержание

Часы на Arduino Uno собираются из трёх частей: модуль DS3231 считает время, индикатор TM1637 его показывает, а три кнопки меняют часы и минуты. По даташиту DS3231 точность ±2 ppm в диапазоне 0–40 °C, то есть порядка минуты в год, а Arduino только читает время по I2C и выводит его на индикатор.

Двоеточие мигает от секундного сигнала на выводе SQW модуля, который вызывает прерывание. Полный скетч лежит ниже одним файлом, его можно скачать.

Часы — один из первых «настоящих» проектов на Arduino: результат видно сразу, а деталей мало. Время держит отдельный модуль DS3231, потому что тактовый генератор платы не рассчитан на точный счёт времени.

Ниже — данные из даташита, подключение, скетч, установка времени, батарейка и ошибки, из-за которых часы сбиваются.

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

Четырёхразрядный светодиодный индикатор TM1637 с двоеточием показывает время в руке над макетной платой

Данные — из даташита на DS3231:

  • Генератор.Встроенный термокомпенсированный кварцевый генератор (TCXO) и кристалл.
  • Точность.±2 ppm в диапазоне 0…+40 °C и ±3,5 ppm в диапазоне −40…+85 °C.
  • Питание.Основное и резервное (VBAT) — от 2,3 до 5,5 В.
  • Интерфейс.I2C, до 400 кГц; адрес 7-битный, 1101000 (0x68).
  • Выход INT/SQW.Программируемый выход меандра; вывод с открытым стоком требует внешней подтяжки.

Для сравнения: ±2 ppm за год дают 2 · 10⁻⁶ · 31 557 600 с ≈ 63 с, то есть порядка минуты. Для ±3,5 ppm получается около 110 с.

Генератор без термокомпенсации с отклонением, например, 100 ppm ушёл бы на 8,6 секунды в сутки (расчёт для примера, не данные платы Arduino).

Индикатор TM1637 — четыре семисегментных разряда на двух сигнальных проводах (CLK и DIO). Он бывает разных размеров, работает одинаково.

Подключение

Индикатор часов подключён перемычками к плате микроконтроллера

Подключение займёт несколько минут.

Модуль Вывод Arduino Uno
DS3231: VCC, GND 5 В, GND
DS3231: SDA, SCL A4, A5
DS3231: SQW D2 (прерывание 0)
TM1637: CLK, DIO D6, D7
Кнопка «часы» D5 на GND
Кнопка «минуты» D4 на GND
Кнопка «плюс» D3 на GND

Вывод SQW выдаёт сигнал с периодом в секунду. Он вызывает прерывание, а в нём переключается двоеточие: отключите SQW — точки перестанут мигать.

По даташиту вывод INT/SQW имеет открытый сток и требует подтяжки. В скетче его подтягивает внутренний резистор входа Arduino (по даташиту ATmega328P от 20 до 50 кОм); на многих модулях подтяжка уже есть.

Библиотеки

В менеджере библиотек Arduino IDE 2 найдите и установите RTClib (Adafruit) и TM1637 (Avishay Orpaz; подключается как TM1637Display.h).

Скетч

Скетч использует библиотеки RTClib и TM1637; проверено с RTClib 2.1.4 и TM1637 1.2.0.

#include <Wire.h>
#include <RTClib.h>          // Adafruit RTClib
#include <TM1637Display.h>   // TM1637Display, Avishay Orpaz

const uint8_t PIN_CLK = 6;
const uint8_t PIN_DIO = 7;
const uint8_t PIN_SQW = 2;   // прерывание 0 на Uno
const uint8_t KEY_HOUR = 5;
const uint8_t KEY_MIN = 4;
const uint8_t KEY_PLUS = 3;

TM1637Display display(PIN_CLK, PIN_DIO);
RTC_DS3231 rtc;
volatile bool colon = false;

void onTick() {
  colon = !colon;
}

void setup() {
  pinMode(KEY_HOUR, INPUT_PULLUP);
  pinMode(KEY_MIN, INPUT_PULLUP);
  pinMode(KEY_PLUS, INPUT_PULLUP);
  pinMode(PIN_SQW, INPUT_PULLUP);

  rtc.begin();
  if (rtc.lostPower()) {
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));  // время сборки, если батарейка была вынута
  }
  rtc.writeSqwPinMode(DS3231_SquareWave1Hz);          // 1 Гц на выводе SQW

  display.setBrightness(4);                           // яркость 0–7
  attachInterrupt(digitalPinToInterrupt(PIN_SQW), onTick, CHANGE);
}

void loop() {
  DateTime now = rtc.now();

  bool hourKey = !digitalRead(KEY_HOUR);
  bool minKey = !digitalRead(KEY_MIN);
  bool plusKey = !digitalRead(KEY_PLUS);

  if (plusKey && (hourKey || minKey)) {
    int h = now.hour();
    int m = now.minute();
    if (hourKey) h = (h + 1) % 24;
    else m = (m + 1) % 60;
    rtc.adjust(DateTime(now.year(), now.month(), now.day(), h, m, 0));
    delay(250);
    return;
  }

  display.showNumberDecEx(now.hour() * 100 + now.minute(),
                          colon ? 0b01000000 : 0, true);
}

Как ставить время

Тактовые кнопки рядом с индикатором для установки времени

Время ставят двумя кнопками и «плюсом».

  1. Часы.Держите кнопку «часы» и нажимайте «плюс»: час растёт на единицу.
  2. Минуты.Держите «минуты» и нажимайте «плюс»: растут минуты.
  3. Секунды.При каждой установке они обнуляются.
  4. Проверка.Сравните показания с эталоном и поправьте.

После установки время идёт само, пока в модуле есть питание или батарейка.

Батарейка

Батарейка-таблетка в открытом корпусе рядом с платой

Батарейка сохраняет время при отключении питания. По даташиту вход VBAT рассчитан на 2,3…5,5 В, и батарейка CR2032 на 3 В в него укладывается.

На многих дешёвых модулях есть цепь зарядки батарейки. Обычную CR2032 заряжать нельзя: она может вздуться. Ставьте перезаряжаемую LIR2032 или отключите цепь зарядки.

Проверьте это по схеме своего модуля. Обе батарейки продаются в российских магазинах электроники.

Типовые ошибки

  • Обычная CR2032 при включённой зарядке на модуле.Батарейка может вздуться.
  • SQW не подключён к D2.Время идёт, но двоеточие стоит.
  • Кнопки без INPUT_PULLUP.Входы «плавают», и время меняется само.
  • Не установлены библиотеки нужных авторов.Скетч не соберётся.
  • Питание модуля не по даташиту.VCC должен быть в пределах 2,3…5,5 В.
  • Время компиляции принято за точное.После потери питания его нужно выставить кнопками.

Где пригодится сегодня

Готовые часы на DS3231 сегодня продаются за копейки, но собрать самому — это лучший способ познакомиться с I2C и прерываниями. Тот же модуль подойдёт для логгера данных, будильника и таймера.

Что в итоге

Подходит: первый проект с внешним модулем и понятным результатом. Не подходит: если нужно только время и ничего больше — проще купить готовые часы.

С чего начинать с Arduino и куда двигаться дальше — в статье «ESP32 или Arduino Uno». Похожие проекты: обороты кулера и резистивная клавиатура.

Частые вопросы

Насколько точны часы на DS3231?

По даташиту ±2 ppm в диапазоне 0…+40 °C и ±3,5 ppm в диапазоне −40…+85 °C. Это порядка минуты в год при комнатной температуре.

Для часов на столе этого достаточно. Реальное отклонение зависит от температуры и возраста модуля.

Как поставить время и что будет после отключения питания?

Держите кнопку «часы» или «минуты» и нажимайте «плюс». Пока в модуле есть батарейка, часы идут и при отключённой Arduino.

Если батарейка села, скетч поставит время компиляции. Тогда выставьте время заново кнопками.

Нужен ли переход на летнее время?

Нет. DS3231 не знает о часовых поясах и переходах: он просто считает время, которое вы поставили.

В России переходов на сезонное время нет, поэтому поставьте местное время один раз.

Какую батарейку ставить в модуль?

CR2032 на 3 В, если цепь зарядки на модуле отключена, или LIR2032, если она есть. По даташиту вход VBAT принимает 2,3…5,5 В.

В российских магазинах электроники продаются оба типа. Смотрите маркировку и схему своего модуля.

Почему не мигает двоеточие?

Скорее всего, SQW не подключён к D2 или скетч не включил выход 1 Гц. По даташиту вывод INT/SQW имеет открытый сток и требует подтяжки.

Проверьте провод и подтяжку. В скетче вход D2 включён с внутренней подтяжкой.

Полезно при расчёте

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

ОбозначениеНоминалТипКол-во
—Arduino Unoили совместимая плата1
—Модуль DS3231с батарейкой CR20321
—Индикатор TM16374 разряда с двоеточием1
—Кнопкибез фиксации3
—Проводадля макетной платы1
Тегиarduinods3231tm1637
Редакция СхемОкАвторМатериалы готовит редакция сайта, формулы и номиналы сверяются с даташитами производителей, расчёты — с калькуляторами сайта.99 материалов

Похожие материалы