СКУД, малина и чайник

в 21:48, , рубрики: Raspberry Pi, RFID

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

В виде наличия множество разнообразной информации в интернете с не совсем рабочими примерами, постараюсь описать все пошагово и подробно. Данный модуль работает с RFID картами на частоте 13,56 МГц и легко понимает кроме карт и чипов с такой частотой, ещё и единые проездные билеты Москвы (я использовал использованный одноразовый единый билет), а также NFC-метки.

Hardware

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

Схема подключения модуля

image

Для проверки работы модуля я использовал несколько диодов и пьезодинамик. Красный и зеленый диоды — для индикации состояния работы условного замка (красный — замок закрыт, зеленый — замок открыт), желтый диод — для индикации управляющего сигнала (в реальных условиях будет заменен на замок), пьезодинамик — подает звуковой сигнал во время открытия замка и сигнализирует об ошибке. В реальной схеме с замком целесообразно использовать реле для управления цепью питания замка.

Схема подключения диодов и динамика

image

Software

Для начала необходимо включить SPI на Raspberry, если не включен. Как это сделать, написано здесь.
Теперь можно скачать библиотеку для работы с нашим модулем и проверить чтение и запись карт. Для нас важно чтение, в частности чтение UID карты, для этого вводим в консоли:

git clone https://github.com/mxgxw/MFRC522-python

Для корректной работы скачанного кода необходимо также скачать и установить SPI-py:

git clone https://github.com/lthiery/SPI-Py
sudo python /SPI-Py/setup.py install

Теперь можно считывать UID карты и записанную в неё информацию. Для этого запускаем их загруженных нами файлов пример:

cd MFRC522-python
sudo python Read.py

На экране должно появиться:

Welcome to the MFRC522 data read example
Press Ctrl-C to stop.

После этого можно поднести к считывателю карточку или метку и мы увидим её UID

Card detected
Card read UID: 60,56,197,101
Size: 8
Sector 8 [12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

В данном случае нас интересует эта часть: UID: 60,56,197,101.
А эту часть мы можем изменять

Заголовок спойлера

, заменяя нули нужными нам значениями: Sector 8 [12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], но это нас сейчас не интересует.

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

Скрипт с моими комментариями
#!/usr/bin/env python

import RPi.GPIO as GPIO
import MFRC522
import signal
import time

red = 11
green = 18
speaker = 16
doorlock = 12

# Список UID карт (UID карты узнаем с помощью sudo python /MFRC522-python/Read.py
card_01 = '6056197101' #white
card_02 = '148167101184' #fob
card_03 = '13652116101' #единый

#Настройка портов вывода
GPIO.setmode(GPIO.BOARD) # Это значит, что считаем пины по порядку с левого верхнего (3v3 - первый)
GPIO.setup(red, GPIO.OUT, initial=1) # Устанавливаем пин 18 на вывод
GPIO.setup(green, GPIO.OUT, initial=0) # тоже самое с пином 11
GPIO.setup(speaker, GPIO.OUT, initial=0) # пин 16
GPIO.setup(doorlock, GPIO.OUT, initial=0) # пин 12

continue_reading = True

def end_read(signal,frame): # что делать, если программу прервать и как её прервать
    global continue_reading
    print "Ctrl+C captured, ending read."
    continue_reading = False
    GPIO.cleanup()

# Create an object of the class MFRC522 (??)
MIFAREReader = MFRC522.MFRC522()

while continue_reading:

# Сканируем карты - считываем их UID
    (status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)

    # Если карту удалось считать, пишем "карта найдена"
    if status == MIFAREReader.MI_OK:
        print "Card detected"

    # Считываем UID карты
    (status,uid) = MIFAREReader.MFRC522_Anticoll()

    # Если считали UID, то идем дальше
    if status == MIFAREReader.MI_OK:
        # выводим UID карты на экран
        UIDcode = str(uid[0])+str(uid[1])+str(uid[2])+str(uid[3])
        print UIDcode

        # Если карта есть в списке
        if UIDcode == card_01 or UIDcode == card_03 or UIDcode == card_02:
        # то дверь открывается
        # предполагается, что замок открывается при подаче на
        # него (на реле, управляющее замком), напряжения
        # т.е. им управляет переключаемое реле
        # т.е. замок открывается при высоком значении пина doorlock
        # при этом, горит зеленая, тухнет красная и пищит динамик

                GPIO.output((red, green, speaker, doorlock), (0,1,1,1))
                print "Door open"

                # успеть дернуть за 1 секунду
                time.sleep(1)
                GPIO.output((red, green, speaker, doorlock), (1,0,0,0))

                # потом дверь закрывается, о чем нас извещают
                print "Door closed"

        # А если карты в списке нет, то моргаем и пищим
        else:
                GPIO.output((red, green, speaker, doorlock), (1,0,0,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (1,0,1,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (1,0,0,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (1,0,1,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (0,1,0,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (0,1,1,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (0,1,0,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (0,1,1,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (1,0,0,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (1,0,1,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (1,0,0,0))
                time.sleep(0.05)
 		GPIO.output((red, green, speaker, doorlock), (1,0,1,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (0,1,0,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (0,1,1,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (0,1,0,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (0,1,1,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (1,0,0,0))
                print "Unrecognised Card"

Создаем файл и копируем в него код:

nano rf.py

сохраняем файл (CTRL+x, y).
Запускаем скрипт командой

sudo python rf.py

После будет происходить следующее:
красный диод загорится, отображая, что наш «замок» закрыт.
Если к считывателю поднесена карта, номер которой (без запятых) внесен в список, то красный диод потухнет, зеленый диод загорится, сигнализируя, что «замок» открыт, желтый диод загорится — он в данном случае «контрольный», показывая, что на «замок» идет управляющий сигнал, пьезодинамик запищит. Через заданное время (в нашем случае 1 секунду) диоды и динамик вернутся к исходному состоянию, считыватель будет ожидать считывания карты.
Если к считывателю поднесена карта не из списка, то красный и зеленый диод будут мигать, пьезодинамик будет прерывисто пищать, сигнализируя ошибку, желтый диод не загорится (т.е. сигнал на открытие «замка» не идет). Чуть меньше чем через секунду все вернется к исходному состоянию.

Короткое видео, иллюстрирующее работу:

Автор: v-milenin

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js