Краткое введение
Умный дом становится все более и более распространенным с развитием технологий, эта статья будет посвящена аспектам безопасности проекта интеллектуального контроля доступа.
Эта статья использует Сенсорный экран STONE для отправки команд на MCU для управления реле и модулем MFRC522.
Принцип чтения карт: управляя модулем RFID-RC522, идентифицируйте ID ID-карты рядом с ID-картой, а затем определите, существует ли ID в базе данных слова типичный, ID является типичным значением слова, если наличие проверки через , а затем распечатайте соответствующее имя и таким же образом приведите в действие электромагнитный замок.
Требуемые материалы
- ESP32
- Электронный замок KOB
- Реле
- STONE STWI070WT-01 сенсорный дисплей
- Модуль MFRC522
Реализованная функция
- оформление карты.
- логин и пароль регистрации.
- карта проведите пальцем, чтобы разблокировать электронный замок.
- Имя пользователя и пароль для разблокировки электронного замка.
Описание основного оборудования
Модуль RFID
Этот модуль можно напрямую загружать в различные считывающие модули. Он использует напряжение 3.3 В через интерфейс SPI всего несколькими проводами. Подключенный напрямую к материнской плате ЦП, модуль может стабильно и надежно работать как дистанционный считыватель карт.
STWI070WT-01 был задуман как монитор TFT и сенсорный контроллер. Он включает в себя процессор, программу управления, драйвер, флэш-память, порт RS232 / RS422 / RS485 / TTL / LAN, Wi-Fi / Bluetooth, сенсорный экран, источник питания и т. Д., Так что это целая система отображения, основанная на мощной и простой операционная система, которой может управлять любой MCU.
Дизайн графического интерфейса
Совместное использование кода
импорт mfrc522
время импорта
импортировать _thread
из ОС импортировать uname
из машины импортный Pin, UART
# из pyb import UART
# импорт машины
suos = Pin (32, Pin.OUT)
uart2 = UART (2, скорость передачи = 115200, rx = 16, tx = 17, тайм-аут = 10)
ESP32_HSPI_CLOCK = 14
ESP32_HSPI_SLAVE_SELECT = 15
ESP32_HSPI_MISO = 12
ESP32_HSPI_MOSI = 13
ESP32_MFRC522_RST = 5
гх3 = []
rx_имя = []
user_id_flag = Ложь
password_flag = Ложь
temp_id = »
temp_mima = »
staff_id = {'zbw': [236,230,169,47], 'lbw': [19,165,93,4]}
staff_ps = {'zbw': 'zbw3366', 'lbw': 'lbwnb'}
admin_password = ('гг')
кнопка_cmd = [16,1]
edit1_cmd = [16,112 XNUMX]
edit2_cmd = [16,113 XNUMX]
edit3_cmd = [16,114 XNUMX]
если uname () [0] == 'esp32':
rdr = mfrc522.MFRC522 (ESP32_HSPI_CLOCK, ESP32_HSPI_MOSI, ESP32_HSPI_MISO, ESP32_MFRC522_RST, ESP32_HSPI_SLAVE_SELECT)
def do_write ():
попробовать:
(stat, tag_type) = rdr.request (rdr.REQIDL)
если stat == rdr.OK:
(stat, raw_uid) = rdr.anticoll ()
если stat == rdr.OK:
print («Обнаружена новая карта»)
print (”- тип тега: 0x% 02x”% tag_type)
print (”- uid: 0x% 02x% 02x% 02x% 02x”% (raw_uid [0], raw_uid [1], raw_uid [2], raw_uid [3]))
Распечатать("")
если rdr.select_tag (raw_uid) == rdr.OK:
ключ = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
если rdr.auth (rdr.AUTHENT1A, 8, key, raw_uid) == rdr.OK:
stat = rdr.write(8, b”\x00\x53\x00\x54\x00\x4F\x00\x4E\x00\x45\x0a\x0b\x0c\x0d\x0e\x0f”)
rdr.stop_crypto1 ()
если stat == rdr.OK:
print («Данные, записанные на карту»)
еще:
print («Не удалось записать данные на карту»)
еще:
print («Ошибка аутентификации»)
еще:
print («Не удалось выбрать тег»)
кроме KeyboardInterrupt:
print («ошибка записи»)
def do_read ():
пока верно:
попробовать:
(stat, tag_type) = rdr.request (rdr.REQIDL)
если stat == rdr.OK:
(stat, raw_uid) = rdr.anticoll ()
если stat == rdr.OK:
print («Обнаружена новая карта»)
print (”- тип тега: 0x% 02x”% tag_type)
print (”- uid: 0x% 02x% 02x% 02x% 02x”% (raw_uid [0], raw_uid [1], raw_uid [2], raw_uid [3]))
print (raw_uid [0], raw_uid [1], raw_uid [2], raw_uid [3])
Распечатать("")
если rdr.select_tag (raw_uid) == rdr.OK:
ключ = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
если rdr.auth (rdr.AUTHENT1A, 8, key, raw_uid) == rdr.OK:
print («Данные адреса 8:% s»% rdr.read (8))
для ps в формате staff_id:
если raw_uid [0: 4: 1] == staff_id.get (ps):
suos.value (1)
печать (пс)
uart_write (ps, * raw_uid [0: 4: 1])
time.sleep (3)
uart2.sendbreak ()
перерыв
rdr.stop_crypto1 ()
time.sleep (3)
suos.value (0)
еще:
print («Ошибка аутентификации»)
еще:
print («Не удалось выбрать тег»)
если uart2.any ()> 1:
гх2 = []
data_name2 = »
bin_data = uart2.read (40)
uart2.sendbreak ()
rx1 = список (bin_data)
для элемента в rx1:
rx2.append (chr (элемент))
печать (rx2)
если rx1 [3: 5: 1] == button_cmd:
data_name_len = rx1 [6] - 1
имя_данных = rx2 [7: имя_данных_len + 7: 1]
data_name2 = ”.join (имя_данных)
печать (имя_данных2)
если data_name2 == 'back3':
возвращают
кроме KeyboardInterrupt:
print («ошибка чтения»)
деф do_read2 (idd):
печать (idd)
пока верно:
попробовать:
(stat, tag_type) = rdr.request (rdr.REQIDL)
если stat == rdr.OK:
(stat, raw_uid) = rdr.anticoll ()
если stat == rdr.OK:
print («Обнаружена новая карта»)
print (”- тип тега: 0x% 02x”% tag_type)
print (”- uid: 0x% 02x% 02x% 02x% 02x”% (raw_uid [0], raw_uid [1], raw_uid [2], raw_uid [3]))
print (raw_uid [0], raw_uid [1], raw_uid [2], raw_uid [3])
Распечатать("")
если rdr.select_tag (raw_uid) == rdr.OK:
ключ = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
если rdr.auth (rdr.AUTHENT1A, 8, key, raw_uid) == rdr.OK:
print («Данные адреса 8:% s»% rdr.read (8))
Персональный_ид [idd] = raw_uid [0: 4: 1]
uart_write3 (* raw_uid [0: 4: 1])
rdr.stop_crypto1 ()
еще:
print («Ошибка аутентификации»)
еще:
print («Не удалось выбрать тег»)
если uart2.any ()> 1:
гх2 = []
data_name2 = »
bin_data = uart2.read (40)
uart2.sendbreak ()
rx1 = список (bin_data)
для элемента в rx1:
rx2.append (chr (элемент))
если rx1 [3: 5: 1] == button_cmd:
data_name_len = rx1 [6] - 1
имя_данных = rx2 [7: имя_данных_len + 7: 1]
data_name2 = ”.join (имя_данных)
печать (имя_данных2)
если data_name2 == 'back1':
возвращают
кроме KeyboardInterrupt:
print («ошибка чтения»)
def uart_write (текст, * ids):
# print (текст, * идентификаторы)
uart2.write ('ST <{«cmd_code»: «set_text», «type»: «label», «widget»: «cardname1 ″,« text »:»' + str (text) + '”}> ET' )
uart2.write ('ST <{«cmd_code»: «set_text», «type»: «label», «widget»: «cardid1 ″,« text »:»' + str (ids) + '”}> ET' )
uart2.write ('ST <{«cmd_code»: «set_visible», «type»: «widget», «widget»: «lock1 ″,« visible »: true}> ET')
time.sleep (3)
uart2.write ('ST <{«cmd_code»: «set_text», «type»: «label», «widget»: «cardname1 ″,« text »:» »»}> ET')
uart2.write ('ST <{«cmd_code»: «set_text», «type»: «label», «widget»: «cardid1 ″,« text »:» »»}> ET')
uart2.write ('ST <{«cmd_code»: «set_visible», «type»: «widget», «widget»: «lock1 ″,« visible »: false}> ET')
def uart_write2 (текст, текст2):
uart2.write ('ST <{«cmd_code»: «set_text», «type»: «label», «widget»: «cardid», «text»: «' + text + '»}> ET')
time.sleep (3)
uart2.write ('ST <{«cmd_code»: «set_text», «type»: «label», «widget»: «cardid», «text»: «' + text2 + '»}> ET')
uart2.write ('ST <{«cmd_code»: «set_text», «type»: «label», «widget»: «edit2 ″,« text »:» »»}> ET')
def uart_write3 (* id2):
uart2.write ('ST <{«cmd_code»: «set_text», «type»: «label», «widget»: «cardid», «text»: »' + str (id2) + '”}> ET' )
time.sleep (3)
uart2.write ('ST <{«cmd_code»: «set_text», «type»: «label», «widget»: «cardid», «text»: »» »}> ET')
def uart_write4 (текст, текст2):
uart2.write ('ST <{«cmd_code»: «set_text», «type»: «label», «widget»: «login», «text»: »' + text + '”}> ET')
time.sleep (1)
uart2.write ('ST <{«cmd_code»: «set_text», «type»: «label», «widget»: «login», «text»: »' + text2 + '”}> ET')
time.sleep (1)
uart2.write ('ST <{«cmd_code»: «set_text», «type»: «label», «widget»: «edit3 ″,« text »:» »»}> ET')
uart2.write ('ST <{«cmd_code»: «set_text», «type»: «label», «widget»: «edit4 ″,« text »:» »»}> ET')
uart2.write ('ST <{«cmd_code»: «set_text», «type»: «label», «widget»: «edit7 ″,« text »:» »»}> ET')
def uart_write5 ():
uart2.write ('ST <{«cmd_code»: «set_text», «type»: «label», «widget»: «cardid», «text»: »' + str (id2) + '”}> ET' )
time.sleep (3)
uart2.write ('ST <{«cmd_code»: «set_text», «type»: «label», «widget»: «cardid», «text»: »» »}> ET')
def card_zhuce ():
пока верно:
если uart2.any ():
user_id = »
пароль = ”
гх2 = []
номер_rx = 0
bin_data = uart2.read (40)
uart2.sendbreak ()
rx1 = список (bin_data)
для элемента в rx1:
rx2.append (chr (элемент))
rx_num + = 1
data_end = rx_num-5
data_id_st = rx2 [8: 13: 1]
data_id_st2 = ”.join (data_id_st)
печать (data_id_st2)
если data_id_st2 == 'edit1':
data_id_st3 = rx2 [15: data_end: 1]
data_id_st4 = ”.join (data_id_st3)
печать (data_id_st4)
если data_id_st4! = »:
имя = Истина
elif data_id_st2 == 'edit2':
data_id_st5 = rx2 [15: data_end: 1]
data_id_st6 = ”.join (data_id_st5)
если data_id_st6 == admin_password:
admin = Правда
uart_write2 ('Проверка пройдена!', 'Поместите карту!')
do_read2 (data_id_st4)
возвращают
def mima_zuce ():
temp_id3 = »
temp_mima3 = »
пока верно:
если uart2.any ():
user_id = »
пароль = ”
гх2 = []
номер_rx = 0
# data_end = 0
bin_data = uart2.read (40)
uart2.sendbreak ()
rx1 = список (bin_data)
для элемента в rx1:
rx2.append (chr (элемент))
rx_num + = 1
# if (rx2 [rx_num] == 'T') and (rx2 [rx_num-1] == 'E') and (rx2 [rx_num-2] == '>'):
# перерыв
data_end = rx_num-5
data_id_st = rx2 [8: 13: 1]
data_id_st2 = ”.join (data_id_st)
печать (data_id_st2)
если rx1 [3: 5: 1] == button_cmd:
data_name_len = rx1 [6] - 1
имя_данных = rx2 [7: имя_данных_len + 7: 1]
data_name2 = ”.join (имя_данных)
печать (имя_данных2)
если data_name2 == 'back2':
возвращают
если data_id_st2 == 'edit3':
data_id_st3 = rx2 [15: data_end: 1]
data_id_st4 = ”.join (data_id_st3)
печать (data_id_st4)
user_id_flag = Истина
temp_id3 = data_id_st4
# staff_ps [temp_id] = raw_uid [0: 4: 1]
elif data_id_st2 == 'edit4':
data_id_st5 = rx2 [15: data_end: 1]
data_id_st6 = ”.join (data_id_st5)
печать (data_id_st6)
# if staff_ps.get (temp_id) == data_id_st6:
password_flag = Истина
temp_mima3 = data_id_st6
# staff_ps [temp_id] = password_flag
# print (rx2, user_id_flag, password_flag)
elif data_id_st2 == 'edit7':
data_id_st5 = rx2 [15: data_end: 1]
data_id_st6 = ”.join (data_id_st5)
если (data_id_st6 == admin_password) и (password_flag == True) и (user_id_flag == True):
admin = Правда
staff_ps [temp_id3] = temp_mima3
password_flag = Ложь
user_id_flag = Ложь
uart_write4 ('Проверка прошла!', 'Вход прошел успешно!')
def password_loin ():
temp_id2 = »
temp_mima = »
пока верно:
если uart2.any ():
user_id = »
пароль = ”
гх2 = []
номер_rx = 0
# data_end = 0
bin_data = uart2.read (40)
uart2.sendbreak ()
rx1 = список (bin_data)
для элемента в rx1:
rx2.append (chr (элемент))
rx_num + = 1
# if (rx2 [rx_num] == 'T') and (rx2 [rx_num-1] == 'E') and (rx2 [rx_num-2] == '>'):
# перерыв
data_end = rx_num-5
data_id_st = rx2 [8: 13: 1]
data_id_st2 = ”.join (data_id_st)
печать (data_id_st2)
если rx1 [3: 5: 1] == button_cmd:
data_name_len = rx1 [6] - 1
имя_данных = rx2 [7: имя_данных_len + 7: 1]
data_name2 = ”.join (имя_данных)
печать (имя_данных2)
если data_name2 == 'back4':
возвращают
если data_id_st2 == 'edit5':
data_id_st3 = rx2 [15: data_end: 1]
data_id_st4 = ”.join (data_id_st3)
печать (data_id_st4)
если data_id_st4 в staff_ps:
user_id_flag = Истина
temp_id2 = data_id_st4
elif data_id_st2 == 'edit6':
data_id_st5 = rx2 [15: data_end: 1]
data_id_st6 = ”.join (data_id_st5)
печать (data_id_st6)
печать (temp_id2)
печать (staff_ps)
если staff_ps.get (temp_id2) == data_id_st6:
password_flag = Истина
# print (rx2, user_id_flag, password_flag)
печать (user_id_flag, password_flag)
если (password_flag == True) и (user_id_flag == True):
uart_write (temp_id2, temp_id2)
password_flag = Ложь
user_id_flag = Ложь
suos.value (1)
uart2.write ('ST <{«cmd_code»: «set_visible», «type»: «widget», «widget»: «lock2 ″,« visible »: true}> ET')
uart2.write ('ST <{«cmd_code»: «set_text», «type»: «label», «widget»: «edit5 ″,« text »:» »»}> ET')
uart2.write ('ST <{«cmd_code»: «set_text», «type»: «label», «widget»: «edit6 ″,« text »:» »»}> ET')
time.sleep (3)
# uart_write ('студент', ”)
suos.value (0)
uart2.write ('ST <{«cmd_code»: «set_visible», «type»: «widget», «widget»: «lock2 ″,« visible »: false}> ET')
uart2.sendbreak ()
пока верно:
если uart2.any ()> 1:
гх2 = []
data_name2 = »
bin_data = uart2.read (40)
# time.sleep (1)
uart2.sendbreak ()
# time.sleep (1)
rx1 = список (bin_data)
для элемента в rx1:
rx2.append (chr (элемент))
печать (rx2)
если rx1 [3: 5: 1] == button_cmd:
data_name_len = rx1 [6] - 1
имя_данных = rx2 [7: имя_данных_len + 7: 1]
data_name2 = ”.join (имя_данных)
печать (имя_данных2)
если data_name2 == 'card1':
card_zhuce ()
elif data_name2 == 'пароль1':
mima_zuce ()
elif data_name2 == 'card2':
do_read ()
elif data_name2 == 'пароль2':
password_loin ()
MFRC522.py
из машины импортный Pin, SPI
из ОС импортировать uname
класс MFRC522:
ОК = 0
НОТАГЕРР = 1
ОШИБКА = 2
РЕКИДЛ = 0x26
ЗАПРОС = 0x52
АУТЕНТ1А = 0x60
АУТЕНТ1Б = 0x61
def __init __ (self, sck, mosi, miso, rst, cs):
self.sck = Pin (sck, Pin.OUT)
self.mosi = Пин (mosi, Pin.OUT)
self.miso = Пин (мисо)
self.rst = Pin (первый, Pin.OUT)
self.cs = Pin (cs, Pin.OUT)
self.rst.value (0)
self.cs.value (1)
доска = uname () [0]
если board == 'WiPy' или board == 'LoPy' или board == 'FiPy':
self.spi = SPI (0)
self.spi.init (SPI.MASTER, скорость передачи = 1000000, контакты = (self.sck, self.mosi, self.miso))
доска elif == 'esp32':
self.spi = SPI (скорость передачи = 100000, полярность = 0, фаза = 0, sck = self.sck, mosi = self.mosi, miso = self.miso)
self.spi.init ()
еще:
поднять RuntimeError («Неподдерживаемая платформа»)
self.rst.value (1)
self.init ()
def _wreg (self, reg, val):
self.cs.value (0)
self.spi.write (b '% c'% int (0xff & ((reg << 1) & 0x7e)))
self.spi.write (b '% c'% int (0xff & val))
self.cs.value (1)
def _rreg (self, reg):
self.cs.value (0)
self.spi.write (b '% c'% int (0xff & ((((reg << 1) & 0x7e) | 0x80)))
val = self.spi.read (1)
self.cs.value (1)
вернуть значение [0]
def _sflags (self, reg, mask):
self._wreg (reg, self._rreg (reg) | маска)
def _cflags (self, reg, mask):
self._wreg (reg, self._rreg (reg) & (~ маска))
def _tocard (self, cmd, send):
получено = []
биты = irq_en = wait_irq = n = 0
стат = self.ERR
если cmd == 0x0E:
irq_en = 0x12
ожидание_ирк = 0x10
Элиф cmd == 0x0C:
irq_en = 0x77
ожидание_ирк = 0x30
self._wreg (0x02, irq_en | 0x80)
self._cflags (0x04, 0x80)
self._sflags (0x0A, 0x80)
self._wreg (0x01, 0x00)
для c в отправке:
self._wreg (0x09, c)
self._wreg (0x01, cmd)
если cmd == 0x0C:
self._sflags (0x0D, 0x80)
я = 2000
пока верно:
n = self._rreg (0x04)
я - = 1
если ~ ((i! = 0) и ~ (n & 0x01) и ~ (n & wait_irq)):
перерыв
self._cflags (0x0D, 0x80)
Если я:
если (self._rreg (0x06) & 0x1B) == 0x00:
стат = сам.ОК
если n & irq_en & 0x01:
стат = self.NOTAGERR
Элиф cmd == 0x0C:
n = self._rreg (0x0A)
lbits = self._rreg (0x0C) & 0x07
если lbits! = 0:
бит = (n - 1) * 8 + lbit
еще:
бит = n * 8
если n == 0:
N = 1
elif n> 16:
N = 16
для _ в диапазоне (n):
recv.append (self._rreg (0x09))
еще:
стат = self.ERR
статистика возврата, возврат, биты
def _crc (себя, данные):
self._cflags (0x05, 0x04)
self._sflags (0x0A, 0x80)
для c в данных:
self._wreg (0x09, c)
self._wreg (0x01, 0x03)
я = 0xFF
пока верно:
n = self._rreg (0x05)
я - = 1
если нет ((i! = 0) and not (n & 0x04)):
перерыв
return [self._rreg (0x22), self._rreg (0x21)]
def init (сам):
self.reset ()
self._wreg (0x2A, 0x8D)
self._wreg (0x2B, 0x3E)
self._wreg (0x2D, 30)
self._wreg (0x2C, 0)
self._wreg (0x15, 0x40)
self._wreg (0x11, 0x3D)
self.antenna_on ()
def сброс (сам):
self._wreg (0x01, 0x0F)
def antenna_on (self, on = True):
если включен и ~ (self._rreg (0x14) & 0x03):
self._sflags (0x14, 0x03)
еще:
self._cflags (0x14, 0x03)
запрос def (self, mode):
self._wreg (0x0D, 0x07)
(stat, recv, bits) = self._tocard (0x0C, [режим])
если (stat! = self.OK) | (биты! = 0x10):
стат = self.ERR
статистика возврата, бит
def anticoll (self):
сер_чк = 0
сер = [0x93, 0x20]
self._wreg (0x0D, 0x00)
(stat, recv, bits) = self._tocard (0x0C, ser)
если stat == self.OK:
если len (recv) == 5:
для i в диапазоне (4):
ser_chk = ser_chk ^ recv [i]
если ser_chk! = recv [4]:
стат = self.ERR
еще:
стат = self.ERR
статистика возврата, recv
def select_tag (self, ser):
buf = [0x93, 0x70] + ser [: 5]
buf + = self._crc (buf)
(stat, recv, bits) = self._tocard (0x0C, buf)
вернуть self.OK if (stat == self.OK) и (bits == 0x18) else self.ERR
def auth (self, mode, addr, sect, ser):
return self._tocard (0x0E, [mode, addr] + sect + ser [: 4]) [0]
def stop_crypto1 (сам):
self._cflags (0x08, 0x08)
def read (self, addr):
данные = [0x30, адрес]
data + = self._crc (данные)
(stat, recv, _) = self._tocard (0x0C, данные)
вернуть recv, если stat == self.OK else None
def write (self, addr, data):
buf = [0xA0, адрес]
buf + = self._crc (buf)
(stat, recv, bits) = self._tocard (0x0C, buf)
если нет (stat == self.OK) или нет (биты == 4) или нет ((recv [0] & 0x0F) == 0x0A):
стат = self.ERR
еще:
буфер = []
для i в диапазоне (16):
buf.append (данные [i])
buf + = self._crc (buf)
(stat, recv, bits) = self._tocard (0x0C, buf)
если нет (stat == self.OK) или нет (биты == 4) или нет ((recv [0] & 0x0F) == 0x0A):
стат = self.ERR
вернуть статистику
Источник: Plato Data Intelligence.