1

I have a problem with the MFRC522 library. It seems to me that after the tag was read / written one time correctly, in the next cycle the library always returns 2 on the check whether a card is present or not, meaning it skips one cycle every time.

The "request" function seems to give controll to the "tocard" function which does strange magic like if ~((i != 0) and ~(n & 0x01) and ~(n & waitIRq)): where it just seems to check registers but it is too hard to understand from only the library.

This is a HUGE problem for me, since I want the reader to poll, like a video game engine does when you hold a button pressed. To be specific, I want to recognise wheter a card that is present was already present in the last reading cycle, and so forth, meaning a user that just held the card onto the device would not create much dump data and senseless database entries, also what's the point in calculating a delta between timestamps when you are not even sure if your stamp was saved or just deleted lol.

I tried something like this:

    # Scan for cards    
    (status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)

    # If a card is found
    if status == MIFAREReader.MI_OK and same_card == False: # MI_OK == status code 0
        print "Card detected"
    elif status == MIFAREReader.MI_ERR: # MI_ERR == status code 2
        print "debug: no card present"
        same_card = False
    else:
        print "same card detected"

[Setting same_card to true after writing data successfully, of course]

For some reason I do not understand, the second reading cycle after I wrote data onto the card (or deleted it after getting my delta, this would be second time we enter work cycle) always returns status code 2 (MI.err)

This can't be possible because I'm still here holding that card against the reader (even if I slept for about 5 seconds, no difference)

The only other call at the end of the working cycle would be to

 def MFRC522_StopCrypto1(self):
    self.ClearBitMask(self.Status2Reg, 0x08)

but this will hardly cause this behaviour, right?

Does anybody have a working example of a script that is blocking if the card is held against the reader constantly? No cheating allowed (sleeping f.e.). Bonus points if you can provide something using interrupts....

Thank you

1 Answer 1

1

Well,

after further searching I found an okish solution thanks to

This post from Constantine Samoilenko

What he said was to cleanup the GPIO at the end of the loop, and also to reinstantiate the MFRC522 object each time the loop restarts. (this creates much overhead and is therefor just a dirty hack, but hey, we are speaking about python here, processor time and ram are wasted per default anyway)

And now it reads correctly on almost every loop. Almost. It still sometimes messes up, but works 9/10 times. (Which for me is enough, but the initial problem still remains, what if an user keeps holding the card against the reader.... )

Here is an estimate build of the program, if this helps anybody:

continue_reading = True

same_card = False

while continue_reading:

    # Create an object of the class MFRC522, reinstantiate on every loop
    MIFAREReader = MFRC522.MFRC522()

    time.sleep(0.5)

    # Scan for cards    
    (status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)

    #If a card is found
    if status == MIFAREReader.MI_OK and same_card == False: # MI_OK == status code 0
        print "Card detected"
    elif status == MIFAREReader.MI_ERR: # MI_ERR == status code 2
        print "debug: no card present"
        same_card = False
    else:
        print "same card detected"

     # Get the UID of the card (basicly first 4 byte of sector 0) -> save into "uid"
    (status,uid) = MIFAREReader.MFRC522_Anticoll()

     #print "DEBUG: " + str(uid) + " UID VAL"

     # If we have the UID, continue
     if status == MIFAREReader.MI_OK and same_card == False:

[ unlock card, do stuff, timestamp and calculate delta for time ]

then, at the end:

       MIFAREReader.MFRC522_Write(4,payload)  


    MIFAREReader.MFRC522_StopCrypto1()
    GPIO.cleanup()
    same_card = True
else:
    print "Authentication error"

This way, it at least won't give me the status 2 (MI_ERR),
so it won't delete my timestamp instantaniously again after writing it.

[In my program, I check whether a timestamp is present, if not stamp it. But if one is there, calculate the time delta between now and timestamp and format card afterwards]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.