간략한 소개
스마트 홈은 기술의 발전과 함께 점점 더 일반화되고 있습니다. 이 기사에서는 지능형 액세스 제어 프로젝트의 보안 측면에 중점을 둘 것입니다.
이 기사는 사용 STONE의 터치 스크린 릴레이 및 MFRC522 모듈을 제어하기 위해 MCU에 명령을 보냅니다.
카드 읽기의 원리: RFID-RC522 모듈을 구동하여 ID 카드에 가까운 ID 카드 ID를 식별한 다음, 해당 ID가 대표단어의 데이터베이스에 존재하는지 여부를 판별하고, ID는 해당 단어의 대표값, 존재 여부를 통한 검증 , 다음 해당 이름을 인쇄하고 동일한 방식으로 전자기 잠금을 구동합니다.
필수 자료
- ESP32
- KOB 전자 자물쇠
- 계전기
- STONE STWI070WT-01 터치 패널 디스플레이
- MFRC522 모듈
실현된 기능
- 카드 등록.
- 사용자 이름 및 암호 등록.
- 카드를 스와이프하여 전자 잠금을 해제합니다.
- 전자 잠금을 해제하기 위한 사용자 이름과 암호.
주요 하드웨어 설명
RFID 모듈
이 모듈은 다양한 리더 모듈에 직접 로드할 수 있습니다. 몇 개의 전선으로 SPI 인터페이스를 통해 3.3V의 전압을 사용합니다. CPU 마더보드와 직접 연결하여 모듈을 안정적이고 안정적인 방식으로 원거리 카드 리더기로 작동할 수 있습니다.
STWI070WT-01은 TFT 모니터 및 터치 컨트롤러로 고안되었습니다. 프로세서, 제어 프로그램, 드라이버, 플래시 메모리, RS232/RS422/RS485/TTL/LAN 포트, Wi-Fi/Bluetooth, 터치 스크린, 전원 공급 장치 등을 포함하므로 강력하고 쉬운 기반의 전체 디스플레이 시스템입니다. 모든 MCU로 제어할 수 있는 운영 체제.
GUI 디자인
코드 공유
가져오기 mfrc522
수입 시간
가져오기 _thread
os import uname에서
기계 가져오기 핀, UART에서
#pyb 가져오기 UART에서
#수입기계
suos = 핀(32, 핀.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_이름 = []
user_id_flag = 거짓
password_flag = 거짓
임시 아이디 = ”
temp_mima = "
인원 ID = {'zbw':[236,230,169,47],'lbw':[19,165,93,4]}
인원_ps = {'zbw':'zbw3366','lbw':'lbwnb'}
admin_password = ('yyds')
버튼_cmd = [16,1]
edit1_cmd = [16,112]
edit2_cmd = [16,113]
edit3_cmd = [16,114]
uname()[0] == 'esp32'인 경우:
rdr = mfrc522.MFRC522(ESP32_HSPI_CLOCK, ESP32_HSPI_MOSI, ESP32_HSPI_MISO, ESP32_MFRC522_RST, ESP32_HSPI_SLAVE_SELECT)
데프 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("쓰기 오류")
데프 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]))
인쇄(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))
person_id의 ps:
raw_uid[0:4:1] == person_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 = []
데이터_이름2 = "
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
data_name = rx2[7:data_name_len+7:1]
data_name2 = ".join(data_name)
인쇄(data_name2)
data_name2 == 'back3'인 경우:
return
KeyboardInterrupt를 제외하고 :
print("읽기 오류")
def do_read2(ID):
인쇄(ID)
진실한 동안 :
시도 :
(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]))
인쇄(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))
직원 ID[ID] = 원시 ID[0:4:1]
uart_write3(*raw_uid[0:4:1])
rdr.stop_crypto1()
그밖에:
print("인증 오류")
그밖에:
print("태그 선택 실패")
uart2.any()>1인 경우:
rx2 = []
데이터_이름2 = "
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
data_name = rx2[7:data_name_len+7:1]
data_name2 = ".join(data_name)
인쇄(data_name2)
data_name2 == 'back1'인 경우:
return
KeyboardInterrupt를 제외하고 :
print("읽기 오류")
def uart_write(텍스트, *ids):
# 인쇄(텍스트, *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')
데프 카드_zhuce():
진실한 동안 :
uart2.any()인 경우:
사용자 아이디 = ”
비밀번호 = ”
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)
인쇄(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 == '편집2':
data_id_st5 = rx2[15:data_end:1]
data_id_st6 = ".join(data_id_st5)
data_id_st6 == admin_password인 경우:
관리자 = 참
uart_write2('인증 통과!','카드를 넣어주세요!')
do_read2(data_id_st4)
return
데프 mima_zuce():
temp_id3 = "
temp_mima3 = "
진실한 동안 :
uart2.any()인 경우:
사용자 아이디 = ”
비밀번호 = ”
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') 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
data_name = rx2[7:data_name_len+7:1]
data_name2 = ".join(data_name)
인쇄(data_name2)
data_name2 == 'back2'인 경우:
return
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
# 직원_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)
인쇄(data_id_st6)
# person_ps.get(temp_id) == data_id_st6인 경우:
password_flag = 참
temp_mima3 = data_id_st6
# 직원_ps[임시_ID] = 암호_플래그
# 인쇄(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):
관리자 = 참
직원_ps[temp_id3] = temp_mima3
password_flag = 거짓
user_id_flag = 거짓
uart_write4('인증 통과!','로그인 성공!')
데프 password_loin():
temp_id2 = "
temp_mima = "
진실한 동안 :
uart2.any()인 경우:
사용자 아이디 = ”
비밀번호 = ”
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') 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
data_name = rx2[7:data_name_len+7:1]
data_name2 = ".join(data_name)
인쇄(data_name2)
data_name2 == 'back4'인 경우:
return
data_id_st2 == 'edit5'인 경우:
data_id_st3 = rx2[15:data_end:1]
data_id_st4 = ".join(data_id_st3)
인쇄(data_id_st4)
person_ps의 data_id_st4인 경우:
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)
인쇄(data_id_st6)
인쇄(temp_id2)
인쇄(personnel_ps)
인사_ps.get(temp_id2) == data_id_st6인 경우:
password_flag = 참
# 인쇄(rx2,user_id_flag,password_flag)
인쇄(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 = []
데이터_이름2 = "
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
data_name = rx2[7:data_name_len+7:1]
data_name2 = ".join(data_name)
인쇄(data_name2)
data_name2 == 'card1'인 경우:
카드_주스()
elif data_name2 == '비밀번호1':
mima_zuce()
elif data_name2 == '카드2':
do_read()
elif data_name2 == '비밀번호2':
비밀번호_로인()
MFRC522.py
기계 수입 핀, SPI에서
os import uname에서
클래스 MFRC522:
확인 = 0
노타게르 = 1
오류 = 2
REQIDL = 0x26
요청 = 0x52
인증1A = 0x60
인증1B = 0x61
def __init__(자체, sck, mosi, 된장, 첫 번째, cs):
self.sck = 핀(sck, Pin.OUT)
self.mosi = 핀(모시, 핀.OUT)
self.miso = 핀(된장)
self.rst = 핀(첫 번째, 핀.OUT)
self.cs = 핀(cs, Pin.OUT)
self.rst.value(0)
self.cs.value(1)
보드 = uname()[0]
보드 == 'WiPy' 또는 보드 == 'LoPy' 또는 보드 == 'FiPy'인 경우:
self.spi = SPI(0)
self.spi.init(SPI.MASTER, baudrate=1000000, 핀=(self.sck, self.msi, self.miso))
엘리프 보드 == 'esp32':
self.spi = SPI(전송 속도=100000, 극성=0, 위상=0, sck=self.sck, mosi=self.msi, miso=self.miso)
self.spi.init()
그밖에:
발생 런타임 오류("지원되지 않는 플랫폼")
self.rst.value(1)
자기초기화()
def _wreg(자신, 등록, 발):
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.cs.value(0)
self.spi.write(b'%c' % int(0xff & (((reg << 1) & 0x7e) | 0x80)))
값 = self.spi.read(1)
self.cs.value(1)
반환 값[0]
def _sflags(자체, 등록, 마스크):
self._wreg(reg, self._rreg(reg) | 마스크)
def _cflags(자체, 등록, 마스크):
self._wreg(reg, self._rreg(reg) & (~마스크))
def _tocard(자신, cmd, 보내기):
수신 = []
비트 = irq_en = wait_irq = n = 0
통계 = self.ERR
cmd == 0x0E인 경우:
irq_en = 0x12
wait_irq = 0x10
엘리프 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)
I = 2000
진실한 동안 :
n = self._rreg(0x04)
나는 -= 1
~((i != 0) 및 ~(n & 0x01) 및 ~(n & wait_irq)):
하다
self._cflags(0x0D, 0x80)
만약 내가:
if (self._rreg(0x06) & 0x1B) == 0x00:
통계 = self.OK
n & irq_en & 0x01인 경우:
통계 = self.NOTAGERR
엘리프 cmd == 0x0C:
n = self._rreg(0x0A)
lbits = self._rreg(0x0C) & 0x07
lbits != 0인 경우:
비트 = (n – 1) * 8 + l비트
그밖에:
비트 = n * 8
n == 0인 경우:
N = 1
엘리프 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) 및 (n & 0x04)):
하다
반환 [self._rreg(0x22), self._rreg(0x21)]
def 초기화(자체):
셀프.리셋()
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._wreg(0x0D, 0x07)
(stat, recv, bits) = self._tocard(0x0C, [모드])
if (stat != self.OK) | (비트 != 0x10):
통계 = self.ERR
반환 통계, 비트
def anticoll(자신):
ser_chk = 0
서버 = [0x93, 0x20]
self._wreg(0x0D, 0x00)
(통계, 수신, 비트) = self._tocard(0x0C, ser)
stat == self.OK인 경우:
len(recv) == 5인 경우:
범위 (4)에있는 i의 경우 :
ser_chk = ser_chk ^ 수신[i]
ser_chk != recv[4]인 경우:
통계 = self.ERR
그밖에:
통계 = self.ERR
반환 통계, 수신
def select_tag(self, ser):
버퍼 = [0x93, 0x70] + ser[:5]
버프 += self._crc(버프)
(stat, recv, 비트) = self._tocard(0x0C, buf)
반환 self.OK if (stat == self.OK) 및 (bits == 0x18) else self.ERR
def 인증(self, 모드, addr, sect, ser):
return self._tocard(0x0E, [모드, 주소] + 분파 + ser[:4])[0]
def stop_crypto1(자체):
self._cflags(0x08, 0x08)
def 읽기(자신, addr):
데이터 = [0x30, addr]
데이터 += self._crc(데이터)
(stat, recv, _) = self._tocard(0x0C, 데이터)
stat == self.OK인 경우 recv를 반환합니다. 그렇지 않으면 없음
def write(자신, addr, 데이터):
buf = [0xA0, 주소]
버프 += self._crc(버프)
(stat, recv, 비트) = self._tocard(0x0C, buf)
그렇지 않은 경우(stat == self.OK) 또는 그렇지 않은 경우(비트 == 4) 또는 그렇지 않은 경우((recv[0] & 0x0F) == 0x0A):
통계 = self.ERR
그밖에:
버프 = []
범위 (16)에있는 i의 경우 :
buf.append(데이터[i])
버프 += self._crc(버프)
(stat, recv, 비트) = self._tocard(0x0C, buf)
그렇지 않은 경우(stat == self.OK) 또는 그렇지 않은 경우(비트 == 4) 또는 그렇지 않은 경우((recv[0] & 0x0F) == 0x0A):
통계 = self.ERR
반환 통계
출처 : Plato Data Intelligence