原理:
通过python实现:
import random
import time
import threading
class Reader_king():
def __init__(self, ack1, command, passwd, handle_back):
self.ack = ack1
self.command = command
self.pwd = passwd
self.handle = handle_back
def printinfo(self_RFID):
print("ack:", self_RFID.ack)
print("命令:", self_RFID.command)
print("密码:", self_RFID.pwd)
print("句柄:", self_RFID.handle)
class RFID_king():
def __init__(self, state, Q, RN16, passwd, handle_back, energy_RFID, epc):
self.state = state
self.Q = Q
self.RN16 = RN16
self.pwd = passwd
self.handle = handle_back
self.energy = energy_RFID
self.epc = epc
def setRN16(self_RFID):
str = ''
a = str.join(random.choice("0123456789") for i in range(16))
#print(a)
self_RFID.RN16 = a
reader = Reader_king(0, '', 0, '')
rfid = RFID_king('', 100, '', 000, 11101, 0, 1001)
exitFlag = 0
class myThread_king(threading.Thread):
def __init__(self_RFID, threadID, name, counter):
threading.Thread.__init__(self_RFID)
self_RFID.threadID = threadID
self_RFID.name = name
self_RFID.counter = counter
def run(self_RFID):
start = time.time()
global x
global e
start = time.time()
print('请输入Req_RN命令:')
x = input()
e = time.time() - start
while 1:
if reader.command == '' or reader.command == 'CW': # 输入命令
reader.command = input('请输入命令:')
if reader.command == "Select" and rfid.energy != 0: # 标签激活且命令为Select则进入就绪态
rfid.state = 'ready'
elif reader.command == "CW" and rfid.state == '': # 激活未激活的标签进入就绪态
rfid.energy = 10
rfid.state = 'ready'
print(rfid.state, "标签已激活")
print("进入就绪态")
elif reader.command == "query" and rfid.state == 'ready': # 就绪->仲裁(query)
rfid.Q = random.randint(0, 10)
rfid.state = 'arbitrate'
print(rfid.state, "进入仲裁态")
reader.command = ''
elif rfid.Q == 0 and rfid.state == 'arbitrate' and reader.command == "query": # 仲裁->回复(query,Q=0)
rfid.state = 'reply'
print(rfid.state, "进入回复态")
rfid.Q = random.randint(1, 10)
reader.command = ''
elif rfid.Q != 0 and rfid.state == 'arbitrate' and reader.command == "query": # 仲裁->回复(query,Q=0)
print('请等待:', rfid.Q, end=' ')
for i in range(0, rfid.Q):
rfid.Q = rfid.Q - 1
print(rfid.Q, end=' ')
time.sleep(0.5)
print('\n')
rfid.state = 'reply'
print(rfid.state, "进入回复态")
rfid.Q = random.randint(1, 10)
reader.command = ''
elif rfid.state == 'reply': # 回复态
if reader.command == 'Select':
rfid.state = 'ready'
if reader.command == '':
pass
else:
rfid.setRN16()
print('标签发送RN16', rfid.RN16)
reader.ack = rfid.RN16
time.sleep(1)
print('阅读器发送ACK', reader.ack)
time.sleep(1)
print('标签发送EPC', rfid.epc)
time.sleep(1)
rfid.state = 'acknowledged'
print(rfid.state, "进入确认态")
reader.command = ''
elif rfid.state == 'acknowledged': # 确认态
if reader.command == 'Select':
rfid.state = 'ready'
if reader.command == 'QueryRep':
rfid.state = 'ready'
if reader.command == 'QueryAdjust':
rfid.state = 'ready'
if reader.command == '':
pass
else:
thread1 = myThread_king(1, "Thread-1", 1)
# 开启新线程
e = 20
x = ''
thread1.start()
thread1.join(20)
reader.command = x
if e < 20:
print('阅读器发送Req_RN和RN16', reader.command, reader.ack)
time.sleep(1)
print("标签返回句柄", rfid.handle)
time.sleep(1)
if rfid.pwd * 1 == 0:
rfid.state = 'secured'
print(rfid.state, "密码功能未启用,进入安全态")
reader.command = ''
else:
rfid.state = 'open'
print(rfid.state, "密码功能启用,进入开放态")
reader.command = ''
else:
rfid.state = 'arbitrate'
print(rfid.state, "响应超时,进入仲裁态")
elif rfid.state == 'open': # 开放态
if reader.command == 'Select':
rfid.state = 'ready'
if reader.command == 'QueryRep':
rfid.state = 'ready'
if reader.command == 'QueryAdjust':
rfid.state = 'ready'
if reader.command == '':
pass
else:
print('请输入句柄')
reader.handle = int(input())
print('请输入密码')
reader.pwd = int(input())
if reader.handle == rfid.handle and reader.pwd == rfid.pwd:
rfid.state = 'secured'
print(rfid.state, "组合正确,进入安全态")
reader.command = ''
else:
print("组合不正确!")
rfid.energy = rfid.energy - 1
reader.command = ''
if rfid.energy == 0:
rfid.state = ''
reader.command = ''
print("能量耗尽")
elif rfid.state == 'secured': # 安全态
if reader.command == 'Select':
rfid.state = 'ready'
if reader.command == 'QueryRep':
rfid.state = 'ready'
if reader.command == 'QueryAdjust':
rfid.state = 'ready'
if reader.command == '':
pass
if reader.command == 'kill':
if rfid.pwd * 1 != 0:
print('请输入句柄')
reader.handle = int(input())
print('请输入密码')
reader.pwd = int(input())
if reader.handle == rfid.handle and reader.pwd == rfid.pwd:
rfid.state = 'killed'
print(rfid.state, "组合正确,杀死标签")
break
else:
print("组合不正确!")
reader.command = ''
else:
print('请输入句柄')
reader.handle = int(input())
if reader.handle == rfid.handle:
rfid.state = 'killed'
print(rfid.state, "句柄正确,杀死标签")
break
else:
print("组合不正确!")
reader.command = ''
else:
print('命令无效')
reader.command = ''
if rfid.state == 'ready' and reader.command != "CW":
print(rfid.state, "进入就绪态")
time.sleep(1)
reader.command = ''
运行结果:
结论:
七个状态及状态转移。就绪态:标签在通电前的状态,此时标签不参加询问过程。标签从阅读器发送的查询命令中,选择一个参数生成随机数用于计算发送的时隙。若为0,标签进入回复状态,否则进入仲裁态。
仲裁态:标签参加本轮查询。此时标签时隙不为0,将等待时隙数变为0,然后进入回复状态。
回复态:当标签需要回复EPC码时,首先进入回复态。标签接受到ACK后进入确认态。否则,标签会自动进入仲裁态。
确认态:标签回复EPC码后进入确认态。这是标签进入访问命令的必经状态。如回复态一样,若标签在指定时间内没有接受到阅读器的命令,将会自动返回仲裁态。
开放态:标签进入访问命令时需要互斥使用的状态。若标签没接受阅读器的命令将一直保持在此状态直至没有能量。标签能从开放态进入安全态。
安全态:标签可以使用一个可选的密码功能要求阅读器在执行任何访问命令时都要提供保护的密码。
杀死态:RFID标签中存储特定对象的信息,在不需要该标签将其杀死以保护信息。当标签进入杀死态以后,将不再响应阅读器发出的任何命令。