← До всіх проєктів
Дисплеї Початковий

Годинник на DS3231 і LCD 1602: точний час без інтернету

Модуль реального часу DS3231 з батарейкою тримає час роками, а LCD 1602 з I2C-перехідником показує його на двох рядках. Два пристрої на одній шині I2C, автоматичне встановлення часу під час прошивки і вбудований термометр.

Складність
Початковий
Час
40 min
Категорія
Дисплеї
Оновлено

Про проєкт

ESP32 вміє брати час з інтернету через NTP, але без Wi-Fi після кожного перезавантаження він починає з нуля. Модуль DS3231 — годинник реального часу з термокомпенсованим кварцом: похибка близько ±2 хв на рік, а батарейка CR2032 тримає хід роками. Виводимо час, дату й температуру на LCD 1602.

Що знадобиться

  • ESP32 DevKit
  • Модуль DS3231 (ZS-042 або міні-версія) + батарейка CR2032
  • LCD 1602 з I2C-перехідником (PCF8574, адреса 0x27 або 0x3F)
  • Бібліотеки RTClib (Adafruit) і LiquidCrystal_I2C

Схема

Обидва модулі сидять на одній шині I2C, у кожного своя адреса (DS3231 — 0x68, LCD — 0x27):

Модуль VCC GND SDA SCL
DS3231 3V3 GND GPIO21 GPIO22
LCD 1602 3V3 (або 5V) GND GPIO21 GPIO22

Від 3.3 В дисплей працює, але контраст нижчий: підкрутіть синій потенціометр на I2C-платі. Якщо живите LCD від 5 В, пам'ятайте, що його підтягувальні резистори тягнуть SDA/SCL до 5 В. ESP32 зазвичай це витримує, але за специфікацією це поза нормою.

Модулі ZS-042 мають «зарядне» коло для батарейки. Зі звичайною CR2032 (не акумулятором LIR2032) його краще вимкнути: випаяти резистор або діод біля батарейки.

Як це працює

  • rtc.lostPower() повертає true, якщо годинник зупинявся, наприклад через розряджену або вийняту батарейку.
  • DateTime(F(__DATE__), F(__TIME__)) — дата й час компіляції скетча. Прошили плату, і годинник виставився сам (з відставанням на час завантаження, кілька секунд).
  • rtc.getTemperature() — вбудований датчик температури з кроком 0.25 °C. Він вимірює температуру самого чипа, тож у корпусі показує на 1–2 °C більше за повітря.
  • snprintf формує рядок фіксованої ширини: цифри не «стрибають», а залишки старого тексту затираються.

HD44780 (контролер LCD) не має кирилиці у вбудованому шрифті, тому дні тижня пишемо латиницею.

Код

// Годинник: DS3231 (час) + LCD 1602 по I2C
#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>

RTC_DS3231 rtc;
LiquidCrystal_I2C lcd(0x27, 16, 2);
const char* DAYS[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};   // на LCD немає кирилиці

void setup() {
  lcd.init();
  lcd.backlight();
  if (!rtc.begin()) {
    lcd.print("RTC not found");
    while (true) delay(1000);
  }
  if (rtc.lostPower()) {
    // батарейку виймали: ставимо час компіляції скетча
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
}

void loop() {
  DateTime now = rtc.now();
  char line[17];   // 16 символів + нуль у кінці
  snprintf(line, sizeof line, "%02d:%02d:%02d   %s", now.hour(), now.minute(), now.second(), DAYS[now.dayOfTheWeek()]);
  lcd.setCursor(0, 0);
  lcd.print(line);
  snprintf(line, sizeof line, "%02d.%02d.%04d %3.0fC", now.day(), now.month(), now.year(), rtc.getTemperature());
  lcd.setCursor(0, 1);
  lcd.print(line);
  delay(200);
}

Типові помилки

  • Порожній екран або рядок квадратів. Не та адреса (спробуйте 0x3F) або не накручено контраст. Скетч-сканер I2C покаже адреси всіх пристроїв на шині.
  • Час скидається після вимкнення. Батарейка сіла, або модуль «заряджає» звичайну CR2032.
  • Час відстає на кілька секунд після прошивки. Це нормально: __TIME__ — момент компіляції, а не завантаження.

Що далі

Додайте кнопки для встановлення часу або синхронізуйте DS3231 з NTP раз на добу: ESP32 підключається до Wi-Fi, отримує точний час і записує його в RTC.