Raspberry Pi Pico: модуль RTC DS1307 – отслеживание времени (MicroPython)

В этом руководстве вы узнаете, как подключить модуль RTC DS1307 к Raspberry Pi Pico, запрограммированному на MicroPython. Мы рассмотрим основные принципы работы модуля, как подключить его к Pico, как установить и отслеживать время. В завершение мы создадим простые цифровые часы с OLED-дисплеем.

Raspberry Pi Pico: модуль RTC DS1307 - отслеживание времени (MicroPython)

Содержание:

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

Предварительные требования – прошивка MicroPython

Для выполнения этого руководства вам необходимо установить прошивку MicroPython на плату Raspberry Pi Pico. Вам также понадобится IDE для написания и загрузки кода на плату.

Рекомендуемой средой разработки MicroPython для Raspberry Pi Pico является Thonny IDE. Следуйте следующему руководству, чтобы узнать, как установить Thonny IDE, прошить прошивку MicroPython и загрузить код на плату.

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

Чтобы отслеживать время, когда Raspberry Pi Pico не подключен к компьютеру или к интернету, мы можем использовать модули часов реального времени (RTC).

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

DS3231 и DS1307 являются одними из самых популярных вариантов для использования с микроконтроллерами. Оба совместимы с Raspberry Pi Pico и обмениваются данными по протоколу I2C. DS3231 более точен, поскольку оснащен датчиком температуры и выдает результаты с температурной компенсацией. Тем не менее, DS1307 также достаточно точен и подходит для большинства приложений, требующих отслеживания времени.

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

На протяжении всего руководства мы будем использовать модуль RTC DS1307, но если у вас есть DS3231, большая часть предоставленной информации применима к обоим модулям. Кроме того, весь код должен быть совместим с обоими модулями с небольшим изменением.

Модуль RTC DS1307

Модуль RTC DS1307 поставляется с чипом DS1307 (для отслеживания времени) и EEPROM AT24C32 (для постоянного хранения данных). Его также можно запрограммировать для генерации прямоугольных импульсов с различными частотами. Мы будем использовать только функции чипа DS1307 для отслеживания времени.

Держатель батарейки DS1307

Модуль поставляется с держателем для батарейки CR2032 для обеспечения точного отслеживания времени. В случае отключения питания он по-прежнему может точно отслеживать время.

Этот модуль также имеет возможность подключения датчика температуры DS18B20. После подключения этого датчика к модулю вы можете получать температуру с вывода DS модуля.

Модуль RTC DS1307 - держатель батарейки Модуль RTC DS1307 - держатель батарейки с батарейкой

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

По умолчанию адрес RTC DS1307 – 0x68, а EEPROM, подключенная к модулю, имеет адрес 0x50. Вы можете запустить скетч I2C-сканера, чтобы проверить эти значения:

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

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

Вывод

Описание

SQ

Выход для прямоугольных импульсов (мы не будем использовать)

DS

Выход для показаний температуры при подключенном DS18B20 (мы не будем использовать)

SCL

Вывод SCL для I2C

SDA

Вывод SDA для I2C

VCC

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

GND

GND

BAT

Вход резервного питания (мы не будем использовать) или используйте стандартный держатель батарейки

Подключение модуля RTC DS1307 к Pico

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

  • Raspberry Pi Pico

  • Модуль RTC DS1307 или модуль DS3231

  • OLED-дисплей SSD1306

  • Соединительные провода

  • Макетная плата

Мы будем использовать только выводы I2C и питания для подключения модуля RTC к Raspberry Pi Pico. Мы подключим SCL к GPIO 5, а SDA к GPIO 4. Вы можете использовать любые другие подходящие выводы I2C, если измените их в коде. Вы можете использовать следующую таблицу в качестве справки или посмотреть на схему подключения.

Модуль RTC DS1307

Raspberry Pi Pico

SCL

GPIO 5

SDA

GPIO 4

VCC

3V3(OUT)

GND

GND

Схема подключения модуля RTC DS1307 к Raspberry Pi Pico

Рекомендуем прочитать: Распиновка Raspberry Pi Pico и Pico W: объяснение GPIO

Библиотека MicroPython для модулей RTC

Для упрощения программирования Raspberry Pi Pico для взаимодействия с модулем RTC мы будем использовать библиотеку, которую можно найти по следующей ссылке.

Эта библиотека совместима с модулями RTC DS1307 и DS3231.

Загрузка библиотеки urtc.py

Загрузите библиотеку на Raspberry Pi Pico, выполнив следующие шаги:

  1. Скачайте библиотеку urtc.py по ссылке выше.

  2. Создайте новый файл в Thonny IDE и скопируйте код библиотеки.

  3. Перейдите в File > Save as и выберите Raspberry Pi Pico.

  4. Назовите файл urtc.py и нажмите OK, чтобы сохранить файл на Raspberry Pi Pico.

Вот и всё. Библиотека загружена на вашу плату. Теперь вы можете использовать функции библиотеки в своём коде, импортировав её.

Синхронизация модуля RTC

Первое, что вы должны сделать при использовании модуля RTC в своих проектах, – это синхронизировать время RTC с вашим местным временем. Для этого вы можете использовать следующий код:

import time
import urtc
from machine import I2C, Pin

days_of_week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

# Initialize RTC (connected to I2C)
i2c = I2C(0, scl=Pin(5), sda=Pin(4))
rtc = urtc.DS1307(i2c)

# Set the current time using a specified time tuple
# Time tupple: (year, month, day, day of week, hour, minute, seconds, milliseconds)
#initial_time = (2024, 1, 30, 1, 12, 30, 0, 0)

# Or get the local time from the system
initial_time_tuple = time.localtime() #tuple (microPython)
initial_time_seconds = time.mktime(initial_time_tuple) # local time in seconds

# Convert to tuple compatible with the library
initial_time = urtc.seconds2tuple(initial_time_seconds)

# Sync the RTC
rtc.datetime(initial_time)

while True:
    current_datetime = rtc.datetime()
    print('Current date and time:')
    print('Year:', current_datetime.year)
    print('Month:', current_datetime.month)
    print('Day:', current_datetime.day)
    print('Hour:', current_datetime.hour)
    print('Minute:', current_datetime.minute)
    print('Second:', current_datetime.second)
    print('Day of the Week:', days_of_week[current_datetime.weekday])

    time.sleep(1)

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

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

Давайте быстро рассмотрим основные части этого кода.

Импорт библиотек

Сначала вам нужно импортировать модуль urtc, который вы загрузили ранее и который содержит функции для взаимодействия с RTC. Вам также нужно импортировать классы Pin и I2C для установления I2C-соединения с модулем.

import time
import urtc
from machine import I2C, Pin

Инициализация модуля RTC

Затем инициализируйте I2C-соединение и создайте объект с именем rtc для обращения к нашему модулю RTC DS1307.

i2c = I2C(0, scl=Pin(5), sda=Pin(4))
rtc = urtc.DS1307(i2c)

Если вы используете DS3231, замените следующую строку:

rtc = urtc.DS1307(i2c)

На:

rtc = urtc.DS3231(i2c)

Синхронизация времени

Для синхронизации времени RTC необходимо использовать метод datetime() на объекте rtc и передать в качестве аргумента кортеж времени в следующем формате:

(year, month, day, day of week, hour, minute, seconds, milliseconds)

Примечание

Этот кортеж отличается от кортежа, используемого модулем time в MicroPython.

Мы можем синхронизировать RTC с системным местным временем.

Сначала мы получаем кортеж местного времени с помощью time.localtime().

initial_time = urtc.seconds2tuple(initial_time_seconds)

Возвращаемый кортеж отличается от того, который используется модулем RTC.

Поэтому сначала мы конвертируем его в секунды с помощью time.mktime().

initial_time_seconds = time.mktime(initial_time_tuple) # local time in seconds

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

initial_time = urtc.seconds2tuple(initial_time_seconds)

Наконец, мы можем передать нашу переменную initial_time, содержащую местное время в кортеже, совместимом с библиотекой RTC, в функцию datetime() следующим образом:

rtc.datetime(initial_time)

После этой строки кода модуль RTC синхронизирован с вашим местным временем, и вы можете просто вызвать rtc.datetime(), чтобы получить текущее время от RTC. Эта функция возвращает объект со всеми элементами времени.

Чтобы получить и вывести каждый элемент времени, мы можем сделать следующее:

current_datetime = rtc.datetime()
print('Current date and time:')
print('Year:', current_datetime.year)
print('Month:', current_datetime.month)
print('Day:', current_datetime.day)
print('Hour:', current_datetime.hour)
print('Minute:', current_datetime.minute)
print('Second:', current_datetime.second)
print('Day of the Week:', days_of_week[current_datetime.weekday])

Запуск кода

Запустите предыдущий код, чтобы синхронизировать время RTC с местным временем.

Запуск скрипта в Thonny IDE MicroPython

С этого момента, если у RTC есть подключенная батарейка, он будет поддерживать синхронизацию с вашим местным временем. Таким образом, вам больше не нужно синхронизировать его, и вы можете вызывать rtc.datetime() для получения текущего времени.

Получение времени с модуля RTC

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

Цифровые часы Raspberry Pi Pico с OLED и модулем RTC

Убедитесь, что вы запустили пример из предыдущего раздела для синхронизации RTC. Также не забудьте, что вам нужен модуль ssd1306.py, импортированный на Raspberry Pi Pico. Следуйте следующим инструкциям для загрузки модуля ssd1306.py на плату.

  1. Создайте новый файл в Thonny IDE и скопируйте код библиотеки. Код библиотеки OLED можно найти здесь.

  2. Перейдите в File > Save as и выберите Raspberry Pi Pico.

  3. Назовите файл ssd1306.py и нажмите OK, чтобы сохранить файл на Raspberry Pi Pico.

Рекомендуем прочитать: Raspberry Pi Pico: OLED-дисплей SSD1306 (MicroPython)

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

Мы подключим OLED-дисплей к GPIO 0 (SDA) и GPIO 1 (SCL/SCK). Мы будем использовать GPIO 4 (SDA) и GPIO 5 (SCL) для подключения RTC. Вы можете использовать следующую таблицу или схему в качестве справки.

SDA

SCL/SCK

OLED-дисплей

GPIO 0

GPIO 1

Модуль RTC

GPIO 4

GPIO 5

Схема подключения Raspberry Pi Pico с модулем RTC и OLED-дисплеем

Код

Загрузите следующий код как main.py на Raspberry Pi Pico.

import time
import urtc
from machine import SoftI2C, Pin
import ssd1306

days_of_week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

# Initialize RTC Module
i2c_rtc = SoftI2C(scl=Pin(5), sda=Pin(4))
rtc = urtc.DS1307(i2c_rtc)

# Initialize OLED
oled_width = 128
oled_height = 64
i2c_oled = SoftI2C(scl=Pin(0), sda=Pin(1))
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c_oled)

while True:
    # Get current time from the RTC
    current_datetime = rtc.datetime()

    # Format the date and time as strings
    formatted_date = '{:02d}-{:02d}-{:04d}'.format(current_datetime.day, current_datetime.month, current_datetime.year)
    formatted_time = '{:02d}:{:02d}:{:02d}'.format(current_datetime.hour, current_datetime.minute, current_datetime.second)
    formatted_day_week = days_of_week[current_datetime.weekday]

    # Clear the OLED display
    oled.fill(0)

    # Display the formatted date and time
    oled.text('Date: ' + formatted_day_week, 0, 0)
    oled.text(formatted_date, 0, 16)
    oled.text('Time: ' + formatted_time, 0, 32)
    oled.show()

    # Print the formatted date and time to the shell
    print('Formatted date:', formatted_date)
    print('Formatted time:', formatted_time)

    # Wait for 1 second
    time.sleep(1)

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

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

Сначала мы импортируем необходимые библиотеки.

import time
import urtc
from machine import SoftI2C, Pin
import ssd1306

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

days_of_week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

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

# Initialize RTC Module
i2c_rtc = SoftI2C(scl=Pin(5), sda=Pin(4))
rtc = urtc.DS1307(i2c_rtc)

Инициализируем OLED-дисплей.

# Initialize OLED
oled_width = 128
oled_height = 64
i2c_oled = SoftI2C(scl=Pin(0), sda=Pin(1))
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c_oled)

Получаем текущую дату и время с модуля RTC.

while True:
    # Get current time from the RTC
    current_datetime = rtc.datetime()

Извлекаем дату и время из переменной current_datetime и форматируем их как строки. Также получаем день недели.

# Format the date and time as strings
formatted_date = '{:02d}-{:02d}-{:04d}'.format(current_datetime.day, current_datetime.month, current_datetime.year)
formatted_time = '{:02d}:{:02d}:{:02d}'.format(current_datetime.hour, current_datetime.minute, current_datetime.second)
formatted_day_week = days_of_week[current_datetime.weekday]

Наконец, отображаем отформатированные дату и время на OLED-дисплее.

# Clear the OLED display
oled.fill(0)

# Display the formatted date and time
oled.text('Date: ' + formatted_day_week, 0, 0)
oled.text(formatted_date, 0, 16)
oled.text('Time: ' + formatted_time, 0, 32)
oled.show()

Мы также выводим дату и время в консоль.

# Print the formatted date and time to the shell
print('Formatted date:', formatted_date)
print('Formatted time:', formatted_time)

Время обновляется на экране каждую секунду.

# Wait for 1 second
time.sleep(1)

Тестирование кода

После загрузки кода на плату с именем main.py:

  1. Перейдите в File > Save as и выберите Raspberry Pi Pico.

  2. Назовите файл main.py и нажмите OK, чтобы сохранить файл на Raspberry Pi Pico.

Отключите Raspberry Pi от REPL и обратите внимание, что он отображает правильную дату и время благодаря отслеживанию времени модулем RTC. Вы можете отключить и снова подключить питание, и он всегда будет показывать точные дату и время.

Часы Raspberry Pi Pico с OLED-дисплеем и модулем RTC

Заключение

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

Мы надеемся, что это руководство оказалось для вас полезным. Другой альтернативой для получения даты и времени является использование GPS-модуля.