Как мы делали небольшую охранную систему на RPi. Часть 1

    Здравствуйте Хабражители!

    Думаю многие из вас слышали о Raspberry Pi, более того, думаю довольно большое количество из вас видели его вживую. В начале 2014 года я решил, что пора мне тоже заказать себе парочку RPi и сделать на них что-то интересное. Так как я являюсь iOS разработчиком, я загорелся идеей обязательно прицепить к этому проекту iOS приложение. Ну и т.к. RPi довольно хорошо умеет работать со сторонним железом, я решил что сделаю небольшую охранную систему для личного пользования.





    Введение


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



    Примерно через месяц я получил из UK два RPi модели A, т.е. с одним USB, и без Ethernet. Прикупил флэшку на 16Гб и установил на нее Raspbian. И тут начали всплывать первые из подводных камней — драйвера и интернет. У меня уже был выигранный на конкурсе пару лет назад 3G роутер, и именно его я планировал подключить к RPi, для того, чтобы там появился интернет. Как же я ошибался.

    Через полчаса я уже стоял в магазине в поисках адаптера USB-Ethernet, продавец с трудом нашел мне один экземпляр компании D-Link. Перед самым выходом я решил подстраховаться и купить еще и wifi адаптер компании ASUS, т.к. время было позднее, а начать работу сильно хотелось именно сегодня, поэтому права на ошибку просто небыло. На обоих девайсах естественно красовалась поддержка Linux.




    Придя домой я убил добрый час в попытках установить с диска, а потом найти в интернете свежие драйвера для D-Link. Оказалось, что ребята из этой компании просто перестали поддерживать это устройство 2 года назад! Я понял, что мне продали барахло (которое я успешно на следующий день поменял на еще две флэшки). Остался план Б, который заработал на удивление без всяких драйверов, я просто вставил адаптер от ASUS в USB и он сразу же определился в системе как сетевая карта. Сразу скажу, работать на RPi model A в режиме графической оболочки просто невозможно, все очень сильно тормозит, после макбука с SSD это про ад. Поэтому я решил его не мучать, просто настроил себе ssh.

    Далее встал вопрос о языке, на котором я буду писать систему для работы с железом. Из всех я выбрал Python, так как там есть работа с железом «из коробки», не нужно дополнительно устанавливать ни каких библиотек и тому подобного, ну и плюс я давно хотел изучить этот язык.

    Примерно за неделю я освоил все что мне было нужно от Python, это была очень интересная неделя. Помните в 9 эпизоде первого сезона «Теории большого взрыва» главные герои приделали к некоторым приборам в своей квартире выключатели, которыми можно было управлять через интернет, и любой желающий мог включить/выключить у них свет или аудио систему? Я сделал тоже самое со светодиодом, подключенным к RPi. Это конечно не аудио система, но когда светодиод загорался от щелчка мыши на противоположном полушарии планеты, ощущения были непередаваемые :)



    Работа с железом


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

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

    Более подробно о работе схемы я расскажу в другой статье, а пока вкратце расскажу про то, как все устроено.



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

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

    Для подключения и питания всей схемы были сделаны две отдельные платы, на одной была реализована работа с железом через оптроны, а на другой преобразование сетевого напряжения 220В в постоянное 12В и 5В. От 12В у нас питаются датчики и сирена, а от 5В соответственно RPi.

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



    GPIO имеет 26 контактов, из них: 2 по 5В, 2 по 3В, 5 земля, остальные могут быть как входами, так и выходами, в зависимости от конфигурации, которую вы задаете.



    Программированию системы работы с железом


    Я решил сделать трехзвенную архитектуру: RPi — Web Server — iOS. Во-первых, чтобы повысить отказоустойчивость, т.к. если исключить сервер из цепочки, то вся система становится очень уязвима из-за того, что RPi может выйти из строя и мы ни как не узнаем об этом. Во-вторых, я решил отказаться от посылки смс и дозвона в пользу push-уведомлений, которые конечно же будет слать сервер.

    Итак, для программирования системы работы с железом я выбрал Python 2.5. Первое, что нужно сделать, это установить WebIOPi. Это отличный open-source проект, который позволяет удобно отлаживать работу с оборудованием через браузер. Он показывает статус портов GPIO, позволяет их сконфигурировать на вход/выход и установить вручную на выходе 0 или 1. Устанавливается все это очень просто, на просторах интернета даже есть подробная инструкция на русском языке.

    Как я писал выше, в Python «из коробки» есть работа с GPIO, для этого надо просто подключить специальную библиотеку.

    import RPi.GPIO as GPIO


    GPIO имеет два режима нумерации контактов, по счету на плате и по внутреннему номеру контакта. Я рекомендую использовать нумерацию по счету, это просто проще.

    GPIO.setmode(GPIO.BOARD)


    Перед запуском системы нам нужно инициализировать все нужные порты, а именно указать как они будут работать, на вход или на выход, а так же указать начальное значение порта.

    GPIO.setup(12, GPIO.OUT, initial=GPIO.LOW)
    GPIO.setup(11, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
    


    Для считывания порта нужно использовать следующий код:

    if (GPIO.input(11) == GPIO.HIGH)


    Для установки на выходе порта 1 или 0:

    GPIO.output(12, GPIO.HIGH)
    GPIO.output(12, GPIO.LOW)
    


    Так как датчик движения выдает сигнал на очень короткий промежуток времени, нам нужно считывать порты постоянно, и тут надо сказать, что в RPi.GPIO это реализуется очень удобно. Можно сделать так, чтобы при получении на входе 1 или 0 вызывалась определенная функция. Так же для каждого порта устанавливается частота считывания.

    GPIO.add_event_detect(11, GPIO.FALLING, callback=move_sensor_callback, bouncetime=500)
    


    Несколько важных подводных камней. В цикле программы обязательно нужно сделать sleep(1), иначе процессор будет всегда загружен на 100%, так же при выходе из программы рекомендуется выполнять GPIO.cleanup().

    try:
        while True:
            sleep(1)
    finally:
    	GPIO.cleanup()
    


    Далее расскажу про еще более странную проблему, причины которой я не нашел, но нашел вполне адекватный выход. Примерно через 6 часов непрерывной работы скрипт перестает реагировать на сенсоры. Скорее всего отваливается та самая удобная система, которая вызывает callback функции при наступлении определенного события. Решается это очень просто, скрипт нужно иногда перезагружать, например с помощью cron’а. Для большей надежности, в моей системе cron перезагружает скрипт каждый час, плюс каждую минуту он проверяет работает ли скрипт и запускает его, если это не так.

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

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

    Самодиагностика делается довольно просто, при инициализации все железо должно иметь на выходе единицу, поэтому если мы имеем там ноль, значит датчик не работает или находится не в замкнутом положении (геркон). Соответственно вся система построена на том, что датчики имеют 1 в спокойном состоянии, и соответственно 0, когда они срабатывают или что-то ломается.

    Вообще система состоит из 4-х датчиков: датчик движения 360°, датчик дыма, 2 геркона. Ну и конечно же сирена, звонкая, автомобильная, в замкнутом помещении просто ломает уши.

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

    Ну и в завершение небольшой спойлер ко второй части :)

    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 19

      +2
      На будущее: совместимость устройств с малиной можно посмотреть тут.
        0
        Спасибо за ссылку!
        +1
        DUB-E100 использовал лично с RPi для раздачи интернета. Поддержка ASIX AX88772 (на котором сделан DUB-E100) есть в ядре.
        Последние драйвера на это устройство вышли в течении года и оно поддерживается . Зачем вы незаслуженно обижаете устройство?

        Использовать макетку в собранном устройстве — вообще несерьезно.
          0
          Хм, значит я что-то не так сделал, раз оно у меня не определилось в системе. Я не захотел дальше возиться с ним после того, как наткнулся в интернете на сообщение представителя D-Link о том, что они не собираются больше делать драйвера для этого устройства.

          Использовать макетку в собранном устройстве — вообще несерьезно.

          Я не профи в железе, что посоветуете использовать?
            +2
            Если хотите связаться с электроникой то стоит осилить создание печатных плат (например ЛУТ).

            А так стоит осилить хотя бы навесной монтаж, выглядеть это может примерно так:
            image
              0
              Понял, спасибо.
            –4
            >Использовать макетку в собранном устройстве — вообще несерьезно
            Это сейчас было сказано не очень серьезно, правда же?
              +3
              Я серьезно считаю что использовать доску для прототипирования (макетку) стоит во время прототипирования и тестирования, готовое устройство собирать уже на плате.
            0
            Скажите а что за аккумулятор в итоге стоит в системе?
              0
              Delta DT 1207. Вот тут полное описание, в том числе про работу в буферном режиме написано.
                +1
                А как его подключить к 220 и чтоб сам отключался/заряжался?
                  0
                  Отвечу цитатой:
                  При буферном режиме работы аккумуляторная батарея постоянно подключена к зарядному устройству и нагрузке. После зарядки аккумуляторная батарея в течение продолжительного времени находится под действием конечного напряжения зарядки. После достижения необходимого значения напряжения на батарее зарядный ток начинает падать и уменьшается до значения, компенсирующего саморазряд АБ, поддерживая батарею в полностью заряженном состоянии. При пропадании напряжения в сети, АБ разряжается на подключенную нагрузку.


                  Насколько я понял аккумулятор просто включается в цепь параллельно. Видимо по такому же принципу работают автомобильные аккумуляторы.
              0
              Тоже собирал что-то подобное, на базе Arduino + rPi + AppEngine + Android. Единственное замечание: не учитывается ситуация когда внезапно отключается свет, случайно или злонамеренно. Таким образом, нужно запасное питание + серверный watchdog который поднимет тревогу если не было heartbeats от охранной системы в течении какого-то времени.
                0
                В моем случае в помещении, где стоит эта охранная система, питание отключается ежедневно на всю ночь, так что тут аккумулятор был просто необходим с самого начала. Кстати про watchdog и другие серверные плюшки расскажу в следующей статье :)
                +1
                Скажите, вы случайно не мой двойник? :)
                1. Я тоже недавно начал серьезно играться с RPi, и тоже хочу сделать из нее что-нибудь полезное
                2. Я тоже недавно заинтересовался схемотехникой, и жду-не дождусь полутора десятков посылок из Китая с компонентами
                3. Я тоже начал лепить контролирующую систему (тоже на Python), первое рабочее название которой было… Alice :D

                И да, мобильное приложение тоже в роадмапе :)
                  +2
                  Могу ответить не скромно: умные люди думают одинаково :D
                    +2
                    Ой, да ладно вам, после первого обителя зла каждый второй домашний сервер, компьютер или головное устройство умного дома Alice называют :)

                    Я кстати тоже недавно начал играть с RPi + Python, но у меня робот машинка и там еще есть Arduino как низкоуровневый контроллер железа :)
                  0
                  А какой софт такие диаграммы рисует?
                    0
                    Если вопрос о карте мыслей, то я лично пользуюсь MindNode Pro.

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

                  Самое читаемое