原理介紹
RFID,也稱為射頻識別,是一種通訊技術。它可以通過無線電信號識別特定目標並讀取和寫入資料,而無需在識別系統和特定目標之間建立機械或光學接觸。射頻一般為微波,1-100GHz,適合短距離識別通訊。
RFID讀寫器也分為移動和固定類型。目前RFID技術應用廣泛,如: 圖書館,門禁系統,食品安全可追溯性等。
電路圖
程式列表
Python – mfrc522.py
"""
mfrc522.py
Reference: https://github.com/wendlers/micropython-mfrc522
"""
from machine import Pin, SPI
class MFRC522:
OK = 0
NOTAGERR = 1
ERR = 2
REQIDL = 0x26
REQALL = 0x52
AUTHENT1A = 0x60
AUTHENT1B = 0x61
def __init__(self, rst, cs):
self.rst = Pin(rst, Pin.OUT)
self.cs = Pin(cs, Pin.OUT)
self.rst.value(0)
self.cs.value(1)
self.spi = SPI(sck=Pin.board.CLK0, miso=Pin.board.MISO, mosi=Pin.board.MOSI)
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
Python – ePy-Lite_MFRC522.py
"""
ePy-Lite_MFRC522.py
------------------------------------------
ePy-Lite MFRC522 Reader
Pin Signal Pin
----------------------------------------
P9(CS) SS SDA(SS)
P8(CLK) Clock SCK
P6(MOSI) Data in MOSI
P7(MISO) Data Out MISO
IRQ
GND GND GND
P10 RST/Reset RST
3V3 3V3 3V3
"""
from micropython import const
from machine import SPI, Pin
from machine import Switch #Get button KEY library
import utime
import mfrc522
spi_0 = None
test = None
# test = 1 #write test
def do_read(addr):
(stat, tag_type) = rdr.request(rdr.REQIDL) #Search for RFID cards
if stat == rdr.OK: #Find the card
(stat, raw_uid) = rdr.anticoll() #Read RFID card number
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, addr, key, raw_uid) == rdr.OK:
print("Address %d data: %s" % (addr,rdr.read(addr)))
rdr.stop_crypto1()
else:
print("Authentication error")
else:
print("Failed to select tag")
def do_write(addr, data):
(stat, tag_type) = rdr.request(rdr.REQIDL) #Search for RFID cards
if stat == rdr.OK: #Find the card
(stat, raw_uid) = rdr.anticoll() #Read RFID card number
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, addr, key, raw_uid) == rdr.OK:
stat = rdr.write(addr, data)
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")
# Start Function
if __name__=="__main__":
buf = bytearray(16)
Num1 = 0
KeyA = Switch('keya') #Create button A
rdr = mfrc522.MFRC522(Pin.board.P10, Pin.board.P9) #rst, cs
utime.sleep_ms(1000)
print("")
if test != None:
print("Place card before reader to write address 0x08")
else:
print("Place card before reader to read from address 0x08")
print("")
while True:
if test != None:
for i in range(16):
buf[i] = Num1 + i
do_write(8,buf)
Num1=Num1+1
else:
do_read(8)
if (KeyA.value()) == True: #Press A Key
break
utime.sleep_ms(500)
# spi_0.deinit()
執行結果