简单的介绍
随着技术的发展,智能家居越来越普遍,本文将重点介绍智能门禁项目的安全方面。
本文使用 STONE的触摸屏 向 MCU 发送命令以控制继电器和 MFRC522 模块。
读卡原理: 通过驱动RFID-RC522模块,识别靠近身份证的身份证ID,然后判断该ID是否存在于词库中的典型值,ID为该词的典型值,如果存在则通过验证,然后打印出对应的名称,然后用同样的方法驱动电磁锁。
所需材料
实现的功能
- 卡注册。
- 用户名和密码注册。
- 刷卡解锁电子锁。
- 用于解锁电子锁的用户名和密码。
主要硬件说明
射频识别模块
该模块可以直接加载到各种阅读器模块中。 它使用 3.3V 的电压,通过 SPI 接口,只需几根线。 该模块直接与CPU主板相连,可作为远距离读卡器稳定可靠地工作。
STWI070WT-01 被设想为 TFT 显示器和触摸控制器。 它包括处理器、控制程序、驱动程序、闪存、RS232/RS422/RS485/TTL/LAN端口、Wi-Fi/蓝牙、触摸屏、电源等,是一个基于强大而简单的显示系统。操作系统,可由任何 MCU 控制。
图形用户界面设计
代码共享
进口 mfrc522
进口时间
导入_thread
从 os 导入 uname
从机器导入引脚,UART
#from pyb 导入 UART
#进口机器
suos = Pin(32,Pin.OUT)
uart2 = UART(2,波特率=115200,rx=16,tx=17,超时=10)
ESP32_HSPI_时钟 = 14
ESP32_HSPI_SLAVE_SELECT = 15
ESP32_HSPI_MISO = 12
ESP32_HSPI_MOSI = 13
ESP32_MFRC522_RST = 5
RX3 = []
接收名称 = []
user_id_flag = 假
密码标志 = 假
临时 ID = ”
temp_mima = ”
people_id = {'zbw':[236,230,169,47],'lbw':[19,165,93,4]}
人员_ps = {'zbw':'zbw3366','lbw':'lbwnb'}
admin_password = ('yyds')
按钮命令 = [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:
打印(“检测到新卡”)
打印(”——标签类型:0x%02x”% tag_type)
打印(”-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:
打印(“数据写入卡”)
其他:
打印(“无法将数据写入卡”)
其他:
打印(“身份验证错误”)
其他:
打印(“无法选择标签”)
除了KeyboardInterrupt:
打印(“写错误”)
定义 do_read():
而True:
尝试:
(stat, tag_type) = rdr.request(rdr.REQIDL)
如果 stat == rdr.OK:
(stat, raw_uid) = rdr.anticoll()
如果 stat == rdr.OK:
打印(“检测到新卡”)
打印(”——标签类型:0x%02x”% tag_type)
打印(”-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, key, raw_uid) == rdr.OK:
打印(“地址 8 数据:%s” % rdr.read(8))
对于persons_id中的ps:
如果 raw_uid[0:4:1] == people_id.get(ps):
suos.value(1)
打印(ps)
uart_write(ps, *raw_uid[0:4:1])
time.sleep(3)
UART2.sendbreak()
打破
rdr.stop_crypto1()
time.sleep(3)
suos.value(0)
其他:
打印(“身份验证错误”)
其他:
打印(“无法选择标签”)
如果 uart2.any()>1:
RX2 = []
数据名称2 = ”
bin_data = UART2.read(40)
UART2.sendbreak()
rx1 = 列表(bin_data)
对于 rx1 中的项目:
rx2.append(字符(项目))
打印(rx2)
如果 rx1[3:5:1] == button_cmd:
数据名称长度 = rx1[6] – 1
数据名称 = rx2[7:data_name_len+7:1]
data_name2 = ".join(data_name)
打印(data_name2)
如果 data_name2 == 'back3':
回报
除了KeyboardInterrupt:
打印(“读取错误”)
def do_read2 (idd):
打印(身份证)
而True:
尝试:
(stat, tag_type) = rdr.request(rdr.REQIDL)
如果 stat == rdr.OK:
(stat, raw_uid) = rdr.anticoll()
如果 stat == rdr.OK:
打印(“检测到新卡”)
打印(”——标签类型:0x%02x”% tag_type)
打印(”-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, key, raw_uid) == rdr.OK:
打印(“地址 8 数据:%s” % rdr.read(8))
people_id[idd] = raw_uid[0:4:1]
uart_write3(*raw_uid[0:4:1])
rdr.stop_crypto1()
其他:
打印(“身份验证错误”)
其他:
打印(“无法选择标签”)
如果 uart2.any()>1:
RX2 = []
数据名称2 = ”
bin_data = UART2.read(40)
UART2.sendbreak()
rx1 = 列表(bin_data)
对于 rx1 中的项目:
rx2.append(字符(项目))
如果 rx1[3:5:1] == button_cmd:
数据名称长度 = rx1[6] – 1
数据名称 = rx2[7:data_name_len+7:1]
data_name2 = ".join(data_name)
打印(data_name2)
如果 data_name2 == 'back1':
回报
除了KeyboardInterrupt:
打印(“读取错误”)
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')
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():
而True:
如果 uart2.any():
用户 ID = ”
密码 = ”
RX2 = []
接收数 = 0
bin_data = UART2.read(40)
UART2.sendbreak()
rx1 = 列表(bin_data)
对于 rx1 中的项目:
rx2.append(字符(项目))
rx_num += 1
数据结束 = 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:
管理员 = 真
uart_write2('验证通过!','请放卡!')
do_read2(data_id_st4)
回报
def mima_zuce():
临时 ID3 = ”
temp_mima3 = ”
而True:
如果 uart2.any():
用户 ID = ”
密码 = ”
RX2 = []
接收数 = 0
# 数据结束 = 0
bin_data = UART2.read(40)
UART2.sendbreak()
rx1 = 列表(bin_data)
对于 rx1 中的项目:
rx2.append(字符(项目))
rx_num += 1
# if (rx2[rx_num] == 'T') and (rx2[rx_num-1] == 'E') and (rx2[rx_num-2] == '>'):
# 休息
数据结束 = 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:
数据名称长度 = rx1[6] – 1
数据名称 = rx2[7:data_name_len+7:1]
data_name2 = ".join(data_name)
打印(data_name2)
如果 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)
用户 ID 标志 = True
temp_id3 = data_id_st4
#personal_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)
# ifpersonal_ps.get(temp_id) == data_id_st6:
密码标志 = 真
temp_mima3 = data_id_st6
#personal_ps[temp_id] = password_flag
# 打印(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):
管理员 = 真
人员_ps[temp_id3] = temp_mima3
密码标志 = 假
user_id_flag = 假
uart_write4('验证通过!','登录成功!')
定义密码_腰():
临时 ID2 = ”
temp_mima = ”
而True:
如果 uart2.any():
用户 ID = ”
密码 = ”
RX2 = []
接收数 = 0
# 数据结束 = 0
bin_data = UART2.read(40)
UART2.sendbreak()
rx1 = 列表(bin_data)
对于 rx1 中的项目:
rx2.append(字符(项目))
rx_num += 1
# if (rx2[rx_num] == 'T') and (rx2[rx_num-1] == 'E') and (rx2[rx_num-2] == '>'):
# 休息
数据结束 = 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:
数据名称长度 = rx1[6] – 1
数据名称 = rx2[7:data_name_len+7:1]
data_name2 = ".join(data_name)
打印(data_name2)
如果 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)
如果persons_ps中的data_id_st4:
用户 ID 标志 = True
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)
打印(personnel_ps)
如果personal_ps.get(temp_id2) == data_id_st6:
密码标志 = 真
# 打印(rx2,user_id_flag,password_flag)
打印(user_id_flag,password_flag)
如果(password_flag == True)和(user_id_flag == True):
UART_write(temp_id2,temp_id2)
密码标志 = 假
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()
而True:
如果 uart2.any()>1:
RX2 = []
数据名称2 = ”
bin_data = UART2.read(40)
# time.sleep(1)
UART2.sendbreak()
# time.sleep(1)
rx1 = 列表(bin_data)
对于 rx1 中的项目:
rx2.append(字符(项目))
打印(rx2)
如果 rx1[3:5:1] == button_cmd:
数据名称长度 = rx1[6] – 1
数据名称 = rx2[7:data_name_len+7:1]
data_name2 = ".join(data_name)
打印(data_name2)
如果 data_name2 == 'card1':
卡_注()
elif data_name2 == 'password1':
mima_zuce()
elif data_name2 == 'card2':
做_读()
elif data_name2 == 'password2':
密码_腰()
MFRC522.py
从机器导入 Pin, SPI
从 os 导入 uname
MFRC522 类:
好 = 0
记数器 = 1
错误率 = 2
要求 = 0x26
请求 = 0x52
身份验证1A = 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(味噌)
self.rst = Pin(rst, 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.miso,miso=self.miso)
自我.spi.init()
其他:
引发运行时错误(“不支持的平台”)
self.rst.value(1)
自我初始化()
def _wreg(自身, 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.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._wreg(reg, self._rreg(reg) | 掩码)
def _cflags(自我,注册,掩码):
self._wreg(reg, self._rreg(reg) & (~mask))
def _tocard(自我,命令,发送):
接收 = []
位 = irq_en = wait_irq = n = 0
stat = self.ERR
如果 cmd == 0x0E:
irq_en = 0x12
等待中断 = 0x10
elif 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 == 0x0C:
self._sflags(0x0D, 0x80)
I = 2000
而True:
n = self._rreg(0x04)
我 -= 1
如果 ~((i != 0) 和 ~(n & 0x01) 和 ~(n & wait_irq)):
打破
self._cflags(0x0D, 0x80)
如果我:
如果 (self._rreg(0x06) & 0x1B) == 0x00:
统计=自我.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._cflags(0x05, 0x04)
self._sflags(0x0A, 0x80)
对于数据中的 c:
self._wreg(0x09, c)
self._wreg(0x01, 0x03)
我 = 0xFF
而True:
n = self._rreg(0x05)
我 -= 1
如果不是 ((i != 0) 而不是 (n & 0x04)):
打破
返回 [self._rreg(0x22), self._rreg(0x21)]
定义初始化(自我):
自我重置()
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天线_on(自我,on = True):
如果打开和 ~(self._rreg(0x14) & 0x03):
self._sflags(0x14, 0x03)
其他:
self._cflags(0x14, 0x03)
定义请求(自我,模式):
self._wreg(0x0D, 0x07)
(统计,接收,位)= self._tocard(0x0C,[模式])
if (stat != self.OK) | (位!= 0x10):
stat = self.ERR
返回状态,位
def anticoll(自我):
Ser_chk = 0
序列 = [0x93, 0x20]
self._wreg(0x0D, 0x00)
(统计,接收,位)= self._tocard(0x0C,ser)
如果 stat == self.OK:
如果 len(recv) == 5:
对于我在范围(4)中:
ser_chk=ser_chk^recv[i]
如果 ser_chk != recv[4]:
stat = self.ERR
其他:
stat = self.ERR
返回状态,接收
def select_tag(self, ser):
buf = [0x93, 0x70] + ser[:5]
buf += self._crc(buf)
(统计,接收,位)= self._tocard(0x0C,buf)
返回 self.OK if (stat == self.OK) and (bits == 0x18) else self.ERR
def auth(自我,模式,地址,教派,ser):
返回 self._tocard(0x0E, [mode, addr] + sect + ser[:4])[0]
def stop_crypto1(自我):
self._cflags(0x08, 0x08)
定义读取(自我,地址):
数据 = [0x30,地址]
数据 += self._crc(data)
(stat, recv, _) = self._tocard(0x0C, 数据)
如果 stat == self.OK 则返回 recv 否则无
def write(自身,地址,数据):
buf = [0xA0,地址]
buf += self._crc(buf)
(统计,接收,位)= self._tocard(0x0C,buf)
如果不是 (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
stat = self.ERR
其他:
缓冲区 = []
对于我在范围(16)中:
buf.append(数据[i])
buf += self._crc(buf)
(统计,接收,位)= self._tocard(0x0C,buf)
如果不是 (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
stat = self.ERR
返回状态
资料来源:柏拉图数据智能