PN532 RFID/NFC reader
Overview
Manufacturer | Philips semiconductors |
---|---|
Name | PN532 |
Datasheet | pn532ds.pdf |
Adafruit | PN532 NFC/RFID controller breakout board1 |
ESPHome component | pn532 2 |
ESPHome API docs | pn532.h File reference3 |
ESPHome config | packages/sensors/rfid.yml 4 |
Supply voltage | 5 |
Supports both SPI and I²C for communicate, reads NFC/RFID tag is able to write to (programmable) tags.
Since the PN532 is able to communicate over either the SPI or I²C, there is usually dip switch to config whichbus the module will usw .
Pinout
If there is no table on the silkscreen, usually2 this is how they are set up:
Protocol | 1 | 2 |
---|---|---|
SPI | OFF | ON |
I²C | ON | OFF |
ESPHome config
Using the I²C bus:
i2c:
- sda: ${gpio_sda_pin}
scl: ${gpio_scl_pin}
id: i2c_pn532
pn532_i2c:
i2c_id: i2c_pn532
update_interval: 200ms
But this doesn't do much at all, other than connecting over the I²C bus.
Send a tag_scanned
event to Home Assistant
To send a tag_scanned
event to Home Assistant, we need to create
an on_tag
automation in the ESPHome config:
pn532_i2c: # or pn532_spi
on_tag:
then:
- homeassistant.tag_scanned: !lambda 'return x;'
Which will make your tag show up in Home Assistant under /config/tags
where you can assign names to them and create automations.
Unfortunately its not possible to use the name/friendly name of the tag in an
automation trigger, only the uid
of the tag (tag_id
in the tag
platform
on the Home Asssistant side).
automation:
- alias: my_tag_scanned
trigger:
- platform: tag
tag_id: DE-AD-BE-EF
condition: []
action: []
This automation (on the Home Assitant side) will be triggered by the on_tag
automation
fired by ESPHome.
Template sensors to detect when a tag is scanned
When a tag is scanned, the pn532
component will by default write the UID of
the scanned tag (as well as type) to the logger
component.
This data is delivered with ESPHome events, that we can capture and publish to
templated sensors with automations provides by the pn532_...
components.
text_sensor:
- platform: template
id: tag_uid
name: "${hostname} Tag UID"
binary_sensor:
- platform: template
name: "${hostname} Tag scanned"
id: tag_scanned
publish_initial_state: true
# Return last known state, avoids an 'unknown' state on boot
# Could also use the on_boot trigger (might be better, the lambda is continuisly evaluated)
lambda: !-
return {};
filters:
- delayed_off: "10s"
Then we combine the on_tag
and on_tag_removed
automations to publish state to
the templated binary_sensor
and sensor
entities.
pn532_i2c:
on_tag:
then:
# Writes the tag's uid to the text_sensor
- text_sensor.template.publish:
id: tag_uid
state: !lambda 'return x;'
# Set the binary_sensor to true/on
# binary_sensor state intead of relying on automations
- binary_sensor.template.publish:
id: tag_scanned
state: ON
on_tag_removed:
then:
# Set the binary_sensor back to false/off.
- binary_sensor.template.publish:
id: tag_scanned
state: OFF
The value of the text_sensor
will persist and show the uid
of the last scanned
tag, unless you add an on_tag_removed
action to clear it. That means that if the
value changes, a tag has just been scanned.
Use a binary_sensor
to track known tags
The pn532
component also provides a binary_sensor
platform to trafic a tag with a known
UID is scanned.
binary_sensor:
- platform: pn532
uid: "${tag_uid}"
name: "NFC ${tag_name}"
filters:
- delayed_off: 10s
This can for example be comined with another automation and template sensor to track when the tag was last scanned.