많이

STONE TFT LCD 및 ESP32 기반 지능형 출입통제

간략한 소개

스마트 홈은 기술의 발전과 함께 점점 더 일반화되고 있습니다. 이 기사에서는 지능형 액세스 제어 프로젝트의 보안 측면에 중점을 둘 것입니다.

이 기사는 사용 STONE의 터치 스크린 릴레이 및 MFRC522 모듈을 제어하기 위해 MCU에 명령을 보냅니다.

카드 읽기의 원리: RFID-RC522 모듈을 구동하여 ID 카드에 가까운 ID 카드 ID를 식별한 다음, 해당 ID가 대표단어의 데이터베이스에 존재하는지 여부를 판별하고, ID는 해당 단어의 대표값, 존재 여부를 통한 검증 , 다음 해당 이름을 인쇄하고 동일한 방식으로 전자기 잠금을 구동합니다.

필수 자료

실현된 기능

  1. 카드 등록.
  2. 사용자 이름 및 암호 등록.
  3. 카드를 스와이프하여 전자 잠금을 해제합니다.
  4. 전자 잠금을 해제하기 위한 사용자 이름과 암호.

주요 하드웨어 설명

RFID 모듈

이 모듈은 다양한 리더 모듈에 직접 로드할 수 있습니다. 몇 개의 전선으로 SPI 인터페이스를 통해 3.3V의 전압을 사용합니다. CPU 마더보드와 직접 연결하여 모듈을 안정적이고 안정적인 방식으로 원거리 카드 리더기로 작동할 수 있습니다.

STONE TFT LCD 및 ESP32 IOT PlatoBlockchain Data Intelligence를 기반으로 한 지능형 출입 통제. 수직 검색. 일체 포함.
STONE TFT LCD 및 ESP32 기반 지능형 출입통제

STWI070WT-01은 TFT 모니터 및 터치 컨트롤러로 고안되었습니다. 프로세서, 제어 프로그램, 드라이버, 플래시 메모리, RS232/RS422/RS485/TTL/LAN 포트, Wi-Fi/Bluetooth, 터치 스크린, 전원 공급 장치 등을 포함하므로 강력하고 쉬운 기반의 전체 디스플레이 시스템입니다. 모든 MCU로 제어할 수 있는 운영 체제.

STONE TFT LCD 및 ESP32 IOT PlatoBlockchain Data Intelligence를 기반으로 한 지능형 출입 통제. 수직 검색. 일체 포함.
STONE TFT LCD 및 ESP32 기반 지능형 출입통제

GUI 디자인

STONE TFT LCD 및 ESP32 IOT PlatoBlockchain Data Intelligence를 기반으로 한 지능형 출입 통제. 수직 검색. 일체 포함.
STONE TFT LCD 및 ESP32 기반 지능형 출입통제

코드 공유

STONE TFT LCD 및 ESP32 IOT PlatoBlockchain Data Intelligence를 기반으로 한 지능형 출입 통제. 수직 검색. 일체 포함.
STONE TFT LCD 및 ESP32 기반 지능형 출입통제

가져오기 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