PiicoDev RFID Module - Guide for Raspberry Pi

Updated 03 June 2022

Radio Frequency IDentification (RFID) uses electromagnetic fields to identify and communicate with tags. Each RFID module emits radio waves that energise the passive tag, which then responds with its own identifying number or data, as requested.

In this tutorial, we'll get started with using a PiicoDev® RFID module by making some starter projects. Once we're done, you'll be able to read the simple ID off a tag, and read or write data to the tag. Depending on the tag type, we can turn the tag into an interactive RFID tag which triggers certain readers (like smartphones) to execute actions such as opening webpages, showing a specific location on a map, and loads more!

To follow along, it's best to have:

Contents

Connect the RFID Module to your Pi

Mount the PiicoDev Adapter on your Raspberry Pi and plug connect your colour sensor to the Adapter via the PiicoDev cable.

The adapter connects to the 40-pin GPIO header on the Raspberry Pi -  ensure the header is mounted correctly, with the "Ethernet" label on the same side as the Pi's ethernet adapter.

If you're unfamiliar with connecting PiicoDev modules, read the PiicoDev Connection Guide before proceeding.

connect-piicodev-rfid-module-to-raspberry-pi

On the RFID Module - make sure both Address Switches (ASW) are in the OFF position. The ASW switch may be covered by a thin, orange film - carefully peel this away if necessary.

piicodev-rfid-module-asw-switches-off-default

If you're unfamiliar with connecting PiicoDev modules, read the PiicoDev Connection Guide before proceeding.

Enable I2C

Power on your Raspberry Pi. Open the Raspberry Pi Configuration Menu, select the Interfaces tab and ensure I2C is enabled.

You only need to do this step for your first PiicoDev project - from here on you probably won't have to repeat this step when using PiicoDev hardware.

raspberry-pi-enable-i2c

Install/Upgrade PiicoDev

Open Thonny (Pi Start Menu > Programming > Thonny IDE) and open the Manage Packages menu (Tools > Manage Packages)

open-thonnythonny-manage-packages

Search for 'piicodev' and install or upgrade if necessary.

search-for-piicodev-pypi     install-piicodev-package

Example 1 - Read Tag ID and Type

Download the example code: read_id.py (right-click, "save link as")

Open Thonny, navigate to where you downloaded the example and open read_id.py.

Run the script (click the Green Play Button, or Ctrl R). You will be prompted to hold a tag near the RFID Module - do so and you ought to see a string of characters display in the Shell - this is the unique ID of your tag. If you have other tags handy, try reading their IDs and observe how they are different.

piicodev-rfid-module-reading-unique-id

Above: Three different tags are held against the sensor - one after the other. Their unique IDs are printed into the shell. The first two tags are NTAG213, and the third is a 'Classic' which has a shorter ID string.

Remix - Tag Type (Detailed Read)

Change readID() to readID(detail=True) to extract additional information about your tag, or the result of an attempted read (Success or Failure). For example, if you move your tag across the reader too quickly, the detailed message will return success: False. In the following image, we read from the same tags. This time, the 'type' is revealed for each ('ntag' or 'classic'), and the last read-attempt is flagged with 'success': False because the tag was moving too quickly to be read properly).
piicodev-rfid-detailed-result

Example 2 - Access Control (Starter Project)

Download the example code: access_control.py (right-click, "save link as"). Open the example in Thonny.

RFID is often used for Access Control eg. permitting authorised personnel into a building. The following program simulates this behaviour. Since we can identify unique tags, we can keep a list of authorised tags. When our program sees an authorised tag it can perform one behaviour ("Access Granted"), and perform a different behaviour ("Access Denied") if the tag is not recognised.

Run the script and hold your tag to the RFID Module. Your tag is not yet recognised so the program prints "ACCESS DENIED".

Now try copying your tag's ID string from the shell, and pasting it into the authorised_users list. Re-run the program and try scanning your tag again - you ought to see "Access Granted!"

piicodev-rfid-authorised-users-access-control-example

Example 3 - Interactive Tag using Unique Resource Identifier (URI)

Download the example code: write_uri.py (right-click, "save link as"). Open the example in Thonny.

We can write special data to a tag that causes the scanning device to perform special actions. For example, tags may be programmed with:

  • a website address. When a smartphone scans the tag, it opens that webpage.
  • geographic co-ordinates. When scanned, a smartphone would open a map at that location.
  • a phone number. When scanned, a smartphone would open the telephone app and pre-fill that phone number.

The scanner (phone) knows how to interpret each type of resource (webpage, coordinates, phone number) thanks to Unique Resource Identifiers (URIs). There are loads of different URI schemes that we can choose from. The following example will program a tag with one of the example URIs of your choice. Try programming your tag with the web address and scan it with an NFC-enabled phone.

# Demonstrate some different URIs (Unique Resource Identifiers)
# Write a URI to a NTAG - when the tag is scanned a NFC-enabled smartphone the relevant resource will be opened.

from PiicoDev_RFID import PiicoDev_RFID
from PiicoDev_Unified import sleep_ms

rfid = PiicoDev_RFID()

print('Place tag near the PiicoDev RFID Module to write a URI')
print('')

# URIs can link loads of different resources. Here's just a few examples, but there are many more listed here: https://en.wikipedia.org/wiki/List_of_URI_schemes
web_address = 'https://core-electronics.com.au/tutorials/search/query/piicodev/' # URL of a webpage
geo_location = 'geo:-0.6770672,-78.4507881'        # co-ordinates (latitude, longitude) for a map application
email_address = 'mailto:[email protected]'  # compose an email to this recipient
phone = 'tel:##########'                           # call a telephone number (country codes accepted eg. ' 61...')

while True:
    if rfid.tagPresent():
        success = rfid.writeURI(web_address) # Write the selected URI to a tag
        if success:
            print('Write successful')
            break # break out of the loop, stopping the script.
    sleep_ms(10)

Looking closer at the example, we can see that each URI scheme has a special keyword, eg. an email address is preceded by 'mailto:', and a web address is preceded by either 'http://' or 'https://'

Example 4 - Writing and Reading Data

It's possible to write and read ordinary data like text or numbers to a tag:

Write Text

Download the example code: write_text.py (right-click, "save link as"). Open the example in Thonny.

This example writes a string of text (up to 143 characters) to a tag. The text is read back to show that it was written correctly.

# Write a string to a tag, and read it back to show that it wrote correctly

from PiicoDev_RFID import PiicoDev_RFID
from PiicoDev_Unified import sleep_ms

rfid = PiicoDev_RFID()

myString = 'Hello World!' # You can store up to 143 characters on a tag

print('Hold tag near the PiicoDev RFID Module to write some text to it.')
print('')

while True:
    success = rfid.writeText(myString)
    if success:
        data = rfid.readText()
        print('Text in tag:')
        print(data)
        break
    sleep_ms(10)


Read Text

Download the example code: read_text.py (right-click, "save link as"). Open the example in Thonny.

This example reads a string of text from a tag. The text is assumed to have been written by PiicoDev's writeText() function, as in the previous example.

# Read a string from a tag.

from PiicoDev_RFID import PiicoDev_RFID
from PiicoDev_Unified import sleep_ms

rfid = PiicoDev_RFID()

print('Hold tag near the PiicoDev RFID Module to read some text')
print('')

while True:
    myString = rfid.readText()
    print('Text in tag:')
    print(myString)
    break
    sleep_ms(1000)

Write Numbers

Download the example code: write_number.py (right-click, "save link as"). Open the example in Thonny.

This example writes a number to the tag, then reads it back and prints it to the shell. You can store an integer (whole number) between −2,147,483,647 and 2,147,483,647.

This example writes a number to a 'slot' on the tag. A slot is what we're calling a memory location that's safe to write to. There are other locations on RFID tags that we could write to, but that can break your tag. Each slot can store an integer (whole number) between −2,147,483,647 and 2,147,483,647. There are 36 slots, numbered 0 to 35.

# Write a number to a tag. Numbers must be integers between −2,147,483,647,  2,147,483,647
from PiicoDev_RFID import PiicoDev_RFID
from PiicoDev_Unified import sleep_ms

rfid = PiicoDev_RFID()

print('Hold tag near the PiicoDev RFID Module to write a number')
print('')

while True:
    success = rfid.writeNumber(123456, slot=0) # Write a number to slot0. There are 36 slots available (0-35) to store numbers/text
    if success:
        data = rfid.readNumber(slot=0) # Read back from slot0
        print('Number in tag:')
        print(data)
        break
    sleep_ms(10)


If only care about storing a single number, you may omit the slot argument from the writeNumber() and readNumber() functions, which makes them look a bit simpler. In this case, slot 35 is used by default.

 

Read Numbers

Download the example code: read_number.py (right-click, "save link as"). Open the example in Thonny.

This example reads a number from a slot, does some simple arithmetic, and prints it to the shell.

# Read a number from a tag and do some simple math
from PiicoDev_RFID import PiicoDev_RFID
from PiicoDev_Unified import sleep_ms

rfid = PiicoDev_RFID()

print('Hold tag near the PiicoDev RFID Module to read a number')
print('')

while True:
    if rfid.tagPresent():
        data = rfid.readNumber(slot=0) # read a number from slot0
        print('Number in tag: '   str(data))
        newData = data   1 # it's a real number, we can use it for math and stuff!
        print(str(data)  ' plus 1 is '  str(newData))
        sleep_ms(1000)
    sleep_ms(10)

If only care about storing a single number, you may omit the slot argument from the writeNumber() and readNumber() functions, which makes them look a bit simpler. In this case, slot 35 is used by default.

Mixing Data (Text and Numbers)

It's possible to store both strings and integers on a tag - just be careful. Strings are stored starting at slot=0, with four characters fitting in a slot. Strings always get a special, extra character added to the end of them - the so-called 'terminating character.' This means that the 12-letter string "hello world!" requires 4 slots to store it: 12 characters 1 special extra character = 13 total. In this case, if you want to store numbers as well they should be located from the fifth slot, onwards. Remember, slots are counted from zero, so the fifth slot is actually slot=4.

Starter Project - Vending Machine

This example shows how data can be stored on a tag and updated by a script to do something useful. The following starter project behaves like a vending machine. If a tag is held to the RFID Module at the start of the script, a credit is applied to the tag (an integer representing 20 credits is stored on the tag). Now, when the tag is scanned the balance stored on the tag gets reduced, and a message shows that an item is dispensed from the imaginary vending machine. Once the balance is too low, the machine will stop dispensing.

from PiicoDev_RFID import PiicoDev_RFID
from PiicoDev_Unified import sleep_ms

rfid = PiicoDev_RFID()   # Initialise the RFID module

price = 3 # dollars (whole dollars only)

rfid = PiicoDev_RFID()

print('Place tag near the PiicoDev RFID Module to purchase for $'   str(price))
print('')

if rfid.tagPresent(): # apply credit on powerup
    rfid.writeNumber(20) # Give credit (whole dollars only)
    print('Credit applied! Remove tag...')
    while rfid.tagPresent(): sleep_ms(100)

while True:
    balance_dollars = rfid.readNumber()
    print('Previous Balance: $'   str(balance_dollars))
    
    new_balance = balance_dollars - price
    
    if new_balance < 0:
        print('Not enough credit')
    
    if new_balance >= 0:
        print('Item dispensed')
        success = rfid.writeNumber(new_balance)
        
        new_balance = rfid.readNumber()
        print('New Balance: $'   str(new_balance))
        
        # Wait for the user to remove the tag
        while rfid.tagPresent():
            sleep_ms(10)

    sleep_ms(2000)
    print('')
    print('Place tag near the PiicoDev RFID Module to purchase for $'   str(price))

Example 5: Using Multiple RFID Modules

Download the example code: multiple_readers.py (right-click, "save link as"). Open the example in Thonny.

It's possible to connect up to four RFID Modules on a PiicoDev bus - they will each need unique Address Switch (ASW) settings. Until now we've been working with one module with both address switches in the OFF position. To add a second module, set its ASW1 to the ON position. Now, when we initialise both sensors, we can explicitly include the ASW settings in the initialisation function using the asw argument. The asw argument is just a list of the switch positions (in ascending order) where 1 is ON and 0 is OFF. Note: the ASW switch positions are only read on powerup - if you change the ASW switch positions while a module is powered, you will need to remove and reconnect power to the module for the new address to be used.

piicodev-rfid-address-switch-asw-set-address

Above: The left panel shows the procedure for changing the second module's address. (Left) Address Switch (ASW) in the default state, with both switches OFF. (Middle) Use a fine implement like tweezers or a toothpick to set ASW1 to the ON position. (Right) With the new ASW configuration, the module should be initialised with asw=[1,0]

The following example initialises two RFID Modules (with ASW [0,0] and ASW [1,0]) and reads tag IDs from them independently.

# Read from two RFID modules independently
from PiicoDev_RFID import PiicoDev_RFID
from PiicoDev_Unified import sleep_ms

readerA = PiicoDev_RFID(asw=[0,0])     # Initialise the first RFID module with both address switches OFF
readerB = PiicoDev_RFID(asw=[1,0])     # Initialise the second RFID module with the first address switch ON

print('Place tag near one of the PiicoDev RFID Modules')
print('')

while True:    
    if readerA.tagPresent():              # if an RFID tag is present on reader A
        id = readerA.readID()             # get the id
        print('RFID A: '   id)            # print the id on the left side of the shell
        
    if readerB.tagPresent():              # if an RFID tag is present on reader B
        id = readerB.readID()             # get the id
        print(30*' '   'RFID B: '   id)   # print the id on the right side of the shell

    sleep_ms(500)



Conclusion

We've used a PiicoDev RFID Module to read the unique ID from a compatible tag, and completed a simple starter project to perform different actions depending on what tag is scanned (access control). We've completed further examples to read and write user-data to tags including numbers, text, and even interactive URIs. By setting unique addresses using the Address Switch (ASW), we can connect up to four RFID Modules to the same PiicoDev bus.

Resources

Hardware Repository

RFID Module Schematic

PiicoDev RFID MicroPython Module

Have a question? Ask the Author of this guide today!

Please enter minimum 20 characters

Your comment will be posted (automatically) on our Support Forum which is publicly accessible. Don't enter private information, such as your phone number.

Expect a quick reply during business hours, many of us check-in over the weekend as well.

Tags:

Comments


Loading...
Feedback

Please continue if you would like to leave feedback for any of these topics:

  • Website features/issues
  • Content errors/improvements
  • Missing products/categories
  • Product assignments to categories
  • Search results relevance

For all other inquiries (orders status, stock levels, etc), please contact our support team for quick assistance.

Note: click continue and a draft email will be opened to edit. If you don't have an email client on your device, then send a message via the chat icon on the bottom left of our website.

Makers love reviews as much as you do, please follow this link to review the products you have purchased.