Короткий введення
Розумний дім стає все більш поширеним з розвитком технологій, ця стаття буде присвячена аспектам безпеки проекту інтелектуального контролю доступу.
У цій статті використовується Сенсорний екран STONE для відправки команд на MCU для керування реле та модулем MFRC522.
Принцип читання картки: керуючи модулем RFID-RC522, ідентифікуйте ідентифікатор 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
з os import uname
з машинного імпорту Pin, UART
#з pyb імпортувати 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
rx3 = []
rx_name = []
user_id_flag = Неправда
password_flag = Неправда
temp_id = ”
temp_mima = ”
personnel_id = {'zbw':[236,230,169,47],'lbw':[19,165,93,4]}
personnel_ps = {'zbw':'zbw3366′,'lbw':'lbwnb'}
admin_password = ('yyds')
button_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, ключ, 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, ключ, raw_uid) == rdr.OK:
print(“Дані адреси 8: %s” % rdr.read(8))
для ps в personnel_id:
якщо raw_uid[0:4:1] == personnel_id.get(ps):
suos.value(1)
друку (ps)
uart_write(ps, *raw_uid[0:4:1])
час. сон (3)
uart2.sendbreak()
перерву
rdr.stop_crypto1()
час. сон (3)
suos.value(0)
ще:
print("Помилка автентифікації")
ще:
print("Не вдалося вибрати тег")
якщо uart2.any()>1:
rx2 = []
data_name2 = ”
bin_data = uart2.read(40)
uart2.sendbreak()
rx1 = список (bin_data)
для елемента в rx1:
rx2.append(chr(елемент))
print(rx2)
якщо rx1[3:5:1] == button_cmd:
data_name_len = rx1[6] – 1
назва_даних = rx2[7:ім'я_даних_len+7:1]
data_name2 = .join(name_data)
print(назва_даних2)
якщо data_name2 == 'back3':
повертати
крім KeyboardInterrupt:
print ("помилка прочитання")
def do_read2 (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, ключ, raw_uid) == rdr.OK:
print(“Дані адреси 8: %s” % rdr.read(8))
personnel_id[idd] = raw_uid[0:4:1]
uart_write3(*raw_uid[0:4:1])
rdr.stop_crypto1()
ще:
print("Помилка автентифікації")
ще:
print("Не вдалося вибрати тег")
якщо uart2.any()>1:
rx2 = []
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(name_data)
print(назва_даних2)
якщо data_name2 == 'back1':
повертати
крім KeyboardInterrupt:
print ("помилка прочитання")
def uart_write(текст, *ids):
# print(текст, *ids)
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')
час. сон (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')
час. сон (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' )
час. сон (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')
час. сон (1)
uart2.write('ST<{“cmd_code”:”set_text”,”type”:”label”,”widget”:”login”,”text”:”'+text2+'”}>ET')
час. сон (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' )
час. сон (3)
uart2.write('ST<{“cmd_code”:”set_text”,”type”:”label”,”widget”:”cardid”,”text”:”””}>ET')
def card_zhuce():
Правда:
якщо uart2.any():
user_id = ”
пароль = ”
rx2 = []
rx_num = 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)
print(data_id_st2)
якщо data_id_st2 == 'редагувати1':
data_id_st3 = rx2[15:data_end:1]
data_id_st4 = ".join(data_id_st3)
print(data_id_st4)
якщо data_id_st4 != ”:
ім'я = правда
elif data_id_st2 == 'редагувати2':
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 = ”
пароль = ”
rx2 = []
rx_num = 0
#закінчення_даних = 0
bin_data = uart2.read(40)
uart2.sendbreak()
rx1 = список (bin_data)
для елемента в rx1:
rx2.append(chr(елемент))
rx_num += 1
# if (rx2[rx_num] == 'T') і (rx2[rx_num-1] == 'E') і (rx2[rx_num-2] == '>'):
# перерву
data_end = rx_num-5
data_id_st = rx2[8:13:1]
data_id_st2 = .join(data_id_st)
print(data_id_st2)
якщо rx1[3:5:1] == button_cmd:
data_name_len = rx1[6] – 1
назва_даних = rx2[7:ім'я_даних_len+7:1]
data_name2 = .join(name_data)
print(назва_даних2)
якщо data_name2 == 'back2':
повертати
якщо data_id_st2 == 'редагувати3':
data_id_st3 = rx2[15:data_end:1]
data_id_st4 = ".join(data_id_st3)
print(data_id_st4)
user_id_flag = Правда
temp_id3 = data_id_st4
# personnel_ps[temp_id] = raw_uid[0:4:1]
elif data_id_st2 == 'редагувати4':
data_id_st5 = rx2[15:data_end:1]
data_id_st6 = ".join(data_id_st5)
print(data_id_st6)
# якщо personnel_ps.get(temp_id) == data_id_st6:
password_flag = Правда
temp_mima3 = data_id_st6
# personnel_ps[temp_id] = password_flag
# print(rx2,user_id_flag,password_flag)
elif data_id_st2 == 'редагувати7':
data_id_st5 = rx2[15:data_end:1]
data_id_st6 = ".join(data_id_st5)
if (data_id_st6 == admin_password) і (password_flag == True) і (user_id_flag == True):
admin = Правда
personal_ps[temp_id3] = temp_mima3
password_flag = Неправда
user_id_flag = Неправда
uart_write4('Перевірку пройдено!','вхід пройшов успішно!')
def password_loin():
temp_id2 = ”
temp_mima = ”
Правда:
якщо uart2.any():
user_id = ”
пароль = ”
rx2 = []
rx_num = 0
#закінчення_даних = 0
bin_data = uart2.read(40)
uart2.sendbreak()
rx1 = список (bin_data)
для елемента в rx1:
rx2.append(chr(елемент))
rx_num += 1
# if (rx2[rx_num] == 'T') і (rx2[rx_num-1] == 'E') і (rx2[rx_num-2] == '>'):
# перерву
data_end = rx_num-5
data_id_st = rx2[8:13:1]
data_id_st2 = .join(data_id_st)
print(data_id_st2)
якщо rx1[3:5:1] == button_cmd:
data_name_len = rx1[6] – 1
назва_даних = rx2[7:ім'я_даних_len+7:1]
data_name2 = .join(name_data)
print(назва_даних2)
якщо data_name2 == 'back4':
повертати
якщо data_id_st2 == 'редагувати5':
data_id_st3 = rx2[15:data_end:1]
data_id_st4 = ".join(data_id_st3)
print(data_id_st4)
якщо data_id_st4 в personnel_ps:
user_id_flag = Правда
temp_id2 = data_id_st4
elif data_id_st2 == 'редагувати6':
data_id_st5 = rx2[15:data_end:1]
data_id_st6 = ".join(data_id_st5)
print(data_id_st6)
print(temp_id2)
print(personnel_ps)
якщо personnel_ps.get(temp_id2) == data_id_st6:
password_flag = Правда
# print(rx2,user_id_flag,password_flag)
print(user_id_flag,password_flag)
if (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')
час. сон (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:
rx2 = []
data_name2 = ”
bin_data = uart2.read(40)
# time.sleep(1)
uart2.sendbreak()
# time.sleep(1)
rx1 = список (bin_data)
для елемента в rx1:
rx2.append(chr(елемент))
print(rx2)
якщо rx1[3:5:1] == button_cmd:
data_name_len = rx1[6] – 1
назва_даних = rx2[7:ім'я_даних_len+7:1]
data_name2 = .join(name_data)
print(назва_даних2)
якщо data_name2 == 'card1':
card_zhuce()
elif data_name2 == 'пароль1':
mima_zuce()
elif data_name2 == 'картка2':
do_read()
elif data_name2 == 'пароль2':
password_loin()
MFRC522.py
з машинного імпорту Pin, SPI
з os import uname
клас MFRC522:
ОК = 0
NOTAGERR = 1
ERR = 2
REQIDL = 0x26
REQALL = 0x52
AUTHENT1A = 0x60
AUTHENT1B = 0x61
def __init__(self, sck, mosi, miso, rst, cs):
self.sck = Pin(sck, Pin.OUT)
self.mosi = Pin(mosi, Pin.OUT)
self.miso = Pin(miso)
self.rst = Pin(prst, 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, pins=(self.sck, self.mosi, self.miso))
elif board == '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) & (~mask))
def _tocard(self, cmd, send):
recv = []
біти = irq_en = wait_irq = n = 0
stat = self.ERR
якщо cmd == 0x0E:
irq_en = 0x12
wait_irq = 0x10
elif cmd == 0x0C:
irq_en = 0x77
wait_irq = 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:
stat = self.OK
якщо n & irq_en & 0x01:
stat = self.NOTAGERR
elif cmd == 0x0C:
n = self._rreg(0x0A)
lbits = self._rreg(0x0C) & 0x07
якщо lbits != 0:
біти = (n – 1) * 8 + lbits
ще:
біти = n * 8
якщо n == 0:
N = 1
elif n > 16:
N = 16
для _ в діапазоні (n):
recv.append(self._rreg(0x09))
ще:
stat = self.ERR
повернути stat, recv, bits
def _crc(self, data):
self._cflags(0x05, 0x04)
self._sflags(0x0A, 0x80)
для c в даних:
self._wreg(0x09, c)
self._wreg(0x01, 0x03)
i = 0xFF
Правда:
n = self._rreg(0x05)
я -= 1
якщо ні ((i != 0) і ні (n & 0x04)):
перерву
повернути [self._rreg(0x22), self._rreg(0x21)]
def init(self):
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()
скидання визначення (самостійне):
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, [режим])
if (stat != self.OK) | (біти != 0x10):
stat = self.ERR
повернути стат, біти
def anticoll(self):
ser_chk = 0
ser = [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]:
stat = self.ERR
ще:
stat = 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):
повернути self._tocard(0x0E, [mode, addr] + sect + ser[:4])[0]
def stop_crypto1(self):
self._cflags(0x08, 0x08)
def read(self, addr):
дані = [0x30, адрес]
дані += self._crc(дані)
(stat, recv, _) = self._tocard(0x0C, дані)
return recv if stat == self.OK else Немає
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):
stat = self.ERR
ще:
buf = []
для i в діапазоні (16):
buf.append(дані[i])
buf += self._crc(buf)
(stat, recv, bits) = self._tocard(0x0C, buf)
якщо ні (stat == self.OK) чи ні (біти == 4) чи ні ((recv[0] & 0x0F) == 0x0A):
stat = self.ERR
повернути стат
Джерело: Інформація про дані Платона