Цифровые часы Arduino с DS3231 RTC и OLED-дисплеем

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

Цифровые часы Arduino с DS3231 RTC и OLED-дисплеем

Рекомендуемые материалы:

Чтобы лучше понять шаги по созданию цифровых часов, мы рекомендуем ознакомиться с модулем DS3231 RTC и OLED-дисплеем, изучив следующие руководства:

Обзор проекта

Часы Arduino с DS3231 и OLED-дисплеем

Этот проект довольно прост для понимания:

  • Сначала мы устанавливаем время на модуле DS3231 Real Time Clock;

  • Затем мы получаем дату, время и температуру от RTC;

  • Мы отображаем дату, время и температуру на OLED-дисплее;

  • Мы обновляем OLED-дисплей новыми текущими значениями времени и показаниями каждую секунду.

Необходимые компоненты

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

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

Подключение схемы

Следуйте приведённой ниже схеме для подключения, или используйте следующую таблицу в качестве справки. Оба модуля взаимодействуют с платой Arduino по протоколу I2C.

Поскольку каждый модуль имеет уникальный I2C-адрес, мы можем использовать одну и ту же шину I2C (одни и те же выводы I2C) для связи между Arduino и модулями.

OLED-дисплей

DS3231 RTC

Arduino

GND

GND

GND

VCC

VCC

5V

SCL

SCL

A5

SDA

SDA

A4

SQW

Не подключать

32K

Не подключать

Цифровые часы Arduino с DS3231 и OLED-дисплеем — схема подключения

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

Для этого проекта вам необходимо установить следующие библиотеки:

Следуйте приведённым ниже инструкциям для установки библиотек:

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

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

Затем найдите Adafruit SSD1306 и установите библиотеку.

Установка библиотеки OLED-дисплея в Arduino IDE

Теперь вы установили все необходимые библиотеки для этого проекта.

Цифровые часы Arduino — код

Следующий код создаёт цифровые часы. Скопируйте его в вашу Arduino IDE и загрузите на плату.

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

#include <Wire.h>
#include <RTClib.h>
#include <Adafruit_SSD1306.h>

RTC_DS3231 rtc;

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

// Create OLED object
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

// Days of the week array
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

void setup() {
  Serial.begin(9600);

  // Initialize OLED display
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println("SSD1306 allocation failed");
    for (;;);
  }

  // Clear the display
  display.clearDisplay();
  display.display();

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

  // Check if RTC lost power and set the time if necessary
  if (rtc.lostPower()) {
    Serial.println("RTC lost power! Setting the time...");
    // Set the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
  // Or, if you need to set the time for the first time, uncomment the following line:
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

}

void loop() {
  // Get the current time from the RTC
  DateTime now = rtc.now();

  // Clear the OLED display buffer
  display.clearDisplay();

  // Display the date
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.print("Date: ");
  display.print(now.year());
  display.print("-");
  if (now.month() < 10) display.print("0");
  display.print(now.month());
  display.print("-");
  if (now.day() < 10) display.print("0");
  display.print(now.day());

  // Display the time
  display.setCursor(0, 15);
  display.print("Time: ");
  if (now.hour() < 10) display.print("0");
  display.print(now.hour());
  display.print(":");
  if (now.minute() < 10) display.print("0");
  display.print(now.minute());
  display.print(":");
  if (now.second() < 10) display.print("0");
  display.print(now.second());

  // Display the day of the week
  display.setCursor(0, 30);
  display.print("Day: ");
  display.print(daysOfTheWeek[now.dayOfTheWeek()]);

  // Display the temperature from DS3231
  display.setCursor(0, 45);
  display.print("Temp: ");
  display.print(rtc.getTemperature());
  display.cp437(true);
  display.write(167);
  display.print("C");

  // Display everything on the OLED
  display.display();

  delay(1000);
}

Просмотреть исходный код

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

Давайте кратко рассмотрим, как работает код.

Сначала подключаем необходимые библиотеки. Wire — для протокола связи I2C, RTCLib — для взаимодействия с DS3231, и Adafruit_SSD1306 — для взаимодействия с OLED-дисплеем.

#include <Wire.h>
#include <RTClib.h>
#include <Adafruit_SSD1306.h>

Создаём экземпляр RTC_DS3231 с именем rtc для обращения к модулю RTC.

RTC_DS3231 rtc;

Определяем ширину и высоту экрана OLED.

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

Создаём объект Adafruit_SSD1306 с именем display с ранее определёнными шириной и высотой экрана.

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

Затем создаём массив символов с днями недели.

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

Вы можете получить доступ к каждому дню по его индексу. Например:

  • daysOfTheWeek[0] вернёт «Sunday».

  • daysOfTheWeek[1] вернёт «Monday».

В setup() следующие строки инициализируют OLED-дисплей.

// Initialize OLED display
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
  Serial.println("SSD1306 allocation failed");
  for (;;);
}

Эти две команды очищают дисплей.

display.clearDisplay();
display.display();

Далее инициализируем модуль RTC.

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

Затем проверяем, терял ли 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__ — это макросы, которые предоставляют текущую дату и время на момент компиляции.

Если вам нужно повторно установить время на ранее настроенном устройстве, вы можете раскомментировать следующую строку.

// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

В loop() мы получаем данные от модуля 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)

Устанавливаем размер и цвет текста на дисплее.

display.setTextSize(1);
display.setTextColor(WHITE);

А затем начинаем отображать информацию на дисплее. Следующие строки выводят дату.

display.setCursor(0, 0);
display.print("Date: ");
display.print(now.year());
display.print("-");
if (now.month() < 10) display.print("0");
display.print(now.month());
display.print("-");
if (now.day() < 10) display.print("0");
display.print(now.day());

Далее выводим время:

display.setCursor(0, 15);
display.print("Time: ");
if (now.hour() < 10) display.print("0");
display.print(now.hour());
display.print(":");
if (now.minute() < 10) display.print("0");
display.print(now.minute());
display.print(":");
if (now.second() < 10) display.print("0");
display.print(now.second());

День недели:

display.setCursor(0, 30);
display.print("Day: ");
display.print(daysOfTheWeek[now.dayOfTheWeek()]);

И наконец, температуру.

display.setCursor(0, 45);
display.print("Temp: ");
display.print(rtc.getTemperature());
display.cp437(true);
display.write(167);
display.print("C");

Для отображения символа градуса (°) мы используем шрифт Code Page 437. Для этого необходимо установить cp437 в true следующим образом:

display.cp437(true);

Затем используем метод write() для отображения выбранного символа. Символ ° соответствует символу 167.

display.write(167);

Наконец, необходимо вызвать display.display(), чтобы информация действительно была записана на экран.

display.display();

Обратите внимание, что мы добавляем ведущий ноль, когда число меньше 10 для времени и даты. Так, вместо, например: 3:5:6 (что выглядит странно для формата времени), вы получите 03:05:06.

Демонстрация

Загрузите код на плату Arduino. Убедитесь, что вы выбрали правильную плату и COM-порт в Arduino IDE.

После загрузки OLED-дисплей покажет дату, время и температуру. Данные обновляются каждую секунду.

Цифровые часы Arduino DS3231 с OLED-дисплеем

Заключение

Поздравляем! Вы собрали цифровые часы на Arduino с модулем DS3231 RTC и OLED-дисплеем. Вместо OLED-дисплея вы можете использовать LCD-дисплей.

У нас есть другие проекты с Arduino, которые могут вам понравиться:

Узнайте больше об Arduino с нашими материалами: