Годинник на DS3231 і LCD 1602: точний час без інтернету
Модуль реального часу DS3231 з батарейкою тримає час роками, а LCD 1602 з I2C-перехідником показує його на двох рядках. Два пристрої на одній шині I2C, автоматичне встановлення часу під час прошивки і вбудований термометр.
Про проєкт
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.