repkatech
repkatech
477 просмотров0 комментариев

Проект “Умный будильник” на базе одноплатного компьютера Repka PI 4.

Представляю вам образовательный проект — “Умный будильник” разработанный в рамках учебно-методического комплекса на базе одноплатного компьютера Repka PI 4.

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

Для отображения текущего времени применяется компактный цифровой дисплей TM1637 с четырьмя 7-сегментными индикаторами, обеспечивающий чёткую визуализацию часов и минут. Звуковое оповещение реализовано с помощью пассивного зуммера, а дополнительная тактильная индикация достигается за счёт вибромотора

Этот проект отлично подходит для демонстрации реальной интеграции нескольких периферийных модулей и формирования законченного, функционального устройства. Он может быть использован как часть обучающего курса по автоматике, встраиваемым системам, а также для практического освоения архитектуры Repka Pi и работы с внешними устройствами.

Проект будет собираться с использованием “Учебно-методический комплекс REPKA”. Схему сборки можно найти в разделе "Примеры готовых проектов" учебного пособия УМК “REPKA”.

Также все необходимые материалы и схемы подключения доступны в репозитории на платформе Gitflic.

Компоненты проекта

1. Пассивный зуммер (Passive buzzer KY-006), представленный на рисунке 1, используется в проекте в качестве звукового оповещателя для пробуждения. Благодаря своей конструкции, он способен воспроизводить различные звуковые сигналы, создавая эффективное аудиоуведомление при срабатывании будильника.

2. Модуль MOSFET (IRF520), показанный на рисунке 2, используется для управления электродвигателем с редуктором. Этот модуль позволяет эффективно включать и отключать мотор, обеспечивая стабильное питание и защиту схемы.

3. На рисунке 3 представлен мотор с редуктором (brushes DC motor), который служит исполнительным устройством в проекте.

4. Дисплей TM1637 используется для отображения текущего времени.

5. Часы (DS3231) используется для точного отслеживания текущего времени, благодаря встроенному высокоточному кварцевому генератору.

Вы можете приобрести все необходимые компоненты отдельно от "Учебно-методический комплекс REPKA". Ссылки на модули приведены в таблице ниже.

Компонент Ссылка на приобретение
Монтажная/макетная плата Ссылка
Шлейф Ссылка
Переходник с шлейфа на макетную плату Ссылка
Соединительные провода

Провода соединительные м-п

Провода соединительные п-п

Провода соединительные п-п

Пассивный зуммер (Passive buzzer KY-006) Ссылка
Модуль MOSFET (IRF520) Ссылка
Мотор с редуктором (brushes DC motor) Ссылка
Дисплей TM1637 Ссылка
Часы (DS3231) Ссылка

Подготовительный этап

1. Подключим дополнительное питание 5V к макетной плате:

2. После чего выведем дополнительное питание на макетную плату:

3. Подключим переходник с шлейфа на макетную плату:

4. Соединим шлейф с переходником для подключения к макетной плате и Repka Pi 4:

5. Итоговый результат должен выглядеть таким образом:

Сборка проекта

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

Для разработки кода будет использоваться текстовый редактор Geany, который входит в состав стандартного ПО Репка ОС.

Электрическая принципиальная схема #

Монтажная схема #

  1. Подключение пассивного зуммера.

Обратимся к рисункам 6 и 7. Из них видно, что устройство подключается через GPIO22 и питается от 3.3V.

1.1. Выполним подключение к макетной плате согласно таблице 1.

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

Пассивный зуммер

3.3V

VCC

GPIO22

IO

GND

GND

Таблица 1. Подключение пассивного зуммера к макетной плате.

1.2. Результат подключения будет выглядеть следующим образом, см. рисунок 8:

2. Для проверки правильности подключения используем python скрипт из репозитория repka-pi_iot-examples.

2.1. Клонируем репозиторий:

git clone git@gitflic.ru:repka_pi/repka-pi_iot-examples.git

2.2. Переходим в репозиторий:

cd repka-pi_iot-examples/

2.3. Выполним установку зависимостей.

2.3.1. Если хотите установить зависимости только для зуммера, выполните:

make setup-KY-006

2.3.2. Если хотите установить зависимости для всех датчиков и проектов, выполните:

make setup-all

2.4. Запускаем скрипт для проверки работоспособности прибора:

make KY-006

2.4.1. Если нет никакой реакции, то проверьте номер GPIO указанный в скрипте по пути devices/executive/KY-006_example/py.

BEEP_PIN = 111  # Укажите номер пина, к которому подключен BEEP

2.4.2. Обратимся к пособию “УМК Репка. Учебно-методическое пособие”, в котором представлена распиновка Repka PI 4 (рисунок 9).  Из нее следует, что уникальный идентификатор порта GPIO22 равен 113.

2.4.3. Внесем правки в код и выполним скрипт.

BEEP_PIN = 113  # Укажите номер пина, к которому подключен BEEP

2.5. После запуска зуммер должен воспроизвести мелодию.

3. Подключим модуль MOSFET (IRF520).

Обратимся к рисункам 6 и 7. Из них видно, что MOSFET-модуль подключается к одноплатному компьютеру Repka PI 4 через управляющий вывод GPIO4, а питание на него подается от линии 5V. Важно отметить, что для обеспечения стабильной работы мотора питание 5V подаётся напрямую на входные контакты VIN и GND MOSFET-модуля. Такая схема подключения позволяет надежно управлять нагрузкой.

3.1. Выполним подключение к макетной плате согласно таблице 2.

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

MOSFET

Доп. питание 5V

5V

VCC

GND

GND

GPIO4

SIG

VIN

VIN

GND

GND

Таблица 2. MOSFET (IRF520).

3.2. Результат подключения будет выглядеть следующим образом, см. рисунок 10:

Проверку работоспособности MOSFET-модуля будем выполнять после подключения двигателя, чтобы убедиться в корректном управлении нагрузкой и правильной работе всей цепи управления мотором.

4. Подключение мотора с редуктором (brushes DC motor).

4.1. Подключение выполняется следующим образом: положительный (плюсовой) провод мотора следует соединить с клеммой V+ на MOSFET-модуле, а отрицательный (минусовой) провод — с клеммой V-.

4.2. Результат подключения будет выглядеть следующим образом, см. рисунок 11:

5. Проверку будем проводить аналогично пункту 2.

5.1. Если ранее не устанавливали все зависимости командой setup-all, то установим зависимости для дисплей  модуля, выполнив:

make setup-bushes-DC-motor

5.2. Далее изменим значение переменной PIN_R в соответствии с данными, приведенными на рисунке 9, в скрипте, расположенном по пути devices/executive/brushes_DC_motor_example:

PIN_R = 362

5.3. Запустим Python-скрипт командой:

make bushes-DC-motor

5.4. Если всё подключено правильно, мотор должен запуститься, вращая вал редуктор и издавая характерный звук работы двигателя.

6. Подключение дисплея TM1637.

Обратимся к рисункам 6 и 7. Из них видно, что дисплей подключается через интерфейс двухпроводной последовательной связи (CLK и DIO), используя GPIO17 и GPIO27, и питается от линии 5V одноплатного компьютера Repka PI 4.

6.1. Выполним подключение к макетной плате согласно таблице 3.

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

TM1637

5V

VCC

GND

GND

GPIO17

DIO

GPIO27

CLK

Таблица 3. Подключение TM1637 к макетной плате.

6.2. Результат подключения будет выглядеть следующим образом, см. рисунок 12:

7. Проверим подключение аналогично пункту 2.

7.1. Если ранее не устанавливали все зависимости командой setup-all, то установим зависимости для дисплей  модуля, выполнив:

make setup-tm1637

7.2. Запустим Python-скрипт командой:

make tm1637

7.3. Если всё подключено верно, на дисплее должна появится индикация:

8. Подключение часов (DS3231).

Как видно из рисунков 6 и 7 часы подключаются через интерфейс I2C и питаются от 5V.

8.1. Подключим DS3231 к макетной плате согласно таблице 4:

Макетная плата DS3231
5V VCC
GND GND
SDA1 SDA
SCL1 SCL

Таблица 4. Подключение DS3231 к макетной плате.

При использовании модуля часов форм-фактора, как у меня, подключение может быть затруднено из-за отсутствия полноценных подписей на разъёмах. Для удобства прилагаю изображение, которое поможет вам правильно осуществить подключение.

8.2. Результат подключения будет выглядеть следующим образом, см. рисунок 15:

9. Выполним проверку подключения прибора.

9.1. Установите зависимости для часов, если ранее не устанавливали все зависимости.

make setup-ds3231

9.2. После выполним python скрипт, расположенный по пути: /devices/input-output/ds3231_example, используя команду:

make ds3231

9.3. После успешного выполнения скрипта в консоли должна появится информация о времени, см. рисунок 16.

Запуск проекта

Теперь, когда все компоненты подключены, можно запустить проект "Умный будильник". Для этого в репозитории repka-pi_iot-examples выполняем команду:

make smart-clock

Мы можем наблюдать консольный интерфейс приложения, где с помощью команды set устанавливается время будильника. Также командой toggle можно включать или отключать будильник. Текущее время постоянно отображается на дисплее TM1637, обеспечивая удобный визуальный контроль.

При достижении установленного времени зуммер начинает издавать звуковой сигнал, а вибромотор активируется, создавая вибрацию.

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

Для более экономичной реализации проекта можно обойтись без активного охлаждения, используя стандартную комплектацию Repka Pi 4 и макетную плату без внешнего источника питания. Также нужно исключить использование модуля MOSFET и мотора с редуктором, так как они требуют дополнительного питания 5V.

Для подключения нам потребуется “Распиновка портов на 40 pin разъёме на Repka Pi 4“, см. рисунок 9.

Поскольку расширительная плата GPIO полностью повторяет конфигурацию распиновки, можно применить те же таблицы и схемы, которые использовались ранее для устройств:

10. Выполним подключение к макетной плате согласно таблице 1:

Проверка подключения зуммера осуществляется аналогично пункту 2.

11. Выполним подключение дисплея TM1637. к макетной плате согласно таблице 3:

Проверка подключения дисплея осуществляется аналогично пункту 7.

12. Подключим часы DS3231 к макетной плате согласно таблице 4:

Проверка подключения часов осуществляется аналогично пункту 7.

13. Подключим модуль MOSFET (IRF520) согласно таблице 2.

Внимание! Для подключения MOSFET используйте дополнительный источник питания, такой как лабораторный, аккумуляторный или батарейный блок, а не подключение через Repka Pi 4.

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

А. Подключение с использованием лабораторного блока питания:

Б. Подключение с использованием аккумуляторного блока питания:

Проверку работоспособности MOSFET-модуля будем выполнять после подключения двигателя, чтобы убедиться в корректном управлении нагрузкой и правильной работе всей цепи управления мотором.

14. Подключение мотора с редуктором (brushes DC motor).Подключение выполняется следующим образом: положительный (плюсовой) провод мотора следует соединить с клеммой V+ на MOSFET-модуле, а отрицательный (минусовой) провод — с клеммой V-:

Разбор кода проекта.

Проект реализован на языке python с использованием ООП подхода. Для того чтобы понять логику работы программы рассмотрите блок схему ниже:

Импортируются библиотеки для работы с GPIO, временем, датой, I2C (SMBus), многопоточностью.

from periphery import GPIO
from time import sleep
from datetime import datetime
from smbus2 import SMBus
import time
import threading

Далее инициализируются пины для зуммера и вибромотора, создаются объекты GPIO для управления этими устройствами.

# Пины для зуммера и MOSFET
BEEP_PIN = 113  # Пин для зуммера
PIN_R = 362  # Пин для MOSFET (вибромотор)

# Установка GPIO пинов для зуммера и MOSFET
beep = GPIO(BEEP_PIN, "out")
R = GPIO(PIN_R, "out")

Работа с RTC (DS3231)

Определяются адреса и регистры для работы с модулем реального времени по I2C.

Функция bcd2dec преобразует BCD-значения в десятичные.

Функция read_time читает текущее время с RTC и возвращает объект datetime.

def bcd2dec(bcd):
    """Преобразование BCD (Binary Coded Decimal) в целое число"""
    return (bcd >> 4) * 10 + (bcd & 0x0F)

def read_time(bus):
    """Чтение времени с модуля DS3231 (RTC)"""
    data = bus.read_i2c_block_data(DS3231_ADDR, REG_SECONDS, 7)
    sec = bcd2dec(data[0] & 0x7F)
    minute = bcd2dec(data[1])
    hour = bcd2dec(data[2] & 0x3F)
    day = bcd2dec(data[3])
    month = bcd2dec(data[5])
    year = 2000 + bcd2dec(data[6])

    try:
        return datetime(year, month, day, hour, minute, sec)
    except ValueError as e:
        print(f"Ошибка времени: {e}")
        return None  # Возвращаем None, если время некорректное

Управление зуммером и вибромотором

Функция beep_tone генерирует звук определённой частоты и длительности на зуммере.

Функция alarm_signal проигрывает тревожную последовательность звуков.

Функции turn_on и turn_off включают и выключают вибромотор через MOSFET.

def beep_tone(frequency, duration):
    """Генерация тонов для пассивного зуммера"""
    period = 1 / frequency
    half_period = period / 2
    end_time = time.time() + duration
    while time.time() < end_time:
        beep.write(True)
        time.sleep(half_period)
        beep.write(False)
        time.sleep(half_period)

def alarm_signal():
    """Имитация тревожного сигнала"""
    for _ in range(10):
        beep_tone(1000, 0.1)  # Быстрый короткий высокий сигнал
        time.sleep(0.05)      # Пауза
        beep_tone(2000, 0.1)  # Быстрый короткий высокий сигнал
        time.sleep(0.05)      # Пауза
    time.sleep(0.5)

def turn_on():
    """Включение вибромотора через MOSFET"""
    R.write(True)

def turn_off():
    """Выключение вибромотора через MOSFET"""
    R.write(False)

Класс TM1637

Инкапсулирует работу с 4-разрядным 7-сегментным дисплеем TM1637 через два GPIO-пина.

  • set_segments: отображает массив сегментов на дисплее

  • show_time: отображает часы и минуты, может мигать двоеточием

  • hex_digit_to_segment: преобразует цифру в битовую маску сегмента

  • close: освобождает пины

# Дисплей TM1637
class TM1637:
    def __init__(self, clk, dio, brightness=0xA):
        self.clk = clk
        self.dio = dio
        self.brightness = brightness
        self.gpio_clk = GPIO(self.clk, "out")
        self.gpio_dio = GPIO(self.dio, "out")

    def set_segments(self, segments, pos=0):
        """Отображение сегментов на дисплее"""
        self.start()
        self.write_byte(0x40)  # COMM1
        self.stop()

        self.start()
        self.write_byte(0xC0 + pos)  # COMM2
        for seg in segments:
            self.write_byte(seg)
        self.stop()

        self.start()
        self.write_byte(0x80 + self.brightness)  # COMM3
        self.stop()

    def start(self):
        """Запуск передачи данных на дисплей"""
        self.gpio_clk.write(True)
        self.gpio_dio.write(True)
        self.gpio_dio.write(False)
        self.gpio_clk.write(False)

    def stop(self):
        """Завершение передачи данных на дисплей"""
        self.gpio_clk.write(False)
        self.gpio_dio.write(False)
        self.gpio_clk.write(True)
        self.gpio_dio.write(True)

    def write_byte(self, data):
        """Запись байта данных на дисплей"""
        for i in range(8):
            self.gpio_clk.write(False)
            if data & 0x01:
                self.gpio_dio.write(True)
            else:
                self.gpio_dio.write(False)
            data >>= 1
            self.gpio_clk.write(True)

        self.gpio_clk.write(False)
        self.gpio_dio.write(True)
        self.gpio_clk.write(True)

    def show_time(self, hour, minute, blink_colon=False):
        """Отображение времени на дисплее TM1637 с мигающими двоеточиями"""
        segments = [0, 0, 0, 0]
        segments[0] = self.hex_digit_to_segment(hour // 10)
        segments[1] = self.hex_digit_to_segment(hour % 10)
        segments[2] = self.hex_digit_to_segment(minute // 10)
        segments[3] = self.hex_digit_to_segment(minute % 10)
        
        if blink_colon:
            segments[1] |= 0x80  # Добавляем точку в сегмент для двоеточия

        self.set_segments(segments)

    def hex_digit_to_segment(self, digit):
        """Преобразование цифры в сегмент для TM1637"""
        hex_digits = [
            0b0111111,  # 0
            0b0000110,  # 1
            0b1011011,  # 2
            0b1001111,  # 3
            0b1100110,  # 4
            0b1101101,  # 5
            0b1111101,  # 6
            0b0000111,  # 7
            0b1111111,  # 8
            0b1101111,  # 9
        ]
        return hex_digits[digit]

    def close(self):
        """Закрытие GPIO пинов для дисплея"""
        self.gpio_clk.close()
        self.gpio_dio.close()

Класс AlarmClock (логика будильника)

Хранит время и состояние будильника:

class AlarmClock:
    def __init__(self):
        self.alarm_hour = 13
        self.alarm_minute = 18
        self.alarm_active = True

Устанавливает новое время будильника:

    def set_alarm(self, hour, minute):
        self.alarm_hour = hour
        self.alarm_minute = minute
        self.alarm_active = True
        print(f"Будильник установлен на {hour}:{minute}") 

Включает/выключает будильник:

    def toggle_alarm(self):
        self.alarm_active = not self.alarm_active
        state = "включен" if self.alarm_active else "выключен"
        print(f"Будильник {state}")

Если время совпало и будильник активен — проигрывает сигнал и включает вибромотор на 10 секунд:

    def check_alarm(self, hour, minute):
        if self.alarm_active and hour == self.alarm_hour and minute == self.alarm_minute:
            alarm_signal()
            turn_on()
            sleep(10)

Основной цикл main

  • Считывает время с RTC

  • Отображает его на дисплее

  • Проверяет, не пора ли сработать будильнику

  • Мигает двоеточием

def main(alarm_clock):
    tm = TM1637(112, 111)
    with SMBus(I2C_BUS) as bus:
        blink_colon = False
        while True:
            current_time = read_time(bus)
            tm.show_time(current_time.hour, current_time.minute, blink_colon)
            alarm_clock.check_alarm(current_time.hour, current_time.minute)
            blink_colon = not blink_colon
            sleep(1)

Функция command_line_interface (консольный интерфейс)

Позволяет пользователю через консоль:

  • set [hour] [minute] — установить время будильника

  • toggle — включить/выключить будильник

  • exit — завершить программу

def command_line_interface(alarm_clock):
    while True:
        command = input("Введите команду (set [hour] [minute], toggle, exit): ").strip()
        if command.startswith("set"):
            try:
                _, hour, minute = command.split()
                hour, minute = int(hour), int(minute)
                alarm_clock.set_alarm(hour, minute)
            except ValueError:
                print("Некорректный ввод времени!")
        elif command == "toggle":
            alarm_clock.toggle_alarm()
        elif command == "exit":
            print("Выход из программы...")
            break
        else:
            print("Неизвестная команда. Доступные команды: set, toggle, exit.")

Точка входа

if __name__ == "__main__":
    alarm_clock = AlarmClock()
    threading.Thread(target=command_line_interface, args=(alarm_clock,), daemon=True).start()
    main(alarm_clock)

Результат:

Программа реализует умные часы с будильником:

  • Показывает текущее время на 7-сегментном дисплее

  • Позволяет управлять будильником через консоль (в отдельном потоке)

  • В нужное время подаёт звуковой и вибросигнал

  • Работает в двух потоках: основной цикл и интерфейс командной строки

Практическая значимость проекта

Проект «Умный будильник» на базе одноплатного компьютера Repka PI 4 обладает высокой практической значимостью как для образовательных, так и для бытовых целей. Он позволяет на практике изучить интеграцию различных периферийных модулей — часов реального времени, дисплея, звукового и тактильного оповещения, а также управления исполнительными устройствами через MOSFET. Такой проект помогает понять принципы работы встраиваемых систем, основы электроники и программирования в реальном времени.

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

Расширение проекта

Проект «Умный будильник» можно расширить, добавив дополнительные функции и возможности, которые повысят его удобство и практическую пользу. Например, можно интегрировать датчики окружающей среды, такие как датчики температуры и влажности, чтобы устройство могло учитывать комфортные условия для пробуждения и адаптировать работу будильника в зависимости от этих параметров. Также возможно добавить подключение к сети Интернет или мобильным устройствам, что позволит управлять будильником дистанционно через приложение и получать уведомления. Для улучшения взаимодействия с пользователем можно реализовать более сложные сценарии оповещения — например, постепенное увеличение громкости звука или вибрации, а также возможность выбора различных мелодий или звуков. Интерфейс управления можно дополнить сенсорными экранами или даже голосовым управлением, что сделает использование устройства более интуитивным и современным. Кроме того, можно внедрить энергоэффективные режимы работы и автономное питание, чтобы будильник мог функционировать длительное время без подключения к электросети. Все эти улучшения превратят проект из учебного примера в полноценное устройство с широкими возможностями для повседневного использования.

Видеообзор проекта

Для более детального ознакомления с проектом, вы можете посмотреть видеообзор на платформе Rutube:

Пример использования с Python

Проект полностью реализован на языке Python. Код для работы с умным будильником можно найти в репозитории на платформе Gitflic.


Комментарии (0)

Для участия в обсуждении Вы должны быть авторизованным пользователем

Еще посты по теме

Новые посты



Темы

Навигация

ВойтиРегистрация