nfcente/main.py
Kumi 800d003761
feat: add buzzer feedback for RFID reads
Introduced an optional buzzer parameter to `read_task` and `do_read`
functions to provide audible feedback when an RFID/NFC card is
successfully read. This enhancement is aimed at improving user
interaction by providing immediate auditory confirmation of a successful
card scan. The buzzer is triggered for a short duration upon successful
card detection. This feature offers a more intuitive experience,
especially in environments where visual confirmation might be
challenging to notice.

A GPIO pin is configured as output for the buzzer control, ensuring
minimal impact on the code's structure and maintaining backward
compatibility by keeping the buzzer parameter optional.
2024-03-19 20:21:47 +01:00

126 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
time.sleep_ms(1000)
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:
time.sleep_ms(100)
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
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(1000)
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())