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!

Transcript

I'm going to show you how to get started reading RFID tags using a PiicoDev RFID module. We'll connect this to a Raspberry Pi Pico and get some example code working so that we can identify unique tags and also read and write data onto those tags. Let's get started!

To follow along, you'll of course need a Raspberry Pi Pico with pins soldered facing down. This is so it can plug into the PiicoDev expansion board. Just plug that in so that the USB connector is on the same side as the two-pin battery connector. You'll also need a PiicoDev cable to connect your expansion board to the RFID module and of course a couple of RFID tags. For the best experience, we recommend NTAG 213 type RFID tags.

Just before we continue, your RFID module has a switch labelled ASW. You can see there are two little switches side by side. Make sure both of those switches are in the off position, that's where the switches are in the lower position. I've just mounted everything onto this PiicoDev platform to keep it nice and stable and connect to your computer with USB.

Now RFID tags are available in all different kinds of shapes and sizes and there are lots of different standards of RFID tags. I've labelled a couple here so that we can keep track of them. The shape of the tag has nothing to do with the actual standard that the tags used.

Now for the best experience with the PiicoDev RFID module, we recommend NTAG 213 tags. It will also work with classic tags or Mifare tags, but for the best results we recommend NTAG 213. Check the article for the most up-to-date compatibility.

In the article for this tutorial, find the downloads section and right-click and save each link. I'm going to save these to a PiicoDev directory in my documents. This last file, read_id.py, I'm going to save that as main.py. We're going to be working with Python for this tutorial. If you're unfamiliar... the status which is ok and then the raw data which is the hexadecimal representation of the id

Using the Raspberry Pi Pico, we have a tutorial to get started. To upload all the source files to your Pico, open Thonny, connect to your Pico, click the first file, hold down shift, click the second file, then right click and upload to. Let's open up main.py on the Pico. This is just a simple example to read the ID off a tag. We import the functionality for the RFID reader and also a sleep function. Then we call the initialization function and we get an RFID module object which we're going to call RFID. There's a prompt to hold a tag near the RFID module. Then there's an infinite loop. If there's a tag present, we call read ID and that returns a string of the ID which we store in a variable called ID. Next, we print it and loop again.

Press the run current script button or ctrl r to run this script and I'll test the script with my three tags. I hold up the card and I get some long string of letters and numbers that is the first ID. For my second tag, I get some other unique ID the same length just with different data. Then for my classic tag, I actually get a shorter ID, so that's one way to tell the difference between these tags.

So there we have it, three unique IDs. I'm going to comment out this read ID line with alt 3 and uncomment the line below it with alt4. This is exactly the same function call except we're giving an argument now detail equals true. This will give us more details about the tag and the status of the read. I'll run the script again with ctrl r and now if I hold one of my end tags to the reader, we get a lot of information printing out into the shell. If we isolate just one of these lines, we can take a closer look at it. We have the type which has been identified as end tag, there's the formatted ID which is the string of letters and numbers that make up the ID, there's the status which is ok, and then the raw data which is the hexadecimal representation of the ID.

A success indicator was achieved; we were able to successfully read the ID from the tag and there was an integers entry in the dictionary which was the tag's ID represented as numbers. When the classic tag was held up, a very similar result was seen. The classic type was present and the ID was the shorter ID, with the integer representation of that same ID. This success flag can be useful for detecting a misread. If the tag is brought in and away too quickly, a mostly empty line is seen with no data read. We don't know the type of the tag or the ID, but we have this success false indicator so we know that there was a bad read.

We have a couple of tags and they all have a unique ID, so let's do an experiment to see if we can make an access control system. We'll say we have a bunch of users with a bunch of tags, but we only want to allow one of those users to unlock a certain door or access a certain computer. We'll return to the article and find the access control example, highlight all of that code and copy it into the main.py file on the Pico. This looks similar to the first example, with ID equals read ID and the ID is printed. There is some extra logic going on here, so let's give the script a run. When prompted to hold a tag nearby, the nice big one is chosen. In the shell, the ID of that tag is seen and access is denied. Let's have a look at the source code; it starts with the same imports and initialization. There is something called authorized users which will be looked at in the infinite loop.

We read the ID of the tag and then we do a check if that ID is in authorized users. In Python, this is a way of saying "Is this string in this list?" If it is, then we print "Access Granted". If it's not, we print "Access Denied". To test this, we copy the string we printed for debugging, paste it into the list of authorized users, and wrap it in quotes so Python knows it's a string. When we re-run the script and hold the same tag, we get "Access Granted". If we hold any other tag to the reader, we get "Access Denied".

Because this is a list, we can also add the blue tag to the list of authorized users. We copy it, add it to the list with a comma and quotes, and now we have a list of two authorized tags. Sure enough, if we hold the tag, we get "Access Granted". If we hold the other tag, we get "Access Granted" and the third tag is still denied.

A really cool feature of these tags is that they can be set up to be interactive. This means that when they're scanned by a smart reader like a smartphone, it can trigger the device to perform some action. This could be opening a web page, composing an email to a specific recipient, or even geographical coordinates to a specific location. We find the example for creating an interactive tag, copy that example code, overwrite everything in main, and take a look at what we're working with. We have the same setup as before and then we have a couple of things to find called URIs. A URI stands for Universal Resource Indicator and that basically tells the scanning device what it is we're looking at - are we looking at a web address or a phone number?

We declare a variable web address and assign it the string of some web address and the URI for that is the http or https URI. We even have an email address and the URI scheme for that is mailto followed by the email address and finally a phone number. In the loop, we check if a tag is present and if it is, then we just write a specific URI to that tag.

By default, we're working with the web address. I'll run this script and hold my tag to the module and the writer is successful and the script finishes. Now for the moment of truth, I'll hold the tag to the back of my phone. There's a buzz and my phone looks like it's opening a web page. There we have it, it's opened up a web page that was specified in the script and this is just a search for all the PiicoDev articles.

Let's try something else. I'll copy the name of that geolocation variable and paste it in, rerun the script, program the tag, and let's see what happens. Now I'll hold the tag to the back of the phone and it's opened up a menu to look at these coordinates and sure enough the map opens and drops a pin right at those coordinates that we were looking at. How good is that?

At the time of writing, this next example is only compatible with NTAG 213 tags. In the last example, the data we were writing was only really useful to some kind of smart device that can read it. This next example is all about writing our own data to the tag and then reading it back using the RFID module so we can use it in our own projects. There's an example here for writing text, so grab that example, copy it into main.py, and let's give it a run. I'll hold my tag to the module and we can see now the tag.

The RFID module has been programmed with the text "Hello World!" and we can see we can encode capital letters and even some other ASCII characters. After the normal initialization, we assign the string "Hello World" to my string and then in the infinite loop we just call RFID.writeText and we're writing my string to the card. You can store up to 143 text characters on one of these cards and just to prove there's no funny business, I'll pull out the readText example and we should be able to read that string back.

I'll run that script, take the same card, hold it to the module and it has pulled out "Hello World". So this one looks very similar, it's just not priming the card with any text at the start. We just call RFID.readText and assign that to my string which is then printed.

We can also write and read numbers or specifically integers which are positive or negative whole numbers. We can store some pretty big numbers on these cards. Find the rightNumbers example and I'll just copy all of that into main.py again. Run the script and we'll write it to the same card so this will overwrite the text essentially. So here I've written the number to the tag 123456. So what's that? That's like a hundred and twenty three thousand four hundred and fifty six.

The same setup as usual, this time we call RFID.writeNumber, we write the number that we want and something called slot equals zero. This is the location of memory in the card that we want to write the data to. In total, there are 36 slots numbered 0 to 35 and slots are just something that we're calling a memory location that's safe to write to. There are actually plenty of other memory locations on an RFID card that you could write to, but these ones you can write to safely without damaging anything. Writing to the other memory locations can be problematic because if you do the wrong thing.

The RFID module can store a 10 digit number, either positive or negative. To prove that it is on the card, the read number function is called. It is possible to have up to four RFID modules connected on the same PiicoDev bus. The only requirement is that they all have unique address switch settings. The address switch is labelled ASW and should be set to off for the first module. For the second module, the first address switch (ASW1) should be set to on.

To take it for a spin, the tag should be held to the first module and the ID of the tag will be displayed in the shell. When the same tag is held to the second module, the same ID will be displayed. This shows that the two devices can be differentiated in the code.

The initialization function has an argument in it (ASW) and a list of parameters.

Two numbers, ASW, represents the address switch also labelled ASW. You can see for our first unit switch 1 is off and switch 2 is off. So, in the first position we have a 0 for off and in the second position we also have a 0 for off. But for reader B, we initialize that with ASW equals one zero because the first switch is on and the second switch is off. So, because that first switch is on, there is a one in this first position.

Then the rest of the script is pretty familiar. We just check if there's a tag present on both readers and print the ID if there is. So, we do our first check the tag reader A and then tag reader B. We check tag present and the print statements are just a little bit different so that in the shell reader A is always printing on the left and B is always printing on the right.

Yeah, the crux of reading from multiple modules is that they have unique switch positions and then when we initialize them we just have to tell our code what the switch positions are. If you're an advanced user and you just prefer to use I2C addresses, you can find the table on the back of the module which decodes the address switch positions into the actual hex addresses for the I2C bus. So, if you prefer to just use addresses then you can change that to equal 0x2C for that first module and of course this would decode into address equals 0x2D and that will work just as well. You can see I can still read from RFID A and RFID B just fine.

So, there you have it. We started pretty simple just reading some basic IDs but pretty soon we were able to change the program so that we could differentiate between tags and change how our program behaved. That was the access control example. Then we moved on to creating interactive tags where we can actually hold them to a smart device like a phone and have it trigger some action like open a map.

Way up to reading from multiple RFID modules, if you make something cool from these starter projects or have some questions, let us know on the article for this tutorial. We're full-time makers and happy to help. Until next time, thanks for watching!

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.