I'm trying to make RFID RC522 work with my Raspberry Pi 3 B+. I use the library MFRC522, and the the sensor can read data most of the times. However if I just put the card on the sensor it will stop reading after around 25-1.5k reads, as well as won't read any new cards. It either ends with "AUTH ERROR" or it stops on "Card Detected". My guess would be that library read handling has some bug. Here's the code I use(same as sample Read.py from the library, but I added sleep and counter):
import RPi.GPIO as GPIO
import MFRC522
import signal
import time
continue_reading = True
# Capture SIGINT for cleanup when the script is aborted
def end_read(signal,frame):
global continue_reading
print "Ctrl+C captured, ending read."
continue_reading = False
GPIO.cleanup()
# Hook the SIGINT
signal.signal(signal.SIGINT, end_read)
# Create an object of the class MFRC522
MIFAREReader = MFRC522.MFRC522()
counter=0
# This loop keeps checking for chips. If one is near it will get the UID and authenticate
while continue_reading:
# Scan for cards
(status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)
# If a card is found
if status == MIFAREReader.MI_OK:
print "Card detected"
else:
print status
continue
# Get the UID of the card
(status,uid) = MIFAREReader.MFRC522_Anticoll()
# If we have the UID, continue
if status == MIFAREReader.MI_OK:
# Print UID
print "Card read UID: "+str(uid[0])+","+str(uid[1])+","+str(uid[2])+","+str(uid[3])
# This is the default key for authentication
key = [0x8C,0x89,0x8D,0x89,0x83,0x93]
# Select the scanned tag
MIFAREReader.MFRC522_SelectTag(uid)
# Authenticate
status = MIFAREReader.MFRC522_Auth(MIFAREReader.PICC_AUTHENT1A, 3, key, uid)
# Check if authenticated
if status == MIFAREReader.MI_OK:
MIFAREReader.MFRC522_Read(2)
MIFAREReader.MFRC522_StopCrypto1()
counter+=1
print "counter=", counter
else:
print "Authentication error"
time.sleep(0.1)
If I Ctrl+C the program (even without the signal defined) and restart - mostly it will read data. But sometimes it also won't.
EDIT 1:
Also I have added the print status
in case if the return is not MI_OK
. It keeps giving me 2
for output.
Also interesting thing I've noticed - every time I read a card it gives this output:
Card detected
Card read UID: 131,175,134,247
Size: 8
Sector 2 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
counter= 1
2
Card detected
Card read UID: 131,175,134,247
Size: 8
Sector 2 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
counter= 2
2
Card detected
Card read UID: 131,175,134,247
Size: 8
Sector 2 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
counter= 3
2
Card detected
Card read UID: 131,175,134,247
Size: 8
Sector 2 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
counter= 4
2
Card detected
Card read UID: 131,175,134,247
Size: 8
Sector 2 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
counter= 5
2
Card detected
Card read UID: 131,175,134,247
Size: 8
Sector 2 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
counter= 6
EDIT 2:
Ok, I have found a problem and a "brute force" solution. I think the problem is/was related to not complete flush of io channel(s) of the scanner. So I modified the code to force GPIO.cleanup()
and create a new instance of scanner on each loop iteration. If there're better solutions for this case I'd be more than grateful to see it. The new version of code:
import RPi.GPIO as GPIO
import MFRC522
import signal
import time
continue_reading = True
# Capture SIGINT for cleanup when the script is aborted
def end_read(signal,frame):
global continue_reading
print "Ctrl+C captured, ending read."
continue_reading = False
GPIO.cleanup()
# Hook the SIGINT
signal.signal(signal.SIGINT, end_read)
# Create an object of the class MFRC522
counter=0
# This loop keeps checking for chips. If one is near it will get the UID and authenticate
while continue_reading:
##########################################
MIFAREReader = MFRC522.MFRC522()
##########################################
# Scan for cards
(status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)
# If a card is found
if status == MIFAREReader.MI_OK:
print "Card detected"
else:
print status
continue
# print status
# Get the UID of the card
(status,uid) = MIFAREReader.MFRC522_Anticoll()
# If we have the UID, continue
if status == MIFAREReader.MI_OK:
# Print UID
print "Card read UID: "+str(uid[0])+","+str(uid[1])+","+str(uid[2])+","+str(uid[3])
# This is the default key for authentication
key = [0x8C,0x89,0x8D,0x89,0x83,0x93]
# Select the scanned tag
MIFAREReader.MFRC522_SelectTag(uid)
# Authenticate
status = MIFAREReader.MFRC522_Auth(MIFAREReader.PICC_AUTHENT1A, 3, key, uid)
# Check if authenticated
if status == MIFAREReader.MI_OK:
MIFAREReader.MFRC522_Read(2)
MIFAREReader.MFRC522_StopCrypto1()
counter+=1
print "counter=", counter
else:
print "Authentication error"
#############################
GPIO.cleanup()
#############################
time.sleep(0.1)