Raspberry Pi Pico: модуль RTC DS1307 – отслеживание времени (MicroPython)
В этом руководстве вы узнаете, как подключить модуль RTC DS1307 к Raspberry Pi Pico, запрограммированному на MicroPython. Мы рассмотрим основные принципы работы модуля, как подключить его к Pico, как установить и отслеживать время. В завершение мы создадим простые цифровые часы с OLED-дисплеем.
Содержание:
В этом руководстве мы рассмотрим следующие темы:
Предварительные требования – прошивка 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 поставляется с чипом DS1307 (для отслеживания времени) и EEPROM AT24C32 (для постоянного хранения данных). Его также можно запрограммировать для генерации прямоугольных импульсов с различными частотами. Мы будем использовать только функции чипа DS1307 для отслеживания времени.
Держатель батарейки DS1307
Модуль поставляется с держателем для батарейки CR2032 для обеспечения точного отслеживания времени. В случае отключения питания он по-прежнему может точно отслеживать время.
Этот модуль также имеет возможность подключения датчика температуры DS18B20. После подключения этого датчика к модулю вы можете получать температуру с вывода DS модуля.
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 |
Рекомендуем прочитать: Распиновка Raspberry Pi Pico и Pico W: объяснение GPIO
Библиотека MicroPython для модулей RTC
Для упрощения программирования Raspberry Pi Pico для взаимодействия с модулем RTC мы будем использовать библиотеку, которую можно найти по следующей ссылке.
Нажмите здесь, чтобы скачать библиотеку urtc.py: https://raw.githubusercontent.com/RuiSantosdotme/Random-Nerd-Tutorials/refs/heads/master/Projects/Raspberry-Pi-Pico/MicroPython/urtc.py
Эта библиотека совместима с модулями RTC DS1307 и DS3231.
Загрузка библиотеки urtc.py
Загрузите библиотеку на Raspberry Pi Pico, выполнив следующие шаги:
Скачайте библиотеку urtc.py по ссылке выше.
Создайте новый файл в Thonny IDE и скопируйте код библиотеки.
Перейдите в File > Save as и выберите Raspberry Pi Pico.
Назовите файл 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 с местным временем.
С этого момента, если у RTC есть подключенная батарейка, он будет поддерживать синхронизацию с вашим местным временем. Таким образом, вам больше не нужно синхронизировать его, и вы можете вызывать rtc.datetime() для получения текущего времени.
Получение времени с модуля RTC
В этом разделе мы приведём пример, который получает время с модуля RTC (который уже должен быть синхронизирован после запуска предыдущего примера) и отображает его на OLED-дисплее.
Убедитесь, что вы запустили пример из предыдущего раздела для синхронизации RTC. Также не забудьте, что вам нужен модуль ssd1306.py, импортированный на Raspberry Pi Pico. Следуйте следующим инструкциям для загрузки модуля ssd1306.py на плату.
Создайте новый файл в Thonny IDE и скопируйте код библиотеки. Код библиотеки OLED можно найти здесь.
Перейдите в File > Save as и выберите Raspberry Pi Pico.
Назовите файл 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 |
Код
Загрузите следующий код как 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:
Перейдите в File > Save as и выберите Raspberry Pi Pico.
Назовите файл main.py и нажмите OK, чтобы сохранить файл на Raspberry Pi Pico.
Отключите Raspberry Pi от REPL и обратите внимание, что он отображает правильную дату и время благодаря отслеживанию времени модулем RTC. Вы можете отключить и снова подключить питание, и он всегда будет показывать точные дату и время.
Заключение
В этом руководстве вы узнали, как синхронизировать модуль RTC с системным временем и как получать синхронизированное время с него. Вы также научились создавать простые цифровые часы, отображающие день недели, дату и время.
Мы надеемся, что это руководство оказалось для вас полезным. Другой альтернативой для получения даты и времени является использование GPS-модуля.