Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No ACK Frame on ESP32 + SPI, hangs after first tag read or no tag reads (With solution) #117

Open
PockyBum522 opened this issue Jun 27, 2023 · 5 comments

Comments

@PockyBum522
Copy link

I was using known working code, and suddenly, after a few days of things working properly, I started getting no tag reads whatsoever when setting setPassiveActivationRetries(0x01); in the iso14443a_uid example.

Alternate behavior observed: It would read the tag once fine, then hang on the next readPassiveTargetID(); after a tag was read.

I enabled some of the debugs in the library, and saw there was NO ACK FRAME messages when it tried to send data to the PN532.

I made changes in Adafruit_PN532.cpp:

Under line 335 where it says // I2C TUNING
I changed this on line 336:

delay(SLOWDOWN); (Original line in 1.3.1)

to delay(1); (My modification.)

This means a delay of 1ms no matter what interface you're using. I'm using SPI. Before the modification, the library would only delay if you're using i2c. This fixed my issue.

I have board v1.3, I am using library 1.3.1. I see this behavior on two separate Adafruit PN532 boards. Both 1.3. This fixed the issue on both of them. I'm using a ESP32-S3-DevKitC-1 with both boards (Not the same one, this issue exists on two independent adafruit boards with a different ESP32-S3-DevKitC-1 on each.

The weirdest part is it WAS WORKING on one of the setups without the delay a few days ago, and was working solidly for a few days so it wasn't a fluke. I'm guessing the PN532 is just on the hairy edge of responding fast enough.

Let me know if I should pull request this, I'd be happy to. I have tested it with the iso14443a_uid example with and without the library modifications several times. It reliably breaks/fixes things when I remove/add that delay(1);

@PockyBum522
Copy link
Author

If it ends up mattering, pins used are:

#define PN532_SS 5
#define PN532_SCK 6
#define PN532_MOSI 7
#define PN532_MISO 8

@OguzCiftci
Copy link

Sir, you are a lifesaver ❤️

@MaxMyzer
Copy link

MaxMyzer commented Mar 3, 2024

Hello,

Just wanted to add this is not exclusive to ESP32, I was able to reproduce it on an Arduino RP2040 Connect.

@PockyBum522
Copy link
Author

The original board I was using when I made my first post was a ESP32-S3-DevKitC-1. I don't know why I didn't put that.

Today, a year later, I needed to use the adafruit shield with a different board, the ethernet enabled WT32-ETH01

I remembered the issue I ran into before where the library needed the delay(1); even on SPI. However, while this worked fine to get it working on a short connection, I needed to run the connection for this new installation about 40cm, and I chose a CAT6 cable just because it's easy and everything is contained. The PN532 board did not like this combination of cabling and board.

I got confusing instances where ACK frames would say they're dropping when I turned debug on, and confusing instances where the library would say it found the pn532 board when checked with const uint32_t versiondata = m_nfc.getFirmwareVersion(); BUT then would not loop when I check for a tag constantly in loop. The PN532 board would just hang.

Solution:
In the Adafruit_PN532.cpp file, on line 93, where it say:

Adafruit_PN532::Adafruit_PN532(uint8_t clk, uint8_t miso, uint8_t mosi,
                               uint8_t ss) {
  _cs = ss;
  spi_dev = new Adafruit_SPIDevice(ss, clk, miso, mosi, 1000000,
                                   SPI_BITORDER_LSBFIRST, SPI_MODE0);
}

Change the 1000000 to 300000:

Adafruit_PN532::Adafruit_PN532(uint8_t clk, uint8_t miso, uint8_t mosi,
                               uint8_t ss) {
  _cs = ss;
  spi_dev = new Adafruit_SPIDevice(ss, clk, miso, mosi, 300000,
                                   SPI_BITORDER_LSBFIRST, SPI_MODE0);
}

Note that this of course assumes you're setting up the device with this constructor, specifying all the pins. If you're using another constructor in Adafruit_PN532.cpp to set up the NFC board, then modify the speed on that particular constructor.

This also makes it so you do not need the delay(1); outlined in my original post. This is likely a better solution.

@caternuson if I PR'd an additional constructor where a speed override can be specified, would that be alright?

Alternatively, I saw someone in another issue requesting a constructor overload where you can just pass in your own Adafruit_SPIDevice and that would also be helpful, as I could just set the speed then, and pass that in to init the PN532 board.

I'd be happy to help with either of those. They're both simple, but I'm sure clicking merge is still easier. Let me know.

@PockyBum522
Copy link
Author

PockyBum522 commented Aug 8, 2024

If anyone would like to use it, I've added a constructor overload to the below fork that takes in an Adafruit_SPIDevice.

If using platformIO you can start using it with:

lib_deps =
    adafruit/Adafruit BusIO @ ^1.16.1
    https://github.com/PockyBum522/Adafruit-PN532-custom-spi

In your platformio.ini file.

This particular commit is tested and known working with the WT32-ETH01, and likely will work fine for multiple ESP32s that have dropped ACK frame issues:
PockyBum522/wt32-eth01-pn532-reader@92f0df8

It basically boils down to setting things up like this:

auto spiDevice = new Adafruit_SPIDevice(PN532_SS, PN532_SCK, PN532_MISO, PN532_MOSI,
    300000, SPI_BITORDER_LSBFIRST, SPI_MODE0);

Adafruit_PN532 m_nfc(PN532_SS, spiDevice);

at the top of your code, instead of the old way of calling Adafruit_PN532 with all the SPI pins, and then everything else should be able to be used as it was before, once you have setup those new lines.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants