nfcente/main.py
Kumi d90ac6b12f
refactor: optimize sleep durations for RFID reading
Reduced initial sleep time before card detection and adjusted sleep
intervals within read loops to enhance responsiveness and resource
efficiency in RFID/NFC reading routines. This adjustment aims to
minimize unnecessary delays, improving the user experience by making
card detection more prompt without compromising system stability. Moved
consistent sleeping to a `finally` block in `do_read` to ensure regular
timing intervals, regardless of read success or exceptions, contributing
to a more predictable and reliable operation.
2024-03-19 20:42:32 +01:00

128 lines
3.4 KiB
Python

from micropython import const
from os import uname
from machine import SoftSPI, Pin
import uasyncio as asyncio
import aioble
import bluetooth
import random
import struct
import machine
import time
import gc
import sys
import pn532_i2c
# Based on example from: https://github.com/micropython/micropython-lib/blob/master/micropython/bluetooth/aioble/examples/temp_sensor.py
# Unfortunately, there is no license information for aioble anywhere to be found...
# Also based on https://github.com/somervda/nfc-tester which doesn't come with a license file either...
RFID_BASE = lambda x: "1408%s-1337-BABE-B00B-C0FFEEC0FFEE" % (((4 - len(str(x))) * "0") + str(x))
RFID_SERVICE_UUID = bluetooth.UUID(RFID_BASE(1))
RFID_CHAR_UUID = bluetooth.UUID(RFID_BASE(2))
_ADV_INTERVAL_MS = 250_000
rfid_service = aioble.Service(RFID_SERVICE_UUID)
rfid_characteristic = aioble.Characteristic(
rfid_service, RFID_CHAR_UUID, read=True, notify=True
)
aioble.register_services(rfid_service)
async def peripheral_task():
while True:
try:
async with await aioble.advertise(
_ADV_INTERVAL_MS,
name="RFIDTest",
services=[RFID_SERVICE_UUID],
) as connection:
print("Connection from", connection.device)
await connection.disconnected()
except BaseException as e:
print("Exception in peripheral_task:", e)
async def read_task(rdr, buzzer=None):
# Start listening for a card
print("Waiting for RFID/NFC card...")
while True:
try:
do_read(rdr, buzzer)
except Exception as e:
print("Exception in read_task:", e)
await asyncio.sleep_ms(100)
def do_read(rdr, buzzer=None):
gc.collect()
last_uid = None
while True:
try:
uid = rdr.read_passive_target(timeout=0.2)
if last_uid == uid:
continue
if uid is None:
print("No card found")
last_uid = None
continue
struid = "".join(['{:0>{w}}'.format(hex(i)[2:], w=2) for i in uid])
print("Found card with UID:", struid)
rfid_characteristic.write(uid)
if buzzer:
buzzer.value(1)
time.sleep_ms(300)
buzzer.value(0)
last_uid = uid
except Exception as e:
print("Something failed:", e)
pass
finally:
time.sleep_ms(100)
async def main():
try:
i2c = machine.I2C(0, scl=machine.Pin(1), sda=machine.Pin(0))
devices = i2c.scan()
if len(devices) == 0:
print("No i2c device !")
return 1
else:
print('i2c devices found:', len(devices))
for device in devices:
print("Decimal address: ", device, " | Hex address: ", hex(device))
pn532 = pn532_i2c.PN532_I2C(i2c, debug=False)
ic, ver, rev, support = pn532.get_firmware_version()
print("Found PN532 with firmware version: {0}.{1}".format(ver, rev))
pn532.SAM_configuration()
time.sleep_ms(100)
gc.collect()
buzzer = Pin(27, Pin.OUT)
buzzer.value(0)
await asyncio.gather(
peripheral_task(),
read_task(pn532, buzzer)
)
except KeyboardInterrupt:
print("Interrupted")
except Exception as e:
print("Exception in main:", e)
return 1
asyncio.run(main())