ESP8266 NodeMCU: модуль часов реального времени DS3231 (RTC) — получение времени и настройка будильников
Узнайте, как подключить модуль часов реального времени DS3231 к ESP8266 для получения времени и настройки будильников. Модуль DS3231 RTC — это отличный модуль для точного хранения времени, он позволяет устанавливать будильники, генерировать прямоугольные сигналы с различными частотами, а также получать показания температуры.
Используете модуль DS1307 RTC? Следуйте этому руководству: ESP8266 NodeMCU: руководство по модулю часов реального времени DS1307 (RTC).
В этом руководстве мы рассмотрим следующие темы:
Знакомство с модулями часов реального времени (RTC)
Модули RTC, такие как DS3231 и DS1307, имеют внутри крошечные часы для отслеживания времени независимо, без подключения к микроконтроллеру. Они оснащены держателем батарейки для подключения батареи, поэтому продолжают работать, даже если ESP8266 перезагрузится или потеряет питание.
DS3231 и DS1307 — одни из самых популярных вариантов для использования с микроконтроллерами. Оба совместимы с платами ESP8266 и обмениваются данными по протоколу I2C. DS3231 более точен, поскольку обеспечивает результаты с температурной компенсацией. Кроме того, с DS3231 можно настраивать внешние будильники, что может быть чрезвычайно полезно в проектах автоматизации и регистрации данных.
Знакомство с модулем DS3231 RTC
На следующей картинке показан модуль DS3231 RTC. Он использует кварцевый генератор 32 кГц с температурной компенсацией (TCXO) для точного отслеживания времени (он устойчив к изменениям температуры). Благодаря этому он также позволяет получать данные о температуре.
Помимо точного отслеживания даты и времени, он также имеет встроенную память для хранения до двух будильников и может генерировать прямоугольные сигналы на различных частотах: 1 Гц, 4 кГц, 8 кГц и 32 кГц.
Для связи с модулем RTC используется протокол I2C. Обычно его адрес — 0x68.
Этот модуль также поставляется с EEPROM-памятью 24C32 объёмом 32 байта, которую можно использовать для хранения любых энергонезависимых данных. Обращаться к этой EEPROM-памяти можно по шине I2C по адресу 0x57.
Держатель батареи DS3231
DS3231 поставляется с держателем батареи для подключения батареи для поддержания точного хронометража. В случае отключения питания он может продолжать точно отслеживать время и сохранять все будильники.
Вы должны использовать батарею LIR2032, которая является перезаряжаемой. Не используйте CR2032 (не перезаряжаемая).
Если вы хотите использовать батарею CR2032, которая не перезаряжаемая, необходимо отключить цепь зарядки батареи, отпаяв и удалив резистор (на моём модуле обозначен R4) рядом с диодом.
Будильники DS3231
DS3231 может хранить до двух будильников: будильник 1 и будильник 2. Эти будильники можно настроить на срабатывание по определённому времени и/или дате. Когда будильник срабатывает, вывод SQW модуля выдаёт сигнал LOW (это вывод с активным низким уровнем).
Вы можете обнаружить этот сигнал с помощью ESP8266 для вызова прерываний. Таким образом, эта функция чрезвычайно полезна для настройки периодического пробуждения из глубокого сна и других периодических задач, автоматизации на основе времени, а также одноразовых оповещений (поскольку будильник можно сбросить после срабатывания).
Каждый будильник может быть настроен на срабатывание в различных режимах. Эти режимы позволяют создавать будильники, которые срабатывают каждую секунду, минуту, час, ежедневно, еженедельно или даже раз в месяц. Будильник 1 и будильник 2 различаются.
Будильник 1:
Каждую секунду
Когда совпадают секунды, минуты, часы, день или дата
Будильник 2:
Каждую минуту
Когда совпадают минуты, часы, день или дата
Мы рассмотрим, как настраивать будильники, далее в этом руководстве.
I2C-адрес модуля DS3231 RTC
По умолчанию адрес DS3231 RTC — 0x68, а EEPROM, подключённая к модулю, имеет адрес 0x57. Вы можете запустить скетч сканера I2C, чтобы перепроверить адреса.
Распиновка модуля DS3231 RTC
В следующей таблице кратко описана распиновка модуля DS3231 RTC.
32K |
Выход генератора 32 кГц — может использоваться как эталон тактовой частоты |
SQW |
Выход прямоугольного сигнала / прерывания |
SCL |
Вывод SCL для I2C |
SDA |
Вывод SDA для I2C |
VCC |
Питание модуля (3.3 В или 5 В) |
GND |
GND |
Подключение модуля DS3231 RTC к ESP8266
Вот список компонентов, необходимых для этого руководства:
Плата ESP8266 — читайте Лучшие платы разработки ESP8266
Вы можете использовать ссылки выше или перейти напрямую на MakerAdvisor.com/tools, чтобы найти все компоненты для ваших проектов по лучшей цене!
Подключите DS3231 к ESP8266. Вы можете использовать следующую таблицу в качестве справки или посмотреть на схему подключения. Мы используем стандартные выводы I2C.
Модуль DS3231 RTC |
ESP8266 |
|---|---|
SQW |
GPIO 14 (или любой другой цифровой вывод) |
SCL |
GPIO 5 (D1) |
SDA |
GPIO 4 (D2) |
VCC |
3V3 |
GND |
GND |
Вам также может быть полезно: Справочник по распиновке ESP8266: какие GPIO следует использовать?
Работа с RTC
Использование модуля RTC в ваших проектах всегда требует двух важных шагов.
Установка текущего времени: это можно сделать вручную, вставив текущее время (или другое желаемое время) в код; использовать системное локальное время; или получить время с NTP-сервера.
Сохранение времени: чтобы убедиться, что RTC сохраняет правильное время, даже если он потеряет питание, необходимо подключить батарею. Модули RTC поставляются с держателем батареи, обычно для батарейки типа «таблетка».
Установка библиотеки RTCLib
Мы будем программировать ESP8266 NodeMCU с помощью Arduino IDE. Убедитесь, что у вас установлены платы ESP8266, следуя этому руководству: Установка платы ESP8266 в Arduino IDE 2 (Windows, Mac OS X, Linux)
Существует несколько библиотек для взаимодействия с модулем DS3231 RTC. Мы будем использовать RTCLib от Adafruit, которая совместима с модулями RTC DS1307, DS3231 и PCF8523. Кроме того, эта библиотека совместима с платами ESP8266.
В Arduino IDE перейдите в Sketch > Include Library > Manage Libraries. Найдите RTCLib и установите библиотеку от Adafruit. Мы используем версию 2.1.4.
ESP8266 NodeMCU с DS3231: установка и чтение времени
Следующий пример устанавливает время на модуле RTC, а затем считывает время в цикле каждые три секунды. Мы также считываем температуру. Этот код показывает два различных способа установки времени: синхронизация RTC с системным временем (дата и время компиляции скетча) и установка конкретной даты и времени вручную путём записи их в коде.
/*********
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete instructions at https://RandomNerdTutorials.com/esp8266-nodemcu-ds3231-real-time-clock-arduino/
*********/
// Based on the RTCLib Library examples: github.com/adafruit/RTClib
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
#include "RTClib.h"
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
void setup () {
Serial.begin(115200);
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
while (1) delay(10);
}
if (rtc.lostPower()) {
Serial.println("RTC lost power, let's set the time!");
// When time needs to be set on a new device, or after a power loss, the
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
//rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
// When time needs to be re-set on a previously configured device, the
// following line sets the RTC to the date & time this sketch was compiled
//rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
//rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
void loop () {
// Get the current time from the RTC
DateTime now = rtc.now();
// Getting each time field in individual variables
// And adding a leading zero when needed;
String yearStr = String(now.year(), DEC);
String monthStr = (now.month() < 10 ? "0" : "") + String(now.month(), DEC);
String dayStr = (now.day() < 10 ? "0" : "") + String(now.day(), DEC);
String hourStr = (now.hour() < 10 ? "0" : "") + String(now.hour(), DEC);
String minuteStr = (now.minute() < 10 ? "0" : "") + String(now.minute(), DEC);
String secondStr = (now.second() < 10 ? "0" : "") + String(now.second(), DEC);
String dayOfWeek = daysOfTheWeek[now.dayOfTheWeek()];
// Complete time string
String formattedTime = dayOfWeek + ", " + yearStr + "-" + monthStr + "-" + dayStr + " " + hourStr + ":" + minuteStr + ":" + secondStr;
// Print the complete formatted time
Serial.println(formattedTime);
// Getting temperature
Serial.print(rtc.getTemperature());
Serial.println("ºC");
Serial.println();
delay(3000);
}
Как работает код
Начните с подключения библиотеки RTCLib.
#include "RTClib.h"
Затем создайте объект RTC_DS3231 с именем rtc.
RTC_DS3231 rtc;
Далее создайте массив символов с днями недели.
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
Вы можете обращаться к каждому дню по его индексу. Например:
daysOfTheWeek[0] вернёт «Sunday».
daysOfTheWeek[1] вернёт «Monday».
В setup() инициализируйте монитор порта.
Serial.begin(115200);
Инициализируйте модуль RTC следующим образом:
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
while (1) delay(10);
}
Проверка состояния RTC
Затем проверьте, потерял ли RTC питание, с помощью функции lostPower(). Если он не работает, потому что это новое устройство или потому что резервная батарея вышла из строя, мы выведем сообщение в мониторе порта и установим время.
if (rtc.lostPower()) {
Serial.println("RTC lost power, let's set the time!");
Установка времени
Для установки времени на RTC мы можем использовать метод adjust() нашего объекта rtc. Следующая строка устанавливает дату и время RTC на текущую дату и время, когда этот скетч был последний раз скомпилирован.
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
__DATE__ и __TIME__ — это макросы, которые предоставляют текущую дату и время на момент компиляции.
В качестве альтернативы вы можете установить дату и время вручную. Передайте поля времени в следующем порядке: год, месяц, день, час, минута, секунда. Эта строка закомментирована в коде.
// January 21, 2014 at 3am you would call:
rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
Если вам нужно переустановить время на ранее настроенном устройстве, вы можете вызвать одну из двух предыдущих строк для установки времени без проверки потери питания (это закомментировано в коде).
// When time needs to be re-set on a previously configured device, the
// following line sets the RTC to the date & time this sketch was compiled
//rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
//rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
Получение даты и времени
В цикле loop() мы получаем дату и время каждые три секунды и выводим их в мониторе порта.
Мы вызываем rtc.now(), чтобы получить текущую дату и время от модуля RTC.
DateTime now = rtc.now();
Он возвращает объект DateTime, содержащий значения текущего года, месяца, дня, часа, минуты и секунды.
Для доступа к каждому полю даты и времени мы можем использовать следующие методы:
now.year() |
Получает текущий год (например, 2024) |
now.month() |
Получает текущий месяц (1–12) |
now.day() |
Получает текущий день месяца (1–31) |
now.dayOfTheWeek() |
Получает день недели (0–6), где 0 — воскресенье, а 6 — суббота |
now.hour() |
Получает текущий час (0–23) |
now.minute() |
Получает текущую минуту (0–59) |
now.second() |
Получает текущую секунду (0–59) |
Для преобразования результата в строку мы можем использовать метод String(). Мы также передаём DEC в качестве второго аргумента метода String(), чтобы получить десятичное число.
String yearStr = String(now.year(), DEC);
В случае месяца, дня, часа, минуты и секунды мы добавляем ведущий ноль, когда число меньше 10. Таким образом, вместо, например, 3:5:6 (что выглядит странно для формата времени), вы получите 03:05:06.
String monthStr = (now.month() < 10 ? "0" : "") + String(now.month(), DEC);
String dayStr = (now.day() < 10 ? "0" : "") + String(now.day(), DEC);
String hourStr = (now.hour() < 10 ? "0" : "") + String(now.hour(), DEC);
String minuteStr = (now.minute() < 10 ? "0" : "") + String(now.minute(), DEC);
String secondStr = (now.second() < 10 ? "0" : "") + String(now.second(), DEC);
Чтобы получить название дня недели, мы используем массив daysOfTheWeek, который создали в начале кода.
String dayOfWeek = daysOfTheWeek[now.dayOfTheWeek()];
Наконец, мы объединяем все поля времени в одну переменную и выводим её в мониторе порта.
// Complete time string
String formattedTime = dayOfWeek + ", " + yearStr + "-" + monthStr + "-" + dayStr + " " + hourStr + ":" + minuteStr + ":" + secondStr;
// Print the complete formatted time
Serial.println(formattedTime);
DS3231 обеспечивает результаты с температурной компенсацией. Мы можем получить температуру, которую он измеряет, используя метод getTemperature() объекта rtc. Это возвращает температуру в градусах Цельсия.
// Getting temperature
Serial.print(rtc.getTemperature());
Serial.println("ºC");
Тестирование примера
Подключите RTC к плате ESP8266 и загрузите код на вашу плату.
Откройте монитор порта на скорости 115200 бод. ESP8266 установит время RTC и будет отображать текущее время и температуру каждые три секунды.
DS3231 с ESP8266: настройка будильников
Модуль DS3231 RTC позволяет настроить до двух будильников: будильник 1 и будильник 2. При использовании библиотеки RTCLib поддерживаются следующие режимы будильников:
Будильник |
Режим |
Значение (Вызвать будильник…) |
|---|---|---|
Будильник 1 |
DS3231_A1_PerSecond |
каждую секунду |
Будильник 1 |
DS3231_A1_Second |
когда совпадают секунды |
Будильник 1 |
DS3231_A1_Minute |
когда совпадают минуты |
Будильник 1 |
DS3231_A1_Hour |
когда совпадает час |
Будильник 1 |
DS3231_A1_Date |
когда совпадает дата |
Будильник 1 |
DS3231_A1_Day |
когда совпадает день |
Будильник 2 |
DS3231_A2_PerMinute |
каждую минуту |
Будильник 2 |
DS3231_A2_Minute |
когда совпадают минуты |
Будильник 2 |
DS3231_A2_Hour |
когда совпадает час |
Будильник 2 |
DS3231_A2_Date |
когда совпадает дата |
Будильник 2 |
DS3231_A2_Day |
когда совпадает день |
Следующий пример показывает, как настроить два будильника и как использовать их для вызова прерывания на ESP8266 (узнайте больше о прерываниях ESP8266 здесь).
/*********
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete instructions at https://RandomNerdTutorials.com/esp8266-nodemcu-ds3231-real-time-clock-arduino/
*********/
// Example based on the library: implementation of an alarm using DS3231
#include <RTClib.h>
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
// the pin that is connected to SQW
#define CLOCK_INTERRUPT_PIN 14
// LED for visual indication
const int ledPin = 2;
// set the alarms
// (year, month, day, hour, minutes, seconds)
DateTime alarm1Time = DateTime(2025, 01, 03, 18, 42, 0);
DateTime alarm2Time = DateTime(2025, 01, 03, 18, 48, 0);
void printCurrentTime(){
// Get the current time from the RTC
DateTime now = rtc.now();
// Getting each time field in individual variables
// And adding a leading zero when needed;
String yearStr = String(now.year(), DEC);
String monthStr = (now.month() < 10 ? "0" : "") + String(now.month(), DEC);
String dayStr = (now.day() < 10 ? "0" : "") + String(now.day(), DEC);
String hourStr = (now.hour() < 10 ? "0" : "") + String(now.hour(), DEC);
String minuteStr = (now.minute() < 10 ? "0" : "") + String(now.minute(), DEC);
String secondStr = (now.second() < 10 ? "0" : "") + String(now.second(), DEC);
String dayOfWeek = daysOfTheWeek[now.dayOfTheWeek()];
// Complete time string
String formattedTime = dayOfWeek + ", " + yearStr + "-" + monthStr + "-" + dayStr + " " + hourStr + ":" + minuteStr + ":" + secondStr;
// Print the complete formatted time
Serial.println(formattedTime);
}
ICACHE_RAM_ATTR void onAlarm() {
Serial.println("Alarm occured!");
// toggle the current LED state
int state = digitalRead(ledPin);
digitalWrite(ledPin, !state);
}
void setup() {
Serial.begin(115200);
pinMode (ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
// initializing the rtc
if(!rtc.begin()) {
Serial.println("Couldn't find RTC!");
Serial.flush();
while (1) delay(10);
}
if(rtc.lostPower()) {
// this will adjust to the date and time at compilation
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
// Uncomment if you need to adjust the time
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
//we don't need the 32K Pin, so disable it
rtc.disable32K();
// Trigger an interrupt when the alarm happens
pinMode(CLOCK_INTERRUPT_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(CLOCK_INTERRUPT_PIN), onAlarm, FALLING);
// set alarm 1, 2 flag to false (so alarm 1, 2 didn't happen so far)
// if not done, this easily leads to problems, as both register aren't reset on reboot/recompile
rtc.clearAlarm(1);
rtc.clearAlarm(2);
// stop oscillating signals at SQW Pin, otherwise setAlarm1 will fail
rtc.writeSqwPinMode(DS3231_OFF);
// turn off alarm 2 (in case it isn't off already)
// again, this isn't done at reboot, so a previously set alarm could easily go overlooked
rtc.disableAlarm(2);
// Schedule Alarm1 to fire when the minutes match
if(!rtc.setAlarm1(alarm1Time, DS3231_A1_Second)) { // this mode triggers the alarm when the minutes match
Serial.println("Error, alarm wasn't set!");
}else {
Serial.println("Alarm 1 will happen at specified time");
}
}
void loop() {
// print current date and time
printCurrentTime();
// Get Details about the alarm1
DateTime alarm1 = rtc.getAlarm1();
Ds3231Alarm1Mode alarm1mode = rtc.getAlarm1Mode();
char alarm1Date[12] = "DD hh:mm:ss";
alarm1.toString(alarm1Date);
Serial.print("[Alarm1: ");
Serial.print(alarm1Date);
Serial.print(", Mode: ");
switch (alarm1mode) {
case DS3231_A1_PerSecond: Serial.print("PerSecond"); break;
case DS3231_A1_Second: Serial.print("Second"); break;
case DS3231_A1_Minute: Serial.print("Minute"); break;
case DS3231_A1_Hour: Serial.print("Hour"); break;
case DS3231_A1_Date: Serial.print("Date"); break;
case DS3231_A1_Day: Serial.print("Day"); break;
}
// the value at SQW-Pin (because of pullup 1 means no alarm)
Serial.print("] SQW: ");
Serial.print(digitalRead(CLOCK_INTERRUPT_PIN));
// whether a alarm fired
Serial.print(" Fired: ");
Serial.print(rtc.alarmFired(1));
// Only one alarm can be set at a time, reset alarm 1 and activate alarm 2
// resetting SQW and alarm 1 flag
// the next alarm could now be configurated
if (rtc.alarmFired(1)) {
rtc.clearAlarm(1);
Serial.println(" - Alarm cleared");
// Set Alarm 2
if(!rtc.setAlarm2(alarm2Time, DS3231_A2_Minute)) { // this mode triggers the alarm when the minutes match
Serial.println("Error, alarm wasn't set!");
}else {
Serial.println("Alarm 2 will happen at specified time");
}
// Get Details about the alarm2
DateTime alarm1 = rtc.getAlarm2();
Ds3231Alarm2Mode alarm2mode = rtc.getAlarm2Mode();
char alarm2Date[12] = "DD hh:mm:ss";
alarm1.toString(alarm2Date);
Serial.print("[Alarm2: ");
Serial.print(alarm2Date);
Serial.print(", Mode: ");
switch (alarm2mode) {
case DS3231_A2_PerMinute: Serial.print("Every Minute"); break;
case DS3231_A2_Minute: Serial.print("Minute"); break;
case DS3231_A2_Hour: Serial.print("Hour"); break;
case DS3231_A2_Date: Serial.print("Date"); break;
case DS3231_A2_Day: Serial.print("Day"); break;
}
// the value at SQW-Pin (because of pullup 1 means no alarm)
Serial.print("] SQW: ");
Serial.print(digitalRead(CLOCK_INTERRUPT_PIN));
// whether a alarm fired
Serial.print(" Fired: ");
Serial.print(rtc.alarmFired(1));
}
Serial.println();
delay(2000);
}
Важные замечания о будильниках:
RTC позволяет сохранить до двух будильников;
одновременно может быть активен только один будильник;
после срабатывания будильника необходимо сбросить его флаг, чтобы избежать повторного срабатывания и сбоя ESP8266;
необходимо деактивировать один будильник перед активацией другого.
Как работает код?
Мы уже рассмотрели, как инициализировать RTC, устанавливать и получать время от модуля DS3231. Мы объясним только соответствующие части, связанные с будильниками.
Определите GPIO, который подключён к выводу SQW. В нашем случае мы используем GPIO 14, вы можете использовать любой другой подходящий цифровой GPIO.
// the pin that is connected to SQW
#define CLOCK_INTERRUPT_PIN 14
Сначала мы создаём два объекта DateTime для установки времени будильника 1 и будильника 2.
DateTime alarm1Time = DateTime(2025, 01, 03, 18, 42, 0);
DateTime alarm2Time = DateTime(2025, 01, 03, 18, 48, 0);
Затем нам нужно отключить вывод 32K, потому что мы не будем его использовать.
rtc.disable32K();
Установите вывод SQW как прерывание, чтобы мы могли вызвать функцию при срабатывании будильника. SQW активен по низкому уровню, что означает, что его состояние обычно HIGH и меняется на LOW при срабатывании будильника. Когда будильник сработает, мы вызовем функцию onAlarm.
// Trigger an interrupt when the alarm happens
pinMode(CLOCK_INTERRUPT_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(CLOCK_INTERRUPT_PIN), onAlarm, FALLING);
Функция onAlarm(), определённая ранее в коде, выводит сообщение в мониторе порта и инвертирует текущее состояние GPIO 2 (подключённого к встроенному светодиоду ESP8266).
ICACHE_RAM_ATTR void onAlarm() {
Serial.println("Alarm occured!");
// toggle the current LED state
int state = digitalRead(ledPin);
digitalWrite(ledPin, !state);
}
Примечание: функция, которая вызывается при срабатывании прерывания, должна иметь атрибут ICACHE_RAM_ATTR перед определением функции, чтобы код прерывания выполнялся в оперативной памяти.
Сбросьте оба будильника 1 и 2 перед установкой любого будильника.
rtc.clearAlarm(1);
rtc.clearAlarm(2);
Мы будем использовать вывод SQW для срабатывания будильников. Мы не будем использовать его функцию генерации прямоугольных сигналов. Поэтому нам нужно её остановить.
rtc.writeSqwPinMode(DS3231_OFF);
Одновременно может работать только один будильник. Поэтому отключите будильник 2 перед настройкой будильника 1.
rtc.disableAlarm(2);
Настройте будильник 1, используя функцию setAlarm1() объекта rtc. Передайте в качестве аргументов время для будильника 1 и режим будильника. Мы уже рассмотрели варианты режимов будильников 1 и 2 ранее. В данном случае мы устанавливаем DS3231_A1_Minute, что означает, что будильник сработает, когда совпадут минуты.
// Schedule Alarm1 to fire when the minutes match
if(!rtc.setAlarm1(alarm1Time, DS3231_A1_Minute)) { // this mode triggers the alarm when the minutes match
Serial.println("Error, alarm wasn't set!");
} else {
Serial.println("Alarm 1 will happen at specified time");
}
В цикле loop() мы выводим подробности текущего будильника.
// Get Details about the alarm1
DateTime alarm1 = rtc.getAlarm1();
Ds3231Alarm1Mode alarm1mode = rtc.getAlarm1Mode();
char alarm1Date[12] = "DD hh:mm:ss";
alarm1.toString(alarm1Date);
Serial.print("[Alarm1: ");
Serial.print(alarm1Date);
Serial.print(", Mode: ");
switch (alarm1mode) {
case DS3231_A1_PerSecond: Serial.print("PerSecond"); break;
case DS3231_A1_Second: Serial.print("Second"); break;
case DS3231_A1_Minute: Serial.print("Minute"); break;
case DS3231_A1_Hour: Serial.print("Hour"); break;
case DS3231_A1_Date: Serial.print("Date"); break;
case DS3231_A1_Day: Serial.print("Day"); break;
}
// the value at SQW-Pin (because of pullup 1 means no alarm)
Serial.print("] SQW: ");
Serial.print(digitalRead(CLOCK_INTERRUPT_PIN));
// whether a alarm fired
Serial.print(" Fired: ");
Serial.print(rtc.alarmFired(1));
Мы можем проверить, сработал ли будильник 1, с помощью следующей строки:
if (rtc.alarmFired(1)) {
Когда он срабатывает, мы сбрасываем этот будильник и начинаем настройку будильника 2.
// Set Alarm 2
if(!rtc.setAlarm2(alarm2Time, DS3231_A2_Minute)) { // this mode triggers the alarm when the minutes match
Serial.println("Error, alarm wasn't set!");
} else {
Serial.println("Alarm 2 will happen at specified time");
}
Это лишь краткий пример, демонстрирующий детали настройки будильников с модулем DS3231 RTC. Теперь вы должны быть в состоянии модифицировать этот пример для использования будильников в ваших проектах автоматизации и IoT.
После загрузки кода вы должны увидеть в мониторе порта информацию о будильниках. Встроенный светодиод ESP8266 будет переключаться каждый раз, когда срабатывает будильник.
Заключение
В этом руководстве вы узнали, как подключить модуль DS3231 RTC к ESP8266 для получения времени и срабатывания будильников. Этот модуль может быть полезен для периодических задач, регистрации данных, автоматизации и многого другого. Вы также можете добавить OLED-дисплей или LCD для создания цифровых часов.
У нас есть руководства по другим модулям с ESP8266, которые могут быть вам полезны.
ESP8266 NodeMCU с анемометром: измерение скорости ветра (Arduino IDE)
Как использовать I2C LCD с ESP32 в Arduino IDE (совместимо с ESP8266)
Узнайте больше о ESP8266 с нашими ресурсами: