Getting a PN532 NFC to work on UART

OttoES
Posts: 2
Joined: Sat Feb 17, 2018 5:01 am

Getting a PN532 NFC to work on UART

Postby OttoES » Sat Feb 17, 2018 7:53 am

This is a summary of getting a PN532 to work on the UART to help other who might have the same problem.
I used this arduino library for the PN532 https://github.com/elechouse/PN532
It basically worked first time on the SPI but I only had 3 pins left so tried to switch to UART 2.

Changed this in the PN532 "iso14443 example"

Code: Select all

#elif 1
  #include <PN532_HSU.h>
  #include <PN532.h>
  HardwareSerial Serial1(1);      <------------------  add this
  PN532_HSU pn532hsu(Serial1);
  PN532 nfc(pn532hsu);
The first surprise was that the default pins can not be used. This can be changed in one of 2 ways, change the defaults in begin function in the file:
<install directory>\Arduino\hardware\espressif\esp32\cores\esp32\HardwareSerial.cpp

Code: Select all

 if(_uart_nr == 1 && rxPin < 0 && txPin < 0) {
        rxPin = 16;   <---------------------your pin number
        txPin = 15;    <--------------------- your pin number
    }
Alternatively the pins can be specified in the begin function call in PN532_HSU.cpp as follows (this will probably result in a compile error if you try to use the library with another arduio that is not an ESP32)

Code: Select all

void PN532_HSU::begin()
{
    _serial->begin(115200,SERIAL_8N1,16,13);  <------- your pin assignments
}
Note: the best would be to change the begin function to add the pins as arguments,e.g. ser.begin(rxPin,txPin);

I initially called

Code: Select all

Serial1.begin(115200, SERIAL_8N1, 16, 15);
in setup() but that does not work since begin() is called again in the PN532 begin code and over write these values. On a scope I could see that the data send is correct and that the PN532 replies correctly. I initially thought that it is a baud rate problem on the receive side but after some experimentation found that I should not call the begin() function in setup(), it should only be called from the PN532_HSU begin().

Currently I am not sure if the problem is because serial1.begin() was called twice or because set HardwareSerial::changeBaud() is called twice (indirectly through begin). I suspect the latter because of the error reported in https://github.com/espressif/arduino-esp32/issues/441

Hope this helps somebody.

GeorgeFlorian1
Posts: 160
Joined: Thu Jan 31, 2019 2:32 pm

Re: Getting a PN532 NFC to work on UART

Postby GeorgeFlorian1 » Mon Feb 08, 2021 12:52 pm

OttoES wrote:
Sat Feb 17, 2018 7:53 am
This is a summary of getting a PN532 to work on the UART to help other who might have the same problem.
I used this arduino library for the PN532 https://github.com/elechouse/PN532
It basically worked first time on the SPI but I only had 3 pins left so tried to switch to UART 2.

Changed this in the PN532 "iso14443 example"

Code: Select all

#elif 1
  #include <PN532_HSU.h>
  #include <PN532.h>
  HardwareSerial Serial1(1);      <------------------  add this
  PN532_HSU pn532hsu(Serial1);
  PN532 nfc(pn532hsu);
The first surprise was that the default pins can not be used. This can be changed in one of 2 ways, change the defaults in begin function in the file:
<install directory>\Arduino\hardware\espressif\esp32\cores\esp32\HardwareSerial.cpp

Code: Select all

 if(_uart_nr == 1 && rxPin < 0 && txPin < 0) {
        rxPin = 16;   <---------------------your pin number
        txPin = 15;    <--------------------- your pin number
    }
Alternatively the pins can be specified in the begin function call in PN532_HSU.cpp as follows (this will probably result in a compile error if you try to use the library with another arduio that is not an ESP32)

Code: Select all

void PN532_HSU::begin()
{
    _serial->begin(115200,SERIAL_8N1,16,13);  <------- your pin assignments
}
Note: the best would be to change the begin function to add the pins as arguments,e.g. ser.begin(rxPin,txPin);

I initially called

Code: Select all

Serial1.begin(115200, SERIAL_8N1, 16, 15);
in setup() but that does not work since begin() is called again in the PN532 begin code and over write these values. On a scope I could see that the data send is correct and that the PN532 replies correctly. I initially thought that it is a baud rate problem on the receive side but after some experimentation found that I should not call the begin() function in setup(), it should only be called from the PN532_HSU begin().

Currently I am not sure if the problem is because serial1.begin() was called twice or because set HardwareSerial::changeBaud() is called twice (indirectly through begin). I suspect the latter because of the error reported in https://github.com/espressif/arduino-esp32/issues/441

Hope this helps somebody.
I'm trying to integrate RFID1356MIFARE with an ESP32-EVB using an UEXT ribbon.

I'm using https://github.com/elechouse/PN532 library.
I've modified PN532_HSU.cpp as follows:

Code: Select all

void PN532_HSU::begin()
{
    _serial->begin(38400, SERIAL_8N1, 36, 4);
}
I've tried this code:

Code: Select all

  #include <PN532_HSU.h>
  #include <PN532.h>
  
void setup(void) {
  Serial.begin(115200);
  Serial.println("Hello!");

  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    while (1); // halt
  }
  
  // Got ok data, print it out!
  Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX); 
  Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC); 
  Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
  
  // Set the max number of retry attempts to read from a card
  // This prevents us from waiting forever for a card, which is
  // the default behaviour of the PN532.
  nfc.setPassiveActivationRetries(0xFF);
  
  // configure board to read RFID tags
  nfc.SAMConfig();
    
  Serial.println("Waiting for an ISO14443A card");
}

void loop(void) {
  boolean success;
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
  uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
  
  // Wait for an ISO14443A type cards (Mifare, etc.).  When one is found
  // 'uid' will be populated with the UID, and uidLength will indicate
  // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength);
  
  if (success) {
    Serial.println("Found a card!");
    Serial.print("UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
    Serial.print("UID Value: ");
    for (uint8_t i=0; i < uidLength; i++) 
    {
      Serial.print(" 0x");Serial.print(uid[i], HEX); 
    }
    Serial.println("");
    // Wait 1 second before continuing
    delay(1000);
  }
  else
  {
    // PN532 probably timed out waiting for a card
    Serial.println("Timed out waiting for a card");
  }
}
And the only thing I get is "Didn't find PN53x board".

Simple code like the following one works. I receive data from Serial1:

Code: Select all

if(Serial1.available()) {
  Serial.print(Serial1.read());
  Serial.print(" ");
}

Who is online

Users browsing this forum: No registered users and 66 guests