Krótkie wprowadzenie
Inteligentny dom staje się coraz bardziej powszechny wraz z rozwojem technologii, w tym artykule skupimy się na aspektach bezpieczeństwa projektu inteligentnej kontroli dostępu.
Ten artykuł wykorzystuje Ekran dotykowy STONE do wysyłania poleceń do MCU w celu sterowania przekaźnikiem i modułem MFRC522.
Zasada czytania kart: sterując modułem RFID-RC522, zidentyfikuj identyfikator dowodu osobistego w pobliżu dowodu osobistego, a następnie określ, czy identyfikator istnieje w bazie danych słowa typowy, identyfikator jest typową wartością słowa, jeśli istnieje weryfikacja poprzez , a następnie wydrukuj odpowiednią nazwę, a następnie w ten sam sposób uruchom zamek elektromagnetyczny.
Potrzebne materiały
- ESP32
- Zamek elektroniczny KOB
- Przekaźnik
- Wyświetlacz dotykowy STONE STWI070WT-01
- Moduł MFRC522
Zrealizowana funkcja
- rejestracja karty.
- rejestracja nazwy użytkownika i hasła.
- przeciągnij kartę, aby odblokować zamek elektroniczny.
- Nazwa użytkownika i hasło do odblokowania zamka elektronicznego.
Główny opis sprzętu
Moduł RFID
Ten moduł może być bezpośrednio ładowany do różnych modułów czytników. Wykorzystuje napięcie 3.3 V przez interfejs SPI za pomocą zaledwie kilku przewodów. Bezpośrednio połączony z płytą główną procesora, moduł może pracować stabilnie i niezawodnie jako czytnik kart odległościowych.
STWI070WT-01 został pomyślany jako monitor TFT i kontroler dotykowy. Zawiera procesor, program sterujący, sterownik, pamięć flash, port RS232/RS422/RS485/TTL/LAN, Wi-Fi/Bluetooth, ekran dotykowy, zasilacz itp., więc jest to cały system wyświetlania oparty na potężnym i łatwym system operacyjny, który może być kontrolowany przez dowolny MCU.
Projekt GUI
Udostępnianie kodu
importuj mfrc522
czas importu
importuj _wątek
z systemu operacyjnego importuj uname
z maszyny importu Pin, UART
#z pyb importuj UART
#importuj maszynę
suos = Pin(32,Pin.OUT)
uart2 = UART(2, szybkość transmisji=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 = []
nazwa_rx = []
user_id_flag = Fałsz
flaga_hasła = Fałsz
temp_id = ”
temp_mima = ”
person_id = {'zbw':[236,230,169,47],'lbw':[19,165,93,4]}
person_ps = {'zbw':'zbw3366′,'lbw':'lbwnb'}
admin_password = ('rrrr')
przycisk_cmd = [16,1]
edit1_cmd = [16,112 XNUMX]
edit2_cmd = [16,113 XNUMX]
edit3_cmd = [16,114 XNUMX]
if uname()[0] == 'esp32':
rdr = mfrc522.MFRC522(ESP32_HSPI_CLOCK, ESP32_HSPI_MOSI, ESP32_HSPI_MISO, ESP32_MFRC522_RST, ESP32_HSPI_SLAVE_SELECT)
zdecydowanie do_write():
spróbuj:
(statystyka, typ_tagu) = rdr.request(rdr.REQIDL)
jeśli stat == rdr.OK:
(statystyka, surowy_uid) = rdr.anticoll()
jeśli stat == rdr.OK:
print(„Wykryto nową kartę”)
print(” – typ tagu: 0x%02x” % typ_tagu)
print(” – uid : 0x%02x%02x%02x%02x” % (surowy_uid[0], surowy_uid[1], surowy_uid[2], surowy_uid[3]))
wydrukować("")
if rdr.select_tag(raw_uid) == rdr.OK:
klucz = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
if rdr.auth(rdr.AUTHENT1A, 8, klucz, surowy_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()
jeśli stat == rdr.OK:
print("Dane zapisane na karcie")
jeszcze:
print("Nie udało się zapisać danych na karcie")
jeszcze:
print("Błąd uwierzytelniania")
jeszcze:
print(„Nie udało się wybrać tagu”)
oprócz KeyboardInterrupt:
print("błąd zapisu")
zdecydowanie do_read():
podczas gdy prawda:
spróbuj:
(statystyka, typ_tagu) = rdr.request(rdr.REQIDL)
jeśli stat == rdr.OK:
(statystyka, surowy_uid) = rdr.anticoll()
jeśli stat == rdr.OK:
print(„Wykryto nową kartę”)
print(” – typ tagu: 0x%02x” % typ_tagu)
print(” – uid : 0x%02x%02x%02x%02x” % (surowy_uid[0], surowy_uid[1], surowy_uid[2], surowy_uid[3]))
print (surowy_uid[0], surowy_uid[1], surowy_uid[2], surowy_uid[3])
wydrukować("")
if rdr.select_tag(raw_uid) == rdr.OK:
klucz = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
if rdr.auth(rdr.AUTHENT1A, 8, klucz, surowy_uid) == rdr.OK:
print(„Dane adresu 8: %s” % rdr.read(8))
dla ps w personal_id:
if raw_uid[0:4:1] ==person_id.get(ps):
suos.wartość(1)
druk (ps)
uart_write(ps, *raw_uid[0:4:1])
time.sleep (3)
uart2.sendbreak()
złamać
rdr.stop_crypto1()
time.sleep (3)
suos.wartość(0)
jeszcze:
print("Błąd uwierzytelniania")
jeszcze:
print(„Nie udało się wybrać tagu”)
jeśli uart2.any()>1:
rx2 = []
nazwa_danych2 = ”
bin_data = uart2.odczyt(40)
uart2.sendbreak()
rx1 = lista(bin_data)
dla pozycji w rx1:
rx2.append(chr(element))
drukuj(rx2)
jeśli rx1[3:5:1] == przycisk_cmd:
nazwa_danych_len = rx1[6] – 1
nazwa_danych = rx2[7:nazwa_danych_len+7:1]
nazwa_danych2 = ”.join(nazwa_danych)
drukuj(nazwa_danych2)
if data_name2 == 'back3':
powrót
oprócz KeyboardInterrupt:
print(„błąd odczytu”)
def do_read2 (idd):
drukuj(idd)
podczas gdy prawda:
spróbuj:
(statystyka, typ_tagu) = rdr.request(rdr.REQIDL)
jeśli stat == rdr.OK:
(statystyka, surowy_uid) = rdr.anticoll()
jeśli stat == rdr.OK:
print(„Wykryto nową kartę”)
print(” – typ tagu: 0x%02x” % typ_tagu)
print(” – uid : 0x%02x%02x%02x%02x” % (surowy_uid[0], surowy_uid[1], surowy_uid[2], surowy_uid[3]))
print (surowy_uid[0], surowy_uid[1], surowy_uid[2], surowy_uid[3])
wydrukować("")
if rdr.select_tag(raw_uid) == rdr.OK:
klucz = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
if rdr.auth(rdr.AUTHENT1A, 8, klucz, surowy_uid) == rdr.OK:
print(„Dane adresu 8: %s” % rdr.read(8))
identyfikator_personelu[idd] = identyfikator_surowy[0:4:1]
uart_write3(*raw_uid[0:4:1])
rdr.stop_crypto1()
jeszcze:
print("Błąd uwierzytelniania")
jeszcze:
print(„Nie udało się wybrać tagu”)
jeśli uart2.any()>1:
rx2 = []
nazwa_danych2 = ”
bin_data = uart2.odczyt(40)
uart2.sendbreak()
rx1 = lista(bin_data)
dla pozycji w rx1:
rx2.append(chr(element))
jeśli rx1[3:5:1] == przycisk_cmd:
nazwa_danych_len = rx1[6] – 1
nazwa_danych = rx2[7:nazwa_danych_len+7:1]
nazwa_danych2 = ”.join(nazwa_danych)
drukuj(nazwa_danych2)
if data_name2 == 'back1':
powrót
oprócz KeyboardInterrupt:
print(„błąd odczytu”)
def uart_write(tekst, *ids):
# print(tekst, *id)
uart2.write('ST<{“kod_cmd”:”ustaw_tekst”,”typ”:”etykieta”,”widget”:”nazwakarty1″”,tekst”:”'+str(tekst)+'”}>ET' )
uart2.write('ST<{“cmd_code”:”set_text”,”typ”:”etykieta”,”widget”:”cardid1″”,text”:”'+str(ids)+'”}>ET' )
uart2.write('ST<{“cmd_code”:”set_visible”,”typ”:”widget”,”widget”:”lock1″”,visible”:true}>ET')
time.sleep (3)
uart2.write('ST<{“kod_cmd”:”ustaw_tekst”,”typ”:”etykieta”,”widget”:”nazwakarty1″”,tekst”:”””}>ET')
uart2.write('ST<{“cmd_code”:”set_text”,”typ”:”etykieta”,”widget”:”cardid1″”,text”:”””}>ET')
uart2.write('ST<{“cmd_code”:”set_visible”,”typ”:”widget”,”widget”:”lock1″”,visible”:false}>ET')
def uart_write2(tekst,tekst2):
uart2.write('ST<{“cmd_code”:”set_text”,”typ”:”etykieta”,”widget”:”cardid”,”text”:”'+tekst+'”}>ET')
time.sleep (3)
uart2.write('ST<{“cmd_code”:”set_text”,”typ”:”etykieta”,”widget”:”cardid”,”text”:”'+text2+'”}>ET')
uart2.write('ST<{“kod_cmd”:”ustaw_tekst”,”typ”:”etykieta”,”widget”:”edytuj2″”,tekst”:”””}>ET')
def uart_write3(*id2):
uart2.write('ST<{“cmd_code”:”set_text”,”typ”:”etykieta”,”widget”:”cardid”,”text”:”'+str(id2)+'”}>ET' )
time.sleep (3)
uart2.write('ST<{“cmd_code”:”set_text”,”typ”:”etykieta”,”widget”:”cardid”,”tekst”:”””}>ET')
def uart_write4(tekst,tekst2):
uart2.write('ST<{“kod_cmd”:”ustaw_tekst”,”typ”:”etykieta”,”widget”:”login”,”tekst”:”'+tekst+'”}>ET')
time.sleep (1)
uart2.write('ST<{“cmd_code”:”set_text”,”typ”:”etykieta”,”widget”:”login”,”tekst”:”'+text2+'”}>ET')
time.sleep (1)
uart2.write('ST<{“kod_cmd”:”ustaw_tekst”,”typ”:”etykieta”,”widget”:”edytuj3″”,tekst”:”””}>ET')
uart2.write('ST<{“kod_cmd”:”ustaw_tekst”,”typ”:”etykieta”,”widget”:”edytuj4″”,tekst”:”””}>ET')
uart2.write('ST<{“kod_cmd”:”ustaw_tekst”,”typ”:”etykieta”,”widget”:”edytuj7″”,tekst”:”””}>ET')
def uart_write5():
uart2.write('ST<{“cmd_code”:”set_text”,”typ”:”etykieta”,”widget”:”cardid”,”text”:”'+str(id2)+'”}>ET' )
time.sleep (3)
uart2.write('ST<{“cmd_code”:”set_text”,”typ”:”etykieta”,”widget”:”cardid”,”tekst”:”””}>ET')
def card_zhuce():
podczas gdy prawda:
jeśli uart2.any():
identyfikator_użytkownika = ”
hasło = ”
rx2 = []
rx_num = 0
bin_data = uart2.odczyt(40)
uart2.sendbreak()
rx1 = lista(bin_data)
dla pozycji w rx1:
rx2.append(chr(element))
rx_num += 1
koniec_danych = rx_num-5
identyfikator_danych = rx2 [8:13:1]
data_id_st2 = .join(data_id_st)
drukuj(data_id_st2)
if data_id_st2 == 'edytuj1':
data_id_st3 = rx2[15:data_end:1]
data_id_st4 = .join(data_id_st3)
drukuj(data_id_st4)
jeśli data_id_st4 != ”:
nazwa = prawda
elif data_id_st2 == 'edytuj2':
data_id_st5 = rx2[15:data_end:1]
data_id_st6 = .join(data_id_st5)
if data_id_st6 == hasło_administratora:
administrator = Prawda
uart_write2('Weryfikacja przeszła!','Proszę umieścić kartę!')
do_read2(data_id_st4)
powrót
zdecydowanie mima_zuce():
temp_id3 = ”
temp_mima3 = ”
podczas gdy prawda:
jeśli uart2.any():
identyfikator_użytkownika = ”
hasło = ”
rx2 = []
rx_num = 0
# data_end = 0
bin_data = uart2.odczyt(40)
uart2.sendbreak()
rx1 = lista(bin_data)
dla pozycji w rx1:
rx2.append(chr(element))
rx_num += 1
# if (rx2[rx_num] == 'T') and (rx2[rx_num-1] == 'E') and (rx2[rx_num-2] == '>'):
# przerwa
koniec_danych = rx_num-5
identyfikator_danych = rx2 [8:13:1]
data_id_st2 = .join(data_id_st)
drukuj(data_id_st2)
jeśli rx1[3:5:1] == przycisk_cmd:
nazwa_danych_len = rx1[6] – 1
nazwa_danych = rx2[7:nazwa_danych_len+7:1]
nazwa_danych2 = ”.join(nazwa_danych)
drukuj(nazwa_danych2)
if data_name2 == 'back2':
powrót
if data_id_st2 == 'edytuj3':
data_id_st3 = rx2[15:data_end:1]
data_id_st4 = .join(data_id_st3)
drukuj(data_id_st4)
flaga_identyfikatora_użytkownika = Prawda
temp_id3 = id_danych_st4
# personel_ps[temp_id] = surowy_uid[0:4:1]
elif data_id_st2 == 'edytuj4':
data_id_st5 = rx2[15:data_end:1]
data_id_st6 = .join(data_id_st5)
drukuj(data_id_st6)
# if person_ps.get(temp_id) == data_id_st6:
hasło_flaga = Prawda
temp_mima3 = identyfikator_danych_st6
#person_ps[temp_id] = hasło_flaga
# print(rx2,flaga_identyfikatora_użytkownika,flaga_hasła)
elif data_id_st2 == 'edytuj7':
data_id_st5 = rx2[15:data_end:1]
data_id_st6 = .join(data_id_st5)
if (data_id_st6 == admin_password) i (password_flag == True) oraz (user_id_flag == True):
administrator = Prawda
personel_ps[temp_id3] = temp_mima3
flaga_hasła = Fałsz
user_id_flag = Fałsz
uart_write4('Weryfikacja przeszła!','Logowanie powiodło się!')
def hasło_loin():
temp_id2 = ”
temp_mima = ”
podczas gdy prawda:
jeśli uart2.any():
identyfikator_użytkownika = ”
hasło = ”
rx2 = []
rx_num = 0
# data_end = 0
bin_data = uart2.odczyt(40)
uart2.sendbreak()
rx1 = lista(bin_data)
dla pozycji w rx1:
rx2.append(chr(element))
rx_num += 1
# if (rx2[rx_num] == 'T') and (rx2[rx_num-1] == 'E') and (rx2[rx_num-2] == '>'):
# przerwa
koniec_danych = rx_num-5
identyfikator_danych = rx2 [8:13:1]
data_id_st2 = .join(data_id_st)
drukuj(data_id_st2)
jeśli rx1[3:5:1] == przycisk_cmd:
nazwa_danych_len = rx1[6] – 1
nazwa_danych = rx2[7:nazwa_danych_len+7:1]
nazwa_danych2 = ”.join(nazwa_danych)
drukuj(nazwa_danych2)
if data_name2 == 'back4':
powrót
if data_id_st2 == 'edytuj5':
data_id_st3 = rx2[15:data_end:1]
data_id_st4 = .join(data_id_st3)
drukuj(data_id_st4)
jeśli data_id_st4 w person_ps:
flaga_identyfikatora_użytkownika = Prawda
temp_id2 = id_danych_st4
elif data_id_st2 == 'edytuj6':
data_id_st5 = rx2[15:data_end:1]
data_id_st6 = .join(data_id_st5)
drukuj(data_id_st6)
drukuj(temp_id2)
drukuj(personel_ps)
if staff_ps.get(temp_id2) == data_id_st6:
hasło_flaga = Prawda
# print(rx2,flaga_identyfikatora_użytkownika,flaga_hasła)
drukuj(flaga_identyfikatora_użytkownika,flaga_hasła)
if (password_flag == True) i (user_id_flag == True):
uart_write(temp_id2,temp_id2)
flaga_hasła = Fałsz
user_id_flag = Fałsz
suos.wartość(1)
uart2.write('ST<{“cmd_code”:”set_visible”,”typ”:”widget”,”widget”:”lock2″”,visible”:true}>ET')
uart2.write('ST<{“kod_cmd”:”ustaw_tekst”,”typ”:”etykieta”,”widget”:”edytuj5″”,tekst”:”””}>ET')
uart2.write('ST<{“kod_cmd”:”ustaw_tekst”,”typ”:”etykieta”,”widget”:”edytuj6″”,tekst”:”””}>ET')
time.sleep (3)
# uart_write('student',”)
suos.wartość(0)
uart2.write('ST<{“cmd_code”:”set_visible”,”typ”:”widget”,”widget”:”lock2″”,visible”:false}>ET')
uart2.sendbreak()
podczas gdy prawda:
jeśli uart2.any()>1:
rx2 = []
nazwa_danych2 = ”
bin_data = uart2.odczyt(40)
# czas.sen(1)
uart2.sendbreak()
# czas.sen(1)
rx1 = lista(bin_data)
dla pozycji w rx1:
rx2.append(chr(element))
drukuj(rx2)
jeśli rx1[3:5:1] == przycisk_cmd:
nazwa_danych_len = rx1[6] – 1
nazwa_danych = rx2[7:nazwa_danych_len+7:1]
nazwa_danych2 = ”.join(nazwa_danych)
drukuj(nazwa_danych2)
if data_name2 == 'karta1':
card_zuce()
elif data_name2 == 'hasło1':
mima_zuce()
elif data_name2 == 'karta2':
zrób_odczytaj()
elif data_name2 == 'hasło2':
hasło_loin()
MFRC522.py
z maszyny importu Pin, SPI
z systemu operacyjnego importuj uname
klasa MFRC522:
w porządku = 0
NOTAGERRR = 1
BŁĄD = 2
REQIDL = 0x26
PRZYWRÓĆ = 0x52
AUTENTYCZNY1A = 0x60
AUTENTYCZNY1B = 0x61
def __init__(self, sck, mosi, miso, pierwszy, cs):
self.sck = Pin(sck, Pin.OUT)
self.mosi = Pin(mosi, Pin.OUT)
self.miso = Przypnij(miso)
self.rst = Pin(pierwszy, Pin.OUT)
self.cs = Pin(cs, Pin.OUT)
własna.pierwsza.wartość(0)
własna.cs.wartość(1)
tablica = uname()[0]
if plansza == 'WiPy' lub plansza == 'LoPy' lub plansza == 'FiPy':
self.spi = SPI(0)
self.spi.init(SPI.MASTER, szybkość transmisji=1000000, piny=(self.sck, self.mosi, self.miso))
tablica elif == 'esp32':
self.spi = SPI(szybkość transmisji=100000, polaryzacja=0, faza=0, sck=self.sck, mosi=self.mosi, miso=self.miso)
self.spi.init()
jeszcze:
podnieść RuntimeError („Nieobsługiwana platforma”)
własna.pierwsza.wartość(1)
samo.init()
def _wreg(self, reg, wartość):
własna.cs.wartość(0)
self.spi.write(b'%c' % int(0xff & ((reg << 1) & 0x7e)))
self.spi.write(b'%c' % int(0xff & val))
własna.cs.wartość(1)
def _rreg(samo, reg):
własna.cs.wartość(0)
self.spi.write(b'%c' % int(0xff & (((reg << 1) & 0x7e) | 0x80)))
val = własny.spi.odczyt(1)
własna.cs.wartość(1)
wartość zwrotu[0]
def _sflags(self,reg,maska):
self._wreg(reg, self._rreg(reg) | maska)
def _cflags(ja, reg, maska):
self._wreg(reg, self._rreg(reg) & (~maska))
def _tocard(self, cmd, wyślij):
recv = []
bity = irq_en = wait_irq = n = 0
stat = własny.BŁĄD
jeśli cmd == 0x0E:
irq_pl = 0x12
czekanie_irq = 0x10
elif cmd == 0x0C:
irq_pl = 0x77
czekanie_irq = 0x30
self._wreg(0x02, irq_en | 0x80)
self._cflags (0x04, 0x80)
self._sflags (0x0A, 0x80)
self._wreg(0x01, 0x00)
dla c w wyślij:
self._wreg(0x09, c)
self._wreg(0x01, cmd)
jeśli cmd == 0x0C:
self._sflags (0x0D, 0x80)
i = 2000
podczas gdy prawda:
n = własny._rreg(0x04)
ja -= 1
if ~((i != 0) i ~(n & 0x01) oraz ~(n & wait_irq)):
złamać
self._cflags(0x0D, 0x80)
Jeśli ja:
if (self._rreg(0x06) & 0x1B) == 0x00:
stat = self.OK
if n & irq_en & 0x01:
stat = self.NOTAGERR
elif cmd == 0x0C:
n = własny._rreg (0x0A)
lbits = self._rreg (0x0C) i 0x07
jeśli funty != 0:
bity = (n – 1) * 8 + lbits
jeszcze:
bity = n * 8
jeśli n == 0:
n = 1
elif n > 16:
n = 16
dla _ w zakresie(n):
recv.append(self._rreg(0x09))
jeszcze:
stat = własny.BŁĄD
statystyki zwrotu, recv, bity
def _crc(samo, dane):
self._cflags (0x05, 0x04)
self._sflags (0x0A, 0x80)
dla c w danych:
self._wreg(0x09, c)
self._wreg(0x01, 0x03)
ja = 0xFF
podczas gdy prawda:
n = własny._rreg(0x05)
ja -= 1
jeśli nie ((i != 0) i nie (n & 0x04)):
złamać
powrót [self._rreg(0x22), self._rreg(0x21)]
def init(samodzielnie):
samo.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.antena_on()
resetowanie ustawień (samodzielnie):
self._wreg(0x01, 0x0F)
def antena_on(self, on=True):
jeśli włączone i ~(self._rreg(0x14) & 0x03):
self._sflags(0x14, 0x03)
jeszcze:
self._cflags (0x14, 0x03)
def request(self, tryb):
self._wreg(0x0D, 0x07)
(statystyka, recv, bity) = self._tocard(0x0C, [tryb])
if (stat != self.OK) | (bity != 0x10):
stat = własny.BŁĄD
zwróć statystykę, bity
def anticoll(samo):
ser_chk = 0
ser = [0x93, 0x20]
self._wreg(0x0D, 0x00)
(statystyka, recv, bity) = self._tocard(0x0C, ser)
jeśli stat == self.OK:
jeśli len(recv) == 5:
dla i w zakresie (4):
ser_chk = ser_chk ^ recv[i]
jeśli ser_chk != recv[4]:
stat = własny.BŁĄD
jeszcze:
stat = własny.BŁĄD
statystyka zwrotów, recv
def wybierz_tag(self, ser):
buf = [0x93, 0x70] + ser[:5]
buf += self._crc(buf)
(statystyka, recv, bity) = self._tocard(0x0C, buf)
return self.OK if (stat == self.OK) i (bity == 0x18) w przeciwnym razie self.ERR
def auth(self, tryb, adres, sekta, ser):
return self._tocard(0x0E, [tryb, adres] + sekta + ser[:4])[0]
def stop_crypto1(ja):
self._cflags (0x08, 0x08)
def read(self, adres):
dane = [0x30, adres]
dane += self._crc(dane)
(statystyka, recv, _) = self._tocard(0x0C, dane)
return recv if stat == self.OK else Brak
def write(self, adres, dane):
buf = [0xA0, adres]
buf += self._crc(buf)
(statystyka, recv, bity) = self._tocard(0x0C, buf)
jeśli nie (stat == self.OK) lub nie (bity == 4) lub nie ((recv[0] & 0x0F) == 0x0A):
stat = własny.BŁĄD
jeszcze:
buf = []
dla i w zakresie (16):
buf.append(dane[i])
buf += self._crc(buf)
(statystyka, recv, bity) = self._tocard(0x0C, buf)
jeśli nie (stat == self.OK) lub nie (bity == 4) lub nie ((recv[0] & 0x0F) == 0x0A):
stat = własny.BŁĄD
zwrot stat
Źródło: Plato Data Intelligence