ondryaso / pi-rc522

Raspberry Pi Python library for SPI RFID RC522 module
MIT License
412 stars 150 forks source link

Reading Cards on Events #9

Closed mihaj closed 7 years ago

mihaj commented 8 years ago

Hi guys.

I am new to Raspberry Pi and for my fist project I set RC522 and your library. It works fine from the samples. But the thing is, I want to get away from While true loop(CPU consumption) and move to an event listening. How can I do that? Any hints are welcome.

faultylee commented 8 years ago

RC522 requires command to constantly instructing it to read or scan for cards to detect the card. One way or another, a while loop is needed. The sleep in the while loop doesn't incur too much cpu actually, though longer sleep will sacrifice on the scan delay. I was happy with 100ms.

PierreRust commented 8 years ago

There is an IRQ pin on the RC522, which could probably be used to read the card only when an event occurs. I've seen a basic sample of this in the arduino lib for RC522 but I have tried it and it's definitively not implemented in pi-rc522 (but would be a nice feature)

Otherwise I agree the cpu consumption is quite low and you can put the while loop in a background check that would emit the event when something actually happens (but still cause cpu consumption, of course).

mihaj commented 8 years ago

I've changed to 100ms and CPU is at 15%, changed to 200ms and CPU is at 10%, otherwise at 25% (I have 4 cores).

I was looking at GPIO.add_event_detect(24, GPIO.RISING, callback=my_callback) here http://raspi.tv/2013/how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio-part-2

Just not sure which PIN I should connect to. IRQ?

faultylee commented 8 years ago

I did have the same thought but I couldn't find any example using the IRQ for Arduino, C++, Python ...etc. I end up using while loop for my 2 previous projects utilizing RC522 and PN512. Even official example from NXP for PN512 doesn't use IRQ. For PN512, I use an C++ program to handle the loop and card detection and python + pexpect to read the stdout. CPU was below 5% on the old model B.

Based on what I see on the datasheet image the IRQ is more for low level interrupt, i.e. to indicate the end of transmission or completion of a command. I've seen similar IRQ when working with PIC, hence at the end you'll still need to poll the RC522 to see if there's card detected.

Well, I do hope that I was wrong but so far the evidence is pointing the right direction.

mihaj commented 8 years ago

Hmm. OK, let's say IRQ port is useles in this case. But what about other SPI ports? Do you think we could apply something similar to RC522? http://raspi.tv/2013/how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio

PierreRust commented 8 years ago

I've seen this sample (on arduino) which seems to use the irq port to read the UID, using IdleIrq and loAlert (not sure why ?) https://github.com/miguelbalboa/rfid/blob/master/examples/MinimalInterrupt/MinimalInterrupt.ino

I've also check and the cpu consumption is indeed much higher than what I would have expected : 15-20% on a pi 2 B with (200ms sleep). I'm wondering why it's so expensive to read a few byte on spi !

faultylee commented 8 years ago

@mihaj The IRQ is in relation to RC522, not the SPI port itself

@PierreRust That interesting, I didn't notice the interrupt example when I ported the library for PIC. I'll try out that Arduino code sometime this week, to see if the interrupt is fired continuously or only when card is present.

ondryaso commented 8 years ago

Also the program still has to be running in a way even when using interrupts, I don't think it would be a relevant performance boost

faultylee commented 8 years ago

Sorry, @PierreRust couldn't find my RC522 module and I'll be away for 2 weeks. I'll continue to try this out when I'm

LudwigKnuepfer commented 7 years ago

For the predecessor project's code, waiting for interrupts (see diff here https://github.com/mxgxw/MFRC522-python/issues/17#issuecomment-269629633) lowered the CPU usage from 80% (45% with 0.2s sleep in between reads) to 1% in Read.py on a Pi 1 B.

LudwigKnuepfer commented 7 years ago

I ported my hack to work with this library. Will probably do a PR soon ;)

Silberlachs commented 5 years ago

I just want to ask if anybody also experianced that in either case ( interrupt or non interrupt ) the tag won't get recognised for 1 cycle before it will be detected again. I don't know why this is happening and it drives me crazy. I want the card to be timestamped and logged in database as fast as possible, thus having kind of a poll, like in a video game:

`

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"

`

This drives me mad because it does not matter how long i sleep, "same card" will never occure since the status code is always 2! Like it does not recognize that I am still holding the tag against it! This is bad, because what if somebody just holds the tag onto the device? So much dump data, so much wrong timestamps! PLS help

I also tryed the MFRC522_Anticoll, but either it does nothing different, or it is simply for reading multiple tags at once (for whatever reason, maybe if you had a box with multiple tags in it, dunno, duncare)

nooster2 commented 4 years ago

Hi Silverlachs, how did you solve your problem? I have pretty much the same issue: I want to detect when a new card is present, but in every 2nd cycle it doesn't recognize the card and shows status 2.