IOT Tutorial: Read RFID-tags with an USB RFID reader, Raspberry Pi and Node-RED from scratch
For an IOT demonstrator I wanted to read RFID-tags with a cheap USB RFID reader connected to a Raspberry Pi. Whereas the same USB devices plugged into a laptop directly sends read tag IDs as a keyboard input, it is way more tricky to retrieve this ID with a Raspberry Pi.
With the Raspberry Pi, the USB RFID reader sends byte arrays which need some parsing before you can get the vanilla ID.
With Node-RED, you can easily prototype this parsing in a conveniant way, which will be described in that tutorial. I will not go too much into detail regarding the format of the byte arrays and the HID message format in general, the approach is more straight forward to get to a result quickly.
What you need
With current raspbian images, Node-RED is already pre-installed. Nevertheless, we will use the flow node-red-contrib-usbhid to interface the usb reader.
We install the flow with the following command:
npm install node-red-contrib-usbhid
If you haven’t installed npm yet on your raspberry pi, you find a quick solution here.
Since reading/writing the USB devices is not allowed with the standard pi user, don’t forget to grant access to those devices as described on the flow-page in the setction “How to use”.
Now we are ready to start. So just enter and execute
node-red-start in your command line and access the dashboard with the IP address that will be displayed in the command line after Node-RED is started.
Find out the vendor ID (VID) and the product ID (PID) of your RFID-reader
In order to read from your USB RFID-reader, you have to register it with vendor ID and device ID. The flow package that we installed earlier provides the node
getHIDdevices for that purpose. Drag and drop it to the flows and connect it with an
inject node as input and an
debug node as output like displayed in the screenshot.
The inject node is automatically parametrized as of type timestamp, but this doesn’t really matter since we just need any type of event to trigger the second node.
Now you can deploy the flow and click on the activation-part of the
inject node to explore the VID and PID of the USB RFID-reader.
For my Neuftech USB-RFID reader, the vendor ID is 5824 and the product ID is 10203.
Create the flows to parse the RFID readings
As we have seen in the beginning, the ID of one read RFID-tag is transmitted in multiple byte arrays with three bytes. We will now build the flow to capture those byta arrays and parse them into one ID.
Connect the HID device
First, drag and drop a node of type
HIDdevice to the flows and double click it for configuration. Create a new HIDConfig by clicking on the pensil icon.
Then enter the retrieved vendor ID and produt ID. You may give that configuration an expressive name as well.
If you want to explore the byte array, connect the
HIDdevice node to a
debug node, deploy the flows and read a RFID-tag with your device. In the debug-pane, you can see the messages containing the byte arrays.
Select only the part of the byte array containing the ID
The byte array consists of three bytes where only the last one is part of the ID. To select only that byte, wee will use a
PS: make sure to connect that function to the first output of the HIDdevice-node because the second output sends only the errors.
You can again check your intermediat results with a debug node.
Filter on ID part to exclude non-expressive bytes
Some of the ID bytes are just empty or line breaks, so we will filter them out with a
switch node that allows for message routing in Node-RED. Therefore we only keep the numbers between 31 and 39, which are mapping to the digits 0–9. To map the numbers on these digits, we will use another function node which we’ll describe in the next section.
Map ID bytes to the digits 0–9
function node we will map the bytes to real digits. I found a mapping table in the great git repo https://github.com/riklaunim/pyusb-keyboard-alike which kind of implements the same logic we build here with Node-RED in Python. There are many examples provided so it is easy to comprehend.
Join the digits to one ID
join node, that we will use in manual mode, messages can be joined together as e.g. strings or arrays. We use a small timemout as the criteria which messages should be joined and concatenate to a string without any characters in between the messages.
The complete flow
After this step, we have covered all necessary steps in order to rebuild the tag ID based on the byte arrays that we retrieve from the USB RFID reader.
After we have build our parsing flow, we can check the results in the debug-panel when we read our RFID-tags with our reader.
Based on Node-RED, we can now further digest this ID, store it to databases or trigger other events and flows.
I will use the parsing flow to use the tag IDs in an industrial IOT demonstrator to try out product-centered process-data acquisition. Which means that I want to attach unique part IDs to process parameters, sensor readings and results from quality inspection to cfreate data for analytics approaches.
[Upate] One word on the USB RFID reader
I ordered my USB RFID reader from Amazon Germany (here is the link: https://amzn.to/2HlTcLW) (affiliate link).
I haven’t found that product on amazon.com, but similar products that looked exactly the same but had different names, like this product (affiliate link).
I don’t have experience with this product, but if they are as identical with my product as they look like, I can recommend them and would give them more than the 3 stars that the product has on Amazon.
Getting a Raspberry Pi
In my setup, I used a Raspberry Pi 3 B+, but it should work as well with older models. If you are not already owning a Raspberry Pi, it makes sense to order a bundle with some of the extras like a case and a SD card. The middle-sized CanaKit (affiliate link) contains all that. Of course you can also just start with a barebone set of the Raspberry Pi (affiliate link) like the one offered by the makers of the Raspberry Pi.