ondryaso / pi-rc522

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

Request: timeout on wait_for_tag #44

Open tlongeri opened 6 years ago

tlongeri commented 6 years ago

It would be nice to have a timeout argument on the wait_for_tag function. I'm using it to listen for tags on a looping thread that checks on a 'global' exit flag at each loop, but since wait_for_tag can never exit I have no nice way of killing it so I was forced to make my own modified version.

It should be a simple change, like this:

def wait_for_tag(self, timeout):
    # enable IRQ on detect
    start_time = time.time()
    rdr.init()
    rdr.irq.clear()
    rdr.dev_write(0x04, 0x00)
    rdr.dev_write(0x02, 0xA0)
    # wait for it
    waiting = True
    while waiting and time.time() - startTime < timeout:
        rdr.dev_write(0x09, 0x26)
        rdr.dev_write(0x01, 0x0C)
        rdr.dev_write(0x0D, 0x87)
        waiting = not rdr.irq.wait(0.1)
    rdr.irq.clear()
    self.init()

It's just a little detail that would improve usability.

bluepuma77 commented 4 years ago

Just wanted to open a new feature request for rdr.wait_for_tag(timeout=10).

So GitHub "similar issues" works 😃

topermaper commented 1 month ago

Hi @ondryaso, @jo-me ,

wait_for_tag now returns after timeout seconds but unfortunatelly there is no way to know whether it returned normally or because the time out. In case there is a timeout when i call self._reader.request() I would get an error.

Would be possible to use a Timeout Exception so you can handle the timeout in the caller method. Something like this:

try:
    self._reader.wait_for_tag(timeout=1)
except TimeoutError:
    return None

error, tag_type = self._reader.request()

if error:
    raise RfidReadException("Error reading rfid tag")
def wait_for_tag(self, timeout=None):
    if self.pin_irq is None:
        raise NotImplementedError('Waiting not implemented if IRQ is not used')

    # enable IRQ on detect
    self.init()
    self.irq.clear()
    self.dev_write(0x04, 0x00)
    self.dev_write(0x02, 0xA0)
    # wait for it
    start_time = time.time()
    waiting = True

    while waiting:
        if timeout and (time.time() - start_time) >= timeout:
            raise TimeoutError

        self.init()
        self.dev_write(0x04, 0x00)
        self.dev_write(0x02, 0xA0)

        self.dev_write(0x09, 0x26)
        self.dev_write(0x01, 0x0C)
        self.dev_write(0x0D, 0x87)
        waiting = not self.irq.wait(0.1)

    self.irq.clear()
    self.init()

Should i raise a new issue or could this be reopened ?