Intelligent access control based on ESP32 and STONE TFT LCD
Brief Introduction
The smart home is becoming more and more common with the development of technology, this article will focus on the security aspects of the intelligent access control project.
This article uses STONE’s touch screen to send commands to the MCU to control the relay and MFRC522 module.
The principle of card reading: by driving the RFID-RC522 module, identify the ID card ID close to the ID card, and then determine whether the ID exists in the database of the word typical, ID is the typical value of the word, if the existence of the verification through, and then print out the corresponding name, and then drive the electromagnetic lock in the same way.
Required materials
- ESP32
- KOB electronic lock
- Relay
- STONE STWI070WT-01 touch panel display
- MFRC522 module
Realized function
- card registration.
- username and password registration.
- card swipe to unlock the electronic lock.
- User name and password to unlock the electronic lock.
The main hardware Description
RFID Module
This module can be directly loaded into various reader modules. It utilizes a voltage of 3.3V, through the SPI interface with simply a few wires. Directly connected with a CPU motherboard, the module can work in a stable and reliable manner as a distance card reader.
STONE STWI070WT-01 display
The STWI070WT-01 has been conceived as TFT monitor & Touch controller. It includes processor, control program, driver, flash memory, RS232/RS422/RS485/TTL/LAN port, Wi-Fi/Bluetooth, touch screen, power supply etc., so it is a whole display system based on the powerful & easy operating system, which can be controlled by Any MCU.
Connection diagram
GUI design
Code sharing
Main.py
import mfrc522
import time
import _thread
from os import uname
from machine import Pin, UART
#from pyb import UART
#import machine
suos = Pin(32,Pin.OUT)
uart2 = UART(2, baudrate=115200, rx=16,tx=17,timeout=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 = False
password_flag = False
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]
edit2_cmd = [16,113]
edit3_cmd = [16,114]
if 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():
try:
(stat, tag_type) = rdr.request(rdr.REQIDL)
if stat == rdr.OK:
(stat, raw_uid) = rdr.anticoll()
if stat == rdr.OK:
print(“New card detected”)
print(” – tag type: 0x%02x” % tag_type)
print(” – uid : 0x%02x%02x%02x%02x” % (raw_uid[0], raw_uid[1], raw_uid[2], raw_uid[3]))
print(“”)
if rdr.select_tag(raw_uid) == rdr.OK:
key = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
if 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()
if stat == rdr.OK:
print(“Data written to card”)
else:
print(“Failed to write data to card”)
else:
print(“Authentication error”)
else:
print(“Failed to select tag”)
except KeyboardInterrupt:
print(“write error”)
def do_read():
while True:
try:
(stat, tag_type) = rdr.request(rdr.REQIDL)
if stat == rdr.OK:
(stat, raw_uid) = rdr.anticoll()
if stat == rdr.OK:
print(“New card detected”)
print(” – tag type: 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])
print(“”)
if rdr.select_tag(raw_uid) == rdr.OK:
key = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
if rdr.auth(rdr.AUTHENT1A, 8, key, raw_uid) == rdr.OK:
print(“Address 8 data: %s” % rdr.read(8))
for ps in personnel_id:
if raw_uid[0:4:1] == personnel_id.get(ps):
suos.value(1)
print(ps)
uart_write(ps, *raw_uid[0:4:1])
time.sleep(3)
uart2.sendbreak()
break
rdr.stop_crypto1()
time.sleep(3)
suos.value(0)
else:
print(“Authentication error”)
else:
print(“Failed to select tag”)
if uart2.any()>1:
rx2 = []
data_name2 = ”
bin_data = uart2.read(40)
uart2.sendbreak()
rx1 = list(bin_data)
for item in rx1:
rx2.append(chr(item))
print(rx2)
if 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)
print(data_name2)
if data_name2 == ‘back3’:
return
except KeyboardInterrupt:
print(“read error”)
def do_read2 (idd):
print(idd)
while True:
try:
(stat, tag_type) = rdr.request(rdr.REQIDL)
if stat == rdr.OK:
(stat, raw_uid) = rdr.anticoll()
if stat == rdr.OK:
print(“New card detected”)
print(” – tag type: 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])
print(“”)
if rdr.select_tag(raw_uid) == rdr.OK:
key = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
if rdr.auth(rdr.AUTHENT1A, 8, key, raw_uid) == rdr.OK:
print(“Address 8 data: %s” % rdr.read(8))
personnel_id[idd] = raw_uid[0:4:1]
uart_write3(*raw_uid[0:4:1])
rdr.stop_crypto1()
else:
print(“Authentication error”)
else:
print(“Failed to select tag”)
if uart2.any()>1:
rx2 = []
data_name2 = ”
bin_data = uart2.read(40)
uart2.sendbreak()
rx1 = list(bin_data)
for item in rx1:
rx2.append(chr(item))
if 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)
print(data_name2)
if data_name2 == ‘back1’:
return
except KeyboardInterrupt:
print(“read error”)
def uart_write(text, *ids):
# print(text, *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(text,text2):
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(text,text2):
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():
while True:
if uart2.any():
user_id = ”
password = ”
rx2 = []
rx_num = 0
bin_data = uart2.read(40)
uart2.sendbreak()
rx1 = list(bin_data)
for item in rx1:
rx2.append(chr(item))
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)
if data_id_st2 == ‘edit1’:
data_id_st3 = rx2[15:data_end:1]
data_id_st4 = ”.join(data_id_st3)
print(data_id_st4)
if data_id_st4 != ”:
name = True
elif data_id_st2 == ‘edit2’:
data_id_st5 = rx2[15:data_end:1]
data_id_st6 = ”.join(data_id_st5)
if data_id_st6 == admin_password:
admin = True
uart_write2(‘Verification passed!’,’Please place the card!’)
do_read2(data_id_st4)
return
def mima_zuce():
temp_id3 = ”
temp_mima3 = ”
while True:
if uart2.any():
user_id = ”
password = ”
rx2 = []
rx_num = 0
# data_end = 0
bin_data = uart2.read(40)
uart2.sendbreak()
rx1 = list(bin_data)
for item in rx1:
rx2.append(chr(item))
rx_num += 1
# if (rx2[rx_num] == ‘T’) and (rx2[rx_num-1] == ‘E’) and (rx2[rx_num-2] == ‘>’):
# break
data_end = rx_num-5
data_id_st = rx2[8:13:1]
data_id_st2 = ”.join(data_id_st)
print(data_id_st2)
if 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)
print(data_name2)
if data_name2 == ‘back2’:
return
if data_id_st2 == ‘edit3’:
data_id_st3 = rx2[15:data_end:1]
data_id_st4 = ”.join(data_id_st3)
print(data_id_st4)
user_id_flag = True
temp_id3 = data_id_st4
# personnel_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)
print(data_id_st6)
# if personnel_ps.get(temp_id) == data_id_st6:
password_flag = True
temp_mima3 = data_id_st6
# personnel_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)
if (data_id_st6 == admin_password) and (password_flag == True) and (user_id_flag == True):
admin = True
personnel_ps[temp_id3] = temp_mima3
password_flag = False
user_id_flag = False
uart_write4(‘Verification passed!’,’login was successful!’)
def password_loin():
temp_id2 = ”
temp_mima = ”
while True:
if uart2.any():
user_id = ”
password = ”
rx2 = []
rx_num = 0
# data_end = 0
bin_data = uart2.read(40)
uart2.sendbreak()
rx1 = list(bin_data)
for item in rx1:
rx2.append(chr(item))
rx_num += 1
# if (rx2[rx_num] == ‘T’) and (rx2[rx_num-1] == ‘E’) and (rx2[rx_num-2] == ‘>’):
# break
data_end = rx_num-5
data_id_st = rx2[8:13:1]
data_id_st2 = ”.join(data_id_st)
print(data_id_st2)
if 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)
print(data_name2)
if data_name2 == ‘back4’:
return
if data_id_st2 == ‘edit5’:
data_id_st3 = rx2[15:data_end:1]
data_id_st4 = ”.join(data_id_st3)
print(data_id_st4)
if data_id_st4 in personnel_ps:
user_id_flag = 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)
print(data_id_st6)
print(temp_id2)
print(personnel_ps)
if personnel_ps.get(temp_id2) == data_id_st6:
password_flag = True
# print(rx2,user_id_flag,password_flag)
print(user_id_flag,password_flag)
if (password_flag == True) and (user_id_flag == True):
uart_write(temp_id2,temp_id2)
password_flag = False
user_id_flag = False
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(‘student’,”)
suos.value(0)
uart2.write(‘ST<{“cmd_code”:”set_visible”,”type”:”widget”,”widget”:”lock2″,”visible”:false}>ET’)
uart2.sendbreak()
while True:
if uart2.any()>1:
rx2 = []
data_name2 = ”
bin_data = uart2.read(40)
# time.sleep(1)
uart2.sendbreak()
# time.sleep(1)
rx1 = list(bin_data)
for item in rx1:
rx2.append(chr(item))
print(rx2)
if 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)
print(data_name2)
if data_name2 == ‘card1’:
card_zhuce()
elif data_name2 == ‘password1’:
mima_zuce()
elif data_name2 == ‘card2’:
do_read()
elif data_name2 == ‘password2’:
password_loin()
MFRC522.py
from machine import Pin, SPI
from os import uname
class MFRC522:
OK = 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(rst, Pin.OUT)
self.cs = Pin(cs, Pin.OUT)
self.rst.value(0)
self.cs.value(1)
board = uname()[0]
if board == ‘WiPy’ or board == ‘LoPy’ or board == ‘FiPy’:
self.spi = SPI(0)
self.spi.init(SPI.MASTER, baudrate=1000000, pins=(self.sck, self.mosi, self.miso))
elif board == ‘esp32′:
self.spi = SPI(baudrate=100000, polarity=0, phase=0, sck=self.sck, mosi=self.mosi, miso=self.miso)
self.spi.init()
else:
raise RuntimeError(“Unsupported platform”)
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)
return val[0]
def _sflags(self, reg, mask):
self._wreg(reg, self._rreg(reg) | mask)
def _cflags(self, reg, mask):
self._wreg(reg, self._rreg(reg) & (~mask))
def _tocard(self, cmd, send):
recv = []
bits = irq_en = wait_irq = n = 0
stat = self.ERR
if 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)
for c in send:
self._wreg(0x09, c)
self._wreg(0x01, cmd)
if cmd == 0x0C:
self._sflags(0x0D, 0x80)
i = 2000
while True:
n = self._rreg(0x04)
i -= 1
if ~((i != 0) and ~(n & 0x01) and ~(n & wait_irq)):
break
self._cflags(0x0D, 0x80)
if i:
if (self._rreg(0x06) & 0x1B) == 0x00:
stat = self.OK
if n & irq_en & 0x01:
stat = self.NOTAGERR
elif cmd == 0x0C:
n = self._rreg(0x0A)
lbits = self._rreg(0x0C) & 0x07
if lbits != 0:
bits = (n – 1) * 8 + lbits
else:
bits = n * 8
if n == 0:
n = 1
elif n > 16:
n = 16
for _ in range(n):
recv.append(self._rreg(0x09))
else:
stat = self.ERR
return stat, recv, bits
def _crc(self, data):
self._cflags(0x05, 0x04)
self._sflags(0x0A, 0x80)
for c in data:
self._wreg(0x09, c)
self._wreg(0x01, 0x03)
i = 0xFF
while True:
n = self._rreg(0x05)
i -= 1
if not ((i != 0) and not (n & 0x04)):
break
return [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()
def reset(self):
self._wreg(0x01, 0x0F)
def antenna_on(self, on=True):
if on and ~(self._rreg(0x14) & 0x03):
self._sflags(0x14, 0x03)
else:
self._cflags(0x14, 0x03)
def request(self, mode):
self._wreg(0x0D, 0x07)
(stat, recv, bits) = self._tocard(0x0C, [mode])
if (stat != self.OK) | (bits != 0x10):
stat = self.ERR
return stat, bits
def anticoll(self):
ser_chk = 0
ser = [0x93, 0x20]
self._wreg(0x0D, 0x00)
(stat, recv, bits) = self._tocard(0x0C, ser)
if stat == self.OK:
if len(recv) == 5:
for i in range(4):
ser_chk = ser_chk ^ recv[i]
if ser_chk != recv[4]:
stat = self.ERR
else:
stat = self.ERR
return stat, recv
def select_tag(self, ser):
buf = [0x93, 0x70] + ser[:5]
buf += self._crc(buf)
(stat, recv, bits) = self._tocard(0x0C, buf)
return self.OK if (stat == self.OK) and (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):
self._cflags(0x08, 0x08)
def read(self, addr):
data = [0x30, addr]
data += self._crc(data)
(stat, recv, _) = self._tocard(0x0C, data)
return recv if stat == self.OK else None
def write(self, addr, data):
buf = [0xA0, addr]
buf += self._crc(buf)
(stat, recv, bits) = self._tocard(0x0C, buf)
if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
stat = self.ERR
else:
buf = []
for i in range(16):
buf.append(data[i])
buf += self._crc(buf)
(stat, recv, bits) = self._tocard(0x0C, buf)
if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
stat = self.ERR
return stat
Video demo
Aric is a tech enthusiast , who love to write about the tech related products and ‘How To’ blogs . IT Engineer by profession , right now working in the Automation field in a Software product company . The other hobbies includes singing , trekking and writing blogs .