Arduino с DS3231 (часы реального времени): получение времени и настройка будильников

Узнайте, как использовать модуль часов реального времени DS3231 с платой Arduino. Модуль DS3231 RTC полезен для точного отсчёта времени, а также позволяет устанавливать будильники, выводить прямоугольные волны различных частот и получать показания температуры.

Arduino с DS3231 -- часы реального времени RTC -- получение времени и настройка будильников

Примечание

Используете модуль DS1307 RTC? Вместо этого следуйте данному руководству: Руководство по модулю DS1307 RTC с Arduino.

В этом руководстве мы рассмотрим следующие темы:

Знакомство с модулями часов реального времени (RTC)

Модули RTC, такие как DS3231 и DS1307, имеют собственные крошечные часы внутри для самостоятельного отслеживания времени. Обычно они поставляются с держателем батареи для подключения батарейки, чтобы они продолжали работать даже при сбросе Arduino или в случае отключения питания.

Модули RTC DS3231 и RTC DS1307

DS3231 и DS1307 являются одними из самых популярных вариантов для использования с микроконтроллерами. Оба совместимы с платами Arduino и взаимодействуют по протоколу связи I2C. DS3231 более точен, поскольку выдаёт результаты с температурной компенсацией. Кроме того, с DS3231 также можно устанавливать внешние будильники, что может быть чрезвычайно полезно для периодических задач.

Знакомство с модулем DS3231 RTC

На следующем изображении показан модуль DS3231 RTC. Он использует кварцевый генератор с температурной компенсацией (TCXO) на 32 кГц для точного отслеживания времени (он устойчив к изменениям температуры). Благодаря этому он также позволяет получать данные о температуре.

Модуль RTC DS3231

Помимо точного отслеживания даты и времени, он также имеет встроенную память для хранения до двух будильников и может выводить прямоугольные волны различных частот: 1 Гц, 4 кГц, 8 кГц и 32 кГц.

Связь с модулем RTC осуществляется по протоколу связи I2C. Обычно он находится по адресу 0x68.

Этот модуль также оснащён EEPROM 24C32 объёмом 32 байта, который вы можете использовать для хранения любых энергонезависимых данных. Вы можете общаться с этой памятью EEPROM по I2C, обращаясь по правильному адресу (0x57).

Держатель батареи DS3231

DS3231 поставляется с держателем батареи для подключения батарейки, обеспечивающей точный хронометраж. В случае отключения питания он по-прежнему может точно отслеживать время и сохранять все будильники.

Вам следует использовать батарейку LIR2032, которая является перезаряжаемой. Не используйте CR2032 (не перезаряжаемая).

Держатель батареи RTC DS3231 Модуль DS3231 RTC с резервным питанием от батареи

Если вы хотите использовать батарейку CR2032, которая не перезаряжаемая, вы должны отключить цепь зарядки батареи, отпаяв и удалив резистор (обозначенный R4 на моём модуле) рядом с диодом.

RTC DS3231 -- удаление резистора для не перезаряжаемой батареи

Будильники DS3231

DS3231 может хранить до двух будильников: будильник 1 и будильник 2. Эти будильники можно настроить на срабатывание на основе определённого времени и/или даты. При срабатывании будильника вывод SQW модуля выдаёт сигнал LOW.

Вы можете обнаружить этот сигнал с помощью Arduino и вызвать прерывания. Это полезно для установки периодических задач, автоматизации на основе времени, а также одноразовых оповещений (поскольку вы можете сбросить будильник после его срабатывания).

Каждый будильник можно настроить на срабатывание в различных режимах. Эти режимы позволяют создавать будильники, которые повторяются каждую секунду, минуту, час, ежедневно, еженедельно или даже раз в месяц.

Будильник 1:

  • Каждую секунду

  • При совпадении секунд, минут, часов, дня или даты

Будильник 2:

  • Каждую минуту

  • При совпадении минут, часов, дня или даты

Мы рассмотрим, как устанавливать будильники, далее в этом руководстве.

I2C-адрес модуля DS3231 RTC

По умолчанию адрес DS3231 RTC — 0x68, а EEPROM, подключённая к модулю, имеет адрес 0x57. В этом руководстве мы не будем рассматривать использование EEPROM.

Распиновка модуля DS3231 RTC

В следующей таблице кратко описана распиновка модуля DS3231 RTC.

32K

Выход генератора 32 кГц — может использоваться как опорный тактовый сигнал

SQW

Выход прямоугольной волны / прерывания

SCL

Вывод SCL для I2C

SDA

Вывод SDA для I2C

VCC

Питание модуля (3,3 В или 5 В)

GND

GND

Подключение модуля DS3231 RTC к Arduino UNO

Вот список деталей, необходимых для этого руководства:

Вы можете использовать приведённые выше ссылки или перейти непосредственно на MakerAdvisor.com/tools, чтобы найти все детали для ваших проектов по лучшей цене!

Подключите DS3231 к Arduino. Вы можете использовать следующую таблицу в качестве справки или посмотреть схему подключения.

Модуль DS3231 RTC

Arduino

SQW

Pin 2 (или любой другой пин, который может быть настроен как прерывание)

SCL

A5

SDA

A4

VCC

3V3

GND

GND

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

Работа с RTC

Использование модуля RTC в ваших проектах всегда требует двух важных шагов.

  1. Установка текущего времени: вы можете сделать это вручную, вставив текущее время (или другое желаемое время) в код; системное локальное время; или получить время с NTP-сервера.

  2. Сохранение времени: чтобы убедиться, что RTC сохраняет правильное время, даже при потере питания, его необходимо подключить к батарейке. Модули RTC поставляются с держателем батареи, обычно для таблеточной батарейки.

Установка библиотеки RTCLib

Существует несколько библиотек для работы с модулем DS3231 RTC. Мы будем использовать RTCLib от Adafruit, которая совместима с модулями RTC DS1307, DS3231 и PCF8523.

В Arduino IDE перейдите в Sketch > Include Library > Manage Libraries. Найдите RTCLib и установите библиотеку от Adafruit. Мы используем версию 2.1.4.

Установка библиотеки RTCLib в Arduino IDE

Arduino с DS3231: установка и чтение времени

Arduino с часами реального времени DS3231

Следующий пример устанавливает время на часах RTC, а затем считывает время в цикле каждые три секунды. Мы также считываем температуру. Этот код показывает два различных способа установки времени: синхронизация RTC с системным временем (дата и время компиляции скетча) и установка конкретной даты и времени вручную, записав их самостоятельно в код.

/*********
  Rui Santos & Sara Santos - Random Nerd Tutorials
  Complete instructions at https://RandomNerdTutorials.com/arduino-ds3231-real-time-clock/
*********/

// Based on the RTCLib Library examples: https://github.com/adafruit/RTClib/blob/master/examples
// 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(9600);

  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 Monitor.

Serial.begin(9600);

Инициализируйте модуль RTC следующим образом:

if (! rtc.begin()) {
  Serial.println("Couldn't find RTC");
  Serial.flush();
  while (1) delay(10);
}

Проверка состояния RTC

Затем проверьте, не потерял ли RTC питание, с помощью функции lostPower(). Если он не работает, потому что это новое устройство или потому что резервная батарея разрядилась, мы выведем сообщение в Serial Monitor и установим время.

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() мы получаем дату и время каждые три секунды и выводим их в Serial Monitor.

Мы вызываем 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()];

В конце мы объединяем все поля времени в одну переменную и отображаем её в Serial Monitor.

// 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 к Arduino, загрузите код на вашу плату.

Откройте Serial Monitor на скорости 9600 бод. Arduino установит время RTC и будет отображать текущее время и температуру каждые три секунды.

Arduino с DS3231 -- установка и получение времени

DS3231 с Arduino: настройка будильников

Arduino с DS3231 -- настройка будильников

Модуль 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

при совпадении дня

Следующий пример показывает, как настроить два будильника и как использовать их для вызова прерывания на Arduino. При срабатывании прерывания мы переключим состояние светодиода, подключённого к Pin 3 (поэтому для тестирования этого примера добавьте светодиод в вашу схему, подключив его к Pin 3).

/*********
  Rui Santos & Sara Santos - Random Nerd Tutorials
  Complete instructions at https://RandomNerdTutorials.com/arduino-ds3231-real-time-clock/
*********/

// 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 2

// LED for visual indication
const int ledPin = 3;

// set the alarms
// (year, month, day, hour, minutes, seconds)
DateTime alarm1Time = DateTime(2025, 1, 7, 19, 05, 0);
DateTime alarm2Time = DateTime(2025, 1, 7, 19, 06, 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);
}

void onAlarm() {
  Serial.println("Alarm occurred!");
  // toggle the current LED state
  int state = digitalRead(ledPin);
  digitalWrite(ledPin, !state);
}

void setup() {
  Serial.begin(9600);
  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_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");
  }
}

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 позволяет сохранить до двух будильников;

  • одновременно может быть активен только один будильник;

  • после срабатывания будильника необходимо сбросить его флаг, чтобы избежать повторного срабатывания и зависания платы;

  • необходимо деактивировать один будильник перед активацией другого.

Как работает код?

Мы уже рассмотрели, как инициализировать RTC, устанавливать и получать время из модуля DS3231. Мы объясним только соответствующие части, связанные с будильниками.

Определите пин, который подключён к выводу SQW. В нашем случае мы используем Pin 2, вы можете использовать любой другой пин, который можно использовать как прерывание.

#define CLOCK_INTERRUPT_PIN 2

Сначала мы создаём два объекта DateTime для установки времени будильника 1 и будильника 2.

DateTime alarm1Time = DateTime(2025, 1, 7, 15, 25, 0);
DateTime alarm2Time = DateTime(2025, 1, 7, 15, 26, 0);

Затем нам нужно отключить вывод 32K, так как мы не будем его использовать.

rtc.disable32K();

Установите вывод SQW как прерывание, чтобы мы могли вызвать функцию при срабатывании будильника. SQW работает по низкому уровню (active low), что означает, что его состояние обычно HIGH и переходит в LOW при срабатывании будильника. При срабатывании будильника мы вызовем функцию onAlarm.

// Trigger an interrupt when the alarm happens
pinMode(CLOCK_INTERRUPT_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(CLOCK_INTERRUPT_PIN), onAlarm, FALLING);

Функция onAlarm(), определённая ранее в коде, выводит сообщение в Serial Monitor и инвертирует текущее состояние Pin 3 (подключённого к светодиоду).

void onAlarm() {
  Serial.println("Alarm occured!");
  int state = digitalRead(ledPin);
  digitalWrite(ledPin, !state);
}

Сбросьте оба будильника 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. Теперь вы сможете модифицировать этот пример для использования будильников в ваших собственных проектах.

После загрузки кода вы должны получить информацию в Serial Monitor о будильниках. Светодиод будет переключаться каждый раз при срабатывании будильника.

DS3231 с Arduino -- демонстрация настройки будильников в Serial Monitor

Заключение

В этом руководстве вы узнали, как использовать модуль DS3231 RTC с Arduino для установки и получения времени, настройки будильников и получения показаний температуры. Теперь вы можете развить этот проект дальше и добавить OLED-дисплей для создания цифровых часов. Вы также можете добавить несколько кнопок и зуммер для создания будильника с дополнительными функциями.

У нас есть ещё руководства по датчикам и модулям Arduino, которые могут быть вам полезны:

Если вы хотите создать больше проектов с Arduino, ознакомьтесь с нашими проектами: