RC522 NFC/RFID
==============

.. seo::
    :description: Instructions for setting up RC522 NFC/RFID tag readers and tags in ESPHome
    :image: rc522.jpg
    :keywords: RC522, NFC, RFID

.. _rc522-component:

.. figure:: images/rc522-full.jpg
    :align: center
    :width: 60.0%

The ``rc522`` component allows you to use RC522 NFC/RFID controllers
(`datasheet <https://www.nxp.com/docs/en/data-sheet/MFRC522.pdf>`__, `Ali Express <https://es.aliexpress.com/item/1260729519.html>`__)
with ESPHome. ESPHome can read the UID from the tag. Every NFC/RFID tag has a unique "UID" value assigned at the time
of manufacture. Tags can be associated with binary sensors, making it easy to determine when a specific tag is present.
You can also use the tag information directly within ESPHome automations/lambdas. See :ref:`rc522-setting_up_tags` for
information on how to setup individual binary sensors using this component.

The RC522 IC supports SPI, I²C and UART communication protocols; ESPHome can use either SPI or I²C.

Component/Hub
-------------

- If you have a module as shown in the image above, it can only be used in SPI mode
  (`unless hacked <https://forum.arduino.cc/index.php?topic=442750.0>`__) and you must define a :ref:`SPI bus <spi>`
  in your configuration with both the **miso_pin** and **mosi_pin** set.

- If you have a RC522 which communicates via I²C (as on the M5 Stack), you need to have an :ref:`I²C <i2c>` bus configured.

Over SPI
--------

The ``rc522_spi`` component allows you to use RC522 NFC/RFID controllers with ESPHome. This component is a global hub
that establishes the connection to the RC522 via :ref:`SPI <spi>`. Using :ref:`RC522 binary sensors <rc522-binary_sensor>`,
you can then create individual binary sensors that track if an NFC/RFID tag is currently detected by the RC522.

.. code-block:: yaml

    spi:

    rc522_spi:
      cs_pin: GPIO15

    binary_sensor:
      - platform: rc522
        uid: 74-10-37-94
        name: "RC522 RFID Tag"

Configuration variables:
************************

- **cs_pin** (**Required**, :ref:`Pin Schema <config-pin_schema>`): The pin on the ESP that the chip select line
  is connected to.
- **reset_pin** (*Optional*, :ref:`Pin Schema <config-pin_schema>`): The pin connected to the RST line. Some tests
  shows the RC522 working okay without this.
- **update_interval** (*Optional*, :ref:`config-time`): The duration of each scan on the RC522. This affects the
  duration that the individual binary sensors stay active when they're found.
  If a device is not found within this time window, it will be marked as not present. Defaults to ``1s``.
- **spi_id** (*Optional*, :ref:`config-id`): Manually specify the ID of the :ref:`SPI Component <spi>` if you want
  to use multiple SPI buses.
- **id** (*Optional*, :ref:`config-id`): Manually specify the ID for this component.
- **on_tag** (*Optional*, :ref:`Automation <automation>`): An automation to perform when a tag is read. See
  :ref:`rc522-on_tag`.
- **on_tag_removed** (*Optional*, :ref:`Automation <automation>`): An automation to perform after a tag is removed. See
  :ref:`rc522-on_tag_removed`.

Over I²C
--------

The ``rc522_i2c`` component allows you to use RC522 NFC/RFID controllers with ESPHome. This component is a global hub
that establishes the connection to the RC522 via :ref:`I²C <i2c>` (also available over SPI). Using the
:ref:`RC522 binary sensors <rc522-binary_sensor>` you can then create individual binary sensors that track if
an NFC/RFID tag is currently detected by the RC522.

.. code-block:: yaml

    i2c:

    rc522_i2c:

    binary_sensor:
      - platform: rc522
        uid: 74-10-37-94
        name: "RC522 RFID Tag"

Configuration variables:
************************

- **address** (*Optional*, int): Manually specify the I²C address of the sensor. Defaults to ``0x28``.
- **reset_pin** (*Optional*, :ref:`Pin Schema <config-pin_schema>`): The pin connected to the RST line. Some tests
  shows the RC522 working okay without this.
- **update_interval** (*Optional*, :ref:`config-time`): The duration of each scan on the RC522. This affects the
  duration that the individual binary sensors stay active when they're found.
  If a device is not found within this time window, it will be marked as not present. Defaults to ``1s``.
- **i2c_id** (*Optional*, :ref:`config-id`): Manually specify the ID of the :ref:`I²C Component <i2c>` if you want
  to use multiple I²C buses.
- **id** (*Optional*, :ref:`config-id`): Manually specify the ID for this component.
- **on_tag** (*Optional*, :ref:`Automation <automation>`): An automation to perform when a tag is read. See
  :ref:`rc522-on_tag`.
- **on_tag_removed** (*Optional*, :ref:`Automation <automation>`): An automation to perform after a tag is removed. See
  :ref:`rc522-on_tag_removed`.

Triggers
--------

.. _rc522-on_tag:

``on_tag`` Trigger
******************

This automation will be triggered immediately after the RC522 identifies a tag.

The parameter ``x`` this trigger provides is of type ``std::string`` and is the tag UID in the format
``74-10-37-94``. The configuration below will for example publish the tag ID on the MQTT topic ``rc522/tag``.

.. code-block:: yaml

    rc522_spi: # or rc522_i2c
      # ...
      on_tag:
        then:
          - mqtt.publish:
              topic: rc522/tag
              payload: !lambda 'return x;'

A tag scanned event can also be sent to the Home Assistant tag component
using :ref:`api-homeassistant_tag_scanned_action`.

.. code-block:: yaml

    rc522_spi: # or rc522_i2c
      # ...
      on_tag:
        then:
          - homeassistant.tag_scanned: !lambda 'return x;'

.. _rc522-on_tag_removed:

``on_tag_removed`` Trigger
**************************

This automation will be triggered when the RC522 no longer "sees" a previously scanned tag.

The parameter ``x`` this trigger provides is of type ``std::string`` and is the removed tag UID in the format
``74-10-37-94``. The example configuration below will publish the removed tag ID on the MQTT topic ``pn7160/tag_removed``.

.. code-block:: yaml

    rc522_spi: # or rc522_i2c
      # ...
      on_tag_removed:
        then:
          - mqtt.publish:
              topic: rc522/tag_removed
              payload: !lambda 'return x;'



.. _rc522-binary_sensor:

``rc522`` Binary Sensor
-----------------------

The ``rc522`` binary sensor platform lets you track if an NFC/RFID tag with a given unique id (``uid``) is currently
being detected by the RC522 or not.

.. code-block:: yaml

    # Example configuration entry
    spi:
      clk_pin: D0
      miso_pin: D1
      mosi_pin: D2

    rc522_spi: # or rc522_i2c
      cs_pin: D3
      update_interval: 1s

    binary_sensor:
      - platform: rc522
        uid: 74-10-37-94
        name: "RC522 RFID Tag"

Configuration variables:
************************

- **uid** (**Required**, string): The unique ID of the NFC/RFID tag. This is a hyphen-separated list
  of hexadecimal values. For example ``74-10-37-94``.
- **name** (**Required**, string): The name of the binary sensor.
- **id** (*Optional*, :ref:`config-id`): Manually specify the ID used for code generation.
- All other options from :ref:`Binary Sensor <config-binary_sensor>`.

.. _rc522-setting_up_tags:

Setting Up Tags
---------------

To set up binary sensors for specific NFC/RFID tags you first have to know their unique IDs. To obtain this
id, first set up a simple RC522 configuration without any binary sensors like above.

When your code is running and you approach the RC522 with an NFC/RFID Tag, you should see a message like this:

.. code::

    Found new tag '74-10-37-94'

Then copy this id and create a ``binary_sensor`` entry as in the configuration example. Repeat this process for each tag.

See Also
--------

- :doc:`index`
- :doc:`rdm6300`
- :doc:`pn532`
- :apiref:`rc522/rc522.h`
- :ghedit:`Edit`
