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

Проект “Сигнализация” на базе одноплатного компьютера Repka PI 4.

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

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

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

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

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

  1. Зуммер пассивный модуль (Passive buzzer KY-006) — для подачи звуковых сигналов при обнаружении активности датчиком движения, см. рисунок 1.

    2. Датчик движения AM312 используется для детектирования активности в окружающем пространстве.

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

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

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

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

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

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

Зуммер пассивный модуль (Passive buzzer KY-006) Ссылка
Датчик движения AM312 Ссылка
Матрица 8x8 красных светодиодов (MAX7219) Ссылка

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

5V

VCC

GPIO17

IO

GND

GND

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

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

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”, в котором представлена распиновка Repka PI 4 (рисунок 7).  Из нее следует, что уникальный идентификатор порта GPIO17 равен 111.

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

3. Подключение датчика движения AM312.

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

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

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

AM312

5V

VCC

GPIO17

IO

GND

GND

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

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

4. Аналогично пункту 2 выполним проверку подключения датчика.

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

make setup-am312

4.2. Запустим python скрипт, который находится по пути devices/sensors/AM312_example/py:

make am312

4.2.1. Если нет реакции, проверьте номер GPIO, указанный в скрипте, и убедитесь, что он соответствует вашему подключению. Измените уникальный идентификатор GPIO в коде, чтобы он совпадал с тем, который указан на схеме подключения (рисунок 7).

PIN1 = 111

4.3. При правильном подключении, после выполнения скрипта в консоли вы увидите количество срабатываний датчика, как показано на рисунке 9. Это позволит вам отслеживать, как часто датчик фиксирует движение или изменение активности в своей зоне наблюдения.

5. Подключение матрица (MAX7219).

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

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

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

MAX7219

5V

VCC

GND

GND

SPIMOSI

DIN

SPICEO

CS

SPISCLK

CLK

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

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

6. Аналогично пункту 2 выполним проверку подключения устройства.

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

make setup-max7219cng

6.2. Запустим python скрипт, который находится по пути devices/input-output/max7219_luma_example:

make max7219cng

6.3. Если все подключено верно, то на матрице должно появиться приветственное сообщение, см. рисунок 11.

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

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

make signal-folder

После запуска в консоли отобразится информация о срабатывании датчика и движении (см. рисунок 12). Затем зуммер издаст громкий звук, а матрица начнёт мигать. Если движение не будет обнаружено в течение 5 секунд, система автоматически выключится.

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

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

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

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

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

8. Подключение датчика движения AM312. Выполним подключение к макетной плате согласно таблице 2:

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

9.1. Подключение матрицы (MAX7219). Выполним подключение к макетной плате согласно таблице 3.

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

Для снижения нагрузки на линию 5 В одноплатного компьютера Repka Pi 4, рекомендуется использовать дополнительное питание 5 В:

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

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

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

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

Импортируются необходимые библиотеки: для работы с GPIO, временем, потоками, SPI-интерфейсом, LED-матрицей и шрифтами:

from periphery import GPIO
import time
import threading
from luma.core.interface.serial import spi, noop
from luma.led_matrix.device import max7219
from luma.core.render import canvas
from PIL import ImageFont

Инициализация пина для датчика движения (PIR-сенсор) как вход:

PIN1 = 362  # GPIO17
msi = GPIO(PIN1, "in")

Инициализация пина для зуммера как выход:

BEEP_PIN = 111  # Укажите номер пина для зуммера
beep = GPIO(BEEP_PIN, "out")

Настройка SPI-интерфейса и инициализация LED-матрицы max7219, установка яркости:

serial = spi(port=0, device=0, gpio=noop())
device = max7219(serial, cascaded=1, block_orientation=0, rotate=0)
device.contrast(16)  # Яркость матрицы

Функция alarm_signal для генерации звука на зуммере с заданной частотой и длительностью:

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)

Функция blink_matrix мигает всей матрицей 5 раз:

def blink_matrix():
    # Мигающий текст на матрице
    for _ in range(5):  # Мигание 5 раз
        with canvas(device) as draw:
            draw.rectangle(device.bounding_box, outline="black", fill="black")  # Очищаем экран
        time.sleep(0.2)
        with canvas(device) as draw:
            draw.rectangle(device.bounding_box, outline="white", fill="white")  # Заполняем экран белым
        time.sleep(0.2)

Функция show_on_matrix отображает заданный текст по центру матрицы, используя выбранный шрифт.

def show_on_matrix(text):
    font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 8)
    bbox = font.getbbox(text)
    w, h = bbox[2] - bbox[0], bbox[3] - bbox[1]
    offset_y = bbox[1]
    x = (device.width  - w) // 2
    y = (device.height - h) // 2 - offset_y

    with canvas(device) as draw:
        draw.text((x, y), text, font=font, fill="white")

Функция motion_detected_action запускает тревожный сигнал и мигание матрицы параллельно в отдельных потоках, затем ждёт их завершения:

def motion_detected_action():
    # Запускаем тревожный сигнал и мигание матрицы одновременно
    alarm_thread = threading.Thread(target=alarm_signal)
    matrix_thread = threading.Thread(target=blink_matrix)
    
    alarm_thread.start()
    matrix_thread.start()
    
    alarm_thread.join()  # Ожидаем завершения тревожного сигнала
    matrix_thread.join()  # Ожидаем завершения мигания матрицы

Основной цикл программы:

  • Ждёт срабатывания датчика движения.

  • Если движение обнаружено — запускает тревожный сигнал и мигание матрицы, обновляет время последнего движения.

  • Если движения не было 5 секунд — выключает зуммер, очищает матрицу, сбрасывает флаг.

  • Каждые 0.1 секунды проверяет состояние датчика.

  • При завершении работы освобождает ресурсы (закрывает пины).

try:
    print("Ожидание срабатывания датчика. Нажми Ctrl+C для выхода.")
    last_motion_time = time.time()  # Время последнего движения
    motion_detected = False

    while True:
        if msi.read():  # Если движение обнаружено
            motion_detected = True
            last_motion_time = time.time()  # Обновляем время последнего движения
            print("Датчик сработал!")
            motion_detected_action()  # Запуск действия при движении
        else:
            if motion_detected and time.time() - last_motion_time > 5:  # Если движение не было 5 секунд
                print("Движение не обнаружено 5 секунд, затухаем...")
                beep.write(False)  # Выключаем зуммер
                with canvas(device) as draw:  # Очищаем экран матрицы
                    draw.rectangle(device.bounding_box, outline="black", fill="black")
                motion_detected = False  # Сбрасываем флаг

        time.sleep(0.1)  # Пауза перед следующим циклом

except KeyboardInterrupt:
    print("Завершение программы")

finally:
    beep.close()  # Закрываем зуммер

Пример кода выше с использованием ООП

Объявляется основной класс SignalFolderDemo. Внутри класса определяются константы для номеров пинов датчика движения и зуммера:

class SignalFolderDemo:
    # Константы для пинов
    PIN1 = 362  # GPIO17 для датчика движения
    BEEP_PIN = 111  # Пин для зуммера

Конструктор класса. Здесь инициализируются все устройства: датчик движения, зуммер, SPI-интерфейс и LED-матрица. Также задаются переменные состояния для отслеживания времени последнего движения и флага обнаружения движения:

    def __init__(self):
        # Инициализация датчика движения
        self.msi = GPIO(self.PIN1, "in")
        # Инициализация зуммера
        self.beep = GPIO(self.BEEP_PIN, "out")
        # Инициализация SPI интерфейса и матрицы
        self.serial = spi(port=0, device=0, gpio=noop())
        self.device = max7219(self.serial, cascaded=1, block_orientation=0, rotate=0)
        self.device.contrast(16)  # Яркость матрицы
        # Состояния
        self.last_motion_time = time.time()  # Время последнего движения
        self.motion_detected = False

Метод alarm_signal для генерации звука на зуммере с заданной частотой и длительностью. Включает и выключает зуммер с нужным интервалом:

    # Тревожный сигнал (чередование двух тонов)
    def alarm_signal(self):
        for _ in range(10):
            self.beep_tone(1000, 0.1)
            time.sleep(0.05)
            self.beep_tone(2000, 0.1)
            time.sleep(0.05)
        time.sleep(0.5)

Метод show_on_matrix отображает заданный текст по центру матрицы, используя выбранный шрифт:

    # Отображение текста на матрице
    def show_on_matrix(self, text):
        font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 8)
        bbox = font.getbbox(text)
        w, h = bbox[2] - bbox[0], bbox[3] - bbox[1]
        offset_y = bbox[1]
        x = (self.device.width  - w) // 2
        y = (self.device.height - h) // 2 - offset_y
        with canvas(self.device) as draw:
            draw.text((x, y), text, font=font, fill="white")

Метод blink_matrix для мигания всей матрицей 5 раз:

 # Мигающий дисплей
    def blink_matrix(self):
        for _ in range(5):
            with canvas(self.device) as draw:
                draw.rectangle(self.device.bounding_box, outline="black", fill="black")
            time.sleep(0.2)
            with canvas(self.device) as draw:
                draw.rectangle(self.device.bounding_box, outline="white", fill="white")
            time.sleep(0.2)

Метод motion_detected_action запускает тревожный сигнал и мигание матрицы параллельно в отдельных потоках, затем ждёт их завершения:

    # Параллельный запуск тревоги и мигания
    def motion_detected_action(self):
        alarm_thread = threading.Thread(target=self.alarm_signal)
        matrix_thread = threading.Thread(target=self.blink_matrix)
        alarm_thread.start()
        matrix_thread.start()
        alarm_thread.join()
        matrix_thread.join()

Основной цикл программы:

  • Ждёт срабатывания датчика движения.

  • Если движение обнаружено — запускает тревожный сигнал и мигание матрицы, обновляет время последнего движения.

  • Если движения не было 5 секунд — выключает зуммер, очищает матрицу, сбрасывает флаг.

  • Каждые 0.1 секунды проверяет состояние датчика.

  • При завершении работы освобождает ресурсы (закрывает пины).

       # Основной цикл работы
        def run(self):
            try:
                print("Ожидание срабатывания датчика. Нажми Ctrl+C для выхода.")
                self.last_motion_time = time.time()
                self.motion_detected = False
                while True:
                    if self.msi.read():  # Если движение обнаружено
                        self.motion_detected = True
                        self.last_motion_time = time.time()
                        print("Датчик сработал!")
                        self.motion_detected_action()
                    else:
                        if self.motion_detected and time.time() - self.last_motion_time > 5:
                            print("Движение не обнаружено 5 секунд, затухаем...")
                            self.beep.write(False)
                            with canvas(self.device) as draw:
                                draw.rectangle(self.device.bounding_box, outline="black", fill="black")
                            self.motion_detected = False
                    time.sleep(0.1)
            except KeyboardInterrupt:
                print("Завершение программы")
            finally:
                self.beep.close()
                self.msi.close()
    

    Точка входа: создаётся экземпляр класса и запускается основной цикл:

if __name__ == "__main__":
    demo = SignalFolderDemo()
    demo.run()

Преимущества ООП-подхода:

1. Модульность и повторное использование кода

В ООП каждая функциональная часть системы (например, работа с датчиком, реле, дисплеем) оформляется в виде отдельного класса.

Это позволяет легко переиспользовать эти классы в других проектах или расширять функциональность без переписывания кода.

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


2. Упрощение поддержки и масштабирования

Код, разделённый на классы с чётко определённой ответственностью, проще читать, тестировать и отлаживать.

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

Это особенно важно для сложных или развивающихся проектов, где часто появляются новые требования.


3. Инкапсуляция и защита данных

ООП позволяет скрыть внутренние детали реализации (например, работу с I2C или обработку ошибок) внутри класса.

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

Это снижает вероятность ошибок, связанных с неправильным использованием компонентов, и делает интерфейс системы более понятным и безопасным.

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

Проект "Сигнализация" на базе одноплатного компьютера Repka PI 4 имеет высокую практическую значимость, поскольку представляет собой эффективную и доступную систему безопасности, которая может быть использована для создания автономных охранных решений. Этот проект позволяет продемонстрировать возможности интеграции различных компонентов, таких как датчик движения, зуммер и светодиодная матрица, с использованием одноплатного компьютера. Важно, что система позволяет мгновенно реагировать на движение, что делает её полезной в различных областях, включая защиту жилых и коммерческих объектов.

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

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

Проект может быть расширен в несколько направлений:

  1. Добавление удалённого управления и мониторинга: Включение модуля Wi-Fi или Ethernet позволит подключить систему к интернету, что откроет возможность для удалённого мониторинга и получения уведомлений на мобильные устройства или электронную почту при срабатывании сигнализации.

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

  3. Интеграция с системами "умного дома": Система сигнализации может быть интегрирована с другими компонентами "умного дома" (освещением, камерами видеонаблюдения и т.д.), что позволит создать полностью автоматизированную безопасность для дома или офиса.

  4. Разработка пользовательского интерфейса: Для удобства эксплуатации можно разработать мобильное приложение или веб-интерфейс для управления и настройки системы сигнализации, а также просмотра истории срабатываний.

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

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

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

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


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

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

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

Новые посты



Темы

Навигация

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