Optimizing Arduino Code for Faster RFID Tag Processing with PN5180 Reader

Title: "Optimizing Arduino Code for Faster RFID Tag Processing with PN5180 Reader"

Text: I am currently working on a project using an Arduino Nano board and a PN5180 reader to read RFID tags from boxes on a conveyor belt. The nature of the project requires fast and efficient reading and processing of the RFID tags. However, I am facing issues with the speed of the program, possibly due to the library used. I am currently using the Arduino ESP-32 library for PN5180-NFC, specifically the tueddy branch on GitHub by ATrappmann. While the program performs well when the RFID tags move at a slower pace on the conveyor belt, it struggles to keep up with the required speed, resulting in a significant number of failed reads.

This challenge is particularly pressing as I lack control over the conveyor belt speed, making it crucial to optimize the code for quicker and more reliable RFID tag processing. Before using the PN5180 reader, I was using the RC522 reader with a different library, and got it to 100% success rate in tag reads. However, I needed the PN5180 for extended range. If anyone in the community has experience with the Arduino or if you can provide guidance on improving the code's efficiency, I would greatly appreciate your insights.

Library: https://github.com/tueddy/PN5180-Library/tree/ISO14443

#include <PN5180.h>
#include <PN5180ISO14443.h>


#define PN5180_NSS 10
#define PN5180_BUSY 9
#define PN5180_RST 7


PN5180ISO14443 nfc14443(PN5180_NSS, PN5180_BUSY, PN5180_RST);


uint8_t previousUid[10];  // Initialize with zeros


void setup() {
  Serial.begin(115200);
  nfc14443.begin();
  nfc14443.reset();
  uint8_t productVersion[2];
  nfc14443.readEEprom(PRODUCT_VERSION, productVersion, sizeof(productVersion));
  uint8_t firmwareVersion[2];
  nfc14443.readEEprom(FIRMWARE_VERSION, firmwareVersion, sizeof(firmwareVersion));
  uint8_t eepromVersion[2];
  nfc14443.readEEprom(EEPROM_VERSION, eepromVersion, sizeof(eepromVersion));
  nfc14443.setupRF();
}


int count;
uint8_t uidLength;
uint8_t uid[10];


void loop() {
  nfc14443.reset();
  nfc14443.setupRF();


  if (!nfc14443.isCardPresent()) {
    return;
  }
  uidLength = nfc14443.readCardSerial(uid);
  Serial.println(uidLength);
  if (memcmp(uid, previousUid, uidLength) == 0) {
    return;
  }
  if (uidLength > 0) {
    printHEX(uid, uidLength);
    // Update the previous UID
    memcpy(previousUid, uid, uidLength);
    return;
  }
}




// Routine to dump a byte array as a continuous HEXimal number to Serial.
void printHEX(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i], HEX);
    Serial.print(":");
  }
  Serial.println("");
}

Do you have basic numbers like:

  • how long does it take to read a tag now?
  • how many tags pass each minute?
  • what is the speed of the conveyer belt?
  • are boxes side by side or behind each other?
  • etc.

You might just gain time by putting the Serial port in a higher gear if the receiving end can cope.
Serial.begin(500000); or even 1 million bits.
That gives more time to the tag-reader.

Are these two lines needed in loop()?

  nfc14443.reset();
  nfc14443.setupRF();

Why?

a minor rewrite

#include <PN5180.h>
#include <PN5180ISO14443.h>

#define PN5180_NSS 10
#define PN5180_BUSY 9
#define PN5180_RST 7

PN5180ISO14443 nfc14443(PN5180_NSS, PN5180_BUSY, PN5180_RST);

uint8_t previousUid[10];  // Initialize with zeros
uint8_t productVersion[2];
uint8_t firmwareVersion[2];
uint8_t eepromVersion[2];

int     count;
uint8_t uidLength;
uint8_t uid[10];

void setup() 
{
  Serial.begin(500000);
  
  nfc14443.begin();
  nfc14443.reset();

  nfc14443.readEEprom(PRODUCT_VERSION, productVersion, sizeof(productVersion));
  nfc14443.readEEprom(FIRMWARE_VERSION, firmwareVersion, sizeof(firmwareVersion));
  nfc14443.readEEprom(EEPROM_VERSION, eepromVersion, sizeof(eepromVersion));

  nfc14443.setupRF();
}

void loop() 
{
  //  nfc14443.reset();
  //  nfc14443.setupRF();

  //  wait  until card present, 
  while (!nfc14443.isCardPresent()) {};  

  //  read it
  uidLength = nfc14443.readCardSerial(uid);
  Serial.println(uidLength);  //  do you want to print it if it is zer0 ?

  //  check with last read, => do fastest test first.
  if (uidLength > 0)
  {
    if (memcmp(uid, previousUid, uidLength) != 0)
    {
      printHEX(uid, uidLength);
      //  Update the previous UID
      memcpy(previousUid, uid, uidLength);
    }
  }
}

// Routine to dump a byte array as a continuous HEXimal number to Serial.
inline void printHEX(byte *buffer, byte bufferSize) 
{
  Serial.println(bufferSize);
  for (byte i = 0; i < bufferSize; i++) 
  {
    Serial.print(buffer[i], HEX);
    Serial.print(':');
  }
  Serial.println();
}

how long does it take to read a tag now? : I dont have a specific time on how long it takes, from tests I have done I noticed that the tags are actually being read but if its passing by too quick it wont have any output i also dont know the exact speed of the conveyor belt.
how many tags pass each minute? : its like 1 tag every 5 to 10 minutes, its really just the speed of that one box every 5 - 10 minutes.

I have tried the code this way but for some reason if those lines are not in the loop, the program just stops reading after about 15 reads sometimes even less and I have to close it and open it up again to get it going again.

could this check be interfering with the read?

does it need to be done each time in loop()?
shouldn't this check be done in setup()?

This is just telling the program to return if there is no card present. This helps the program faster because if there is no card present the program doesn't need to do nothing.
But I will try this method anyway to see what happens.

if there's nothing there it doesn't matter what it does or doesn't do. are you optimizing the case when there's no rfid detector instead of the case when there is

1 Like

@robtillaart @gcjr I just wanted to thank you guys, just finished testing and had a 100% success on 50 reads!! I had spent in total over 25 hours trying to get this to work properly and finally its done.

All I had to do was increase the baud rate as rob had said and I removed the part which was checking is there was a card present like gcjr had said. So thank you both very much.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.