adafruit / Adafruit-PN532

Arduino library for SPI and I2C access to the PN532 RFID/Near Field Communication chip
Other
422 stars 266 forks source link

ESP32 SPI #80

Closed morgan-wild closed 1 year ago

morgan-wild commented 4 years ago

Hi everybody.

The ESP32 is marked as tested in the compatibility table. But if I use this example sketch with the M5Stack pinout, the board is not detected:

https://github.com/adafruit/Adafruit-PN532/blob/master/examples/ntag2xx_read/ntag2xx_read.ino

M5Stack SPI pinout :

define PN532_SCK (18)

define PN532_MOSI (23)

define PN532_SS (16)

define PN532_MISO (19)

I'm sure my wiring is okay because if I use the following library from Seeed Studio it WORKS!!! (the module is detected, cards readed, it is just complicated to use multiple devices on the SPI with it :s ) : https://github.com/Seeed-Studio/PN532

Adafruit guys, dear LadayAda, are you sure this lib is really/still compatible with the ESP32?

I really want to use the Adafruit version, your support is great and your code too. Regards.

reeganm commented 4 years ago

I was running into this issue as well. Got it to work wired to the VSPI port (see near the end of this for pins: https://randomnerdtutorials.com/esp32-pinout-reference-gpios/ I'm not sure how these line up on your specific board) and the following code:

#define PN532_SS   5  // you can change this if you want
Adafruit_PN532 nfc(PN532_SS);  // This defaults to using the VSPI port

Other SPI pins might require some adjustments to the library.

Also had to change the bitrate of 1000000 defined here https://github.com/adafruit/Adafruit-PN532/blob/master/Adafruit_PN532.cpp#L148 to 100000 when running the esp clk at 240 MHz in order to make the communication less glitchy. I think there is something wrong with how the bitrate is set on the esp32 1000000 isn't very fast and should work fine.

beicnet commented 4 years ago

Hi @reeganm are you familiar with WeMos D1 mini maybe?

reeganm commented 4 years ago

Hi @reeganm are you familiar with WeMos D1 mini maybe?

I am not

beicnet commented 4 years ago

Hi @reeganm are you familiar with WeMos D1 mini maybe?

I am not

Ok, are you had a chance to use PN532 module with HttpClient library?

morgan-wild commented 4 years ago

@reeganm Thank you so much!!!!

I tried simply Adafruit_PN532(PIN_PN532_SS) and modified the library to set 100000 and it works! Beyond that, I can now use one PN532 and a LoRa module (also using SPI) without any issues.

What is the best way to fix it on the repository? A merge request with something like :

Adafruit_PN532::Adafruit_PN532(uint8_t ss) {

    #ifdef ESP32
        uint32_t frequency = 100000;
    #else
        uint32_t frequency = 1000000;
    #endif

    spi_dev = new Adafruit_SPIDevice(ss, frequency, SPI_BITORDER_LSBFIRST, SPI_MODE0);
}

Best regards!

reeganm commented 4 years ago

I'm glad it worked! I would do something slight different like defining this near the top of the file:

#ifdef ESP32
#define SPI_FREQUENCY 100000
#else
#define SPI_FREQUENCY 1000000
#end

And then changing both:

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

and

Adafruit_PN532::Adafruit_PN532(uint8_t ss) {
  spi_dev =
      new Adafruit_SPIDevice(ss, SPI_FREQUENCY, SPI_BITORDER_LSBFIRST, SPI_MODE0);
}

I feel this is a bit cleaner. However, this is still more of a hack fix than a proper fix. Are you able to test with it set to 1000000 and confirm with a oscilloscope that the SPI bus actually runs at 1 MHz? (I would borrow one from my university but it is closed.) If it isn't (I assume it is going faster than the PN532's maximum of 5 MHz) it is probably better to fix that than randomly change the value set in this library. The issue would then either be here: https://github.com/adafruit/Adafruit_BusIO/blob/master/Adafruit_SPIDevice.cpp or in the ESP code: https://github.com/espressif/arduino-esp32/tree/master/libraries/SPI/src

It would also be good to test with the 100000 and see what the speed actually is.

On a side note, for software SPI, the frequency setting doesn't actually appear to do anything. https://github.com/adafruit/Adafruit_BusIO/blob/master/Adafruit_SPIDevice.cpp#L103 . When sending it just shifts the bits as fast as possible. It would be interesting to see how fast the ESP does that and could possibly be the reason software spi wasn't working.

morgan-wild commented 4 years ago

Hi!

You are right, your fix is cleaner! I'm not able to check the SPI with an oscilloscope rigth now, maybe soon.

Thank you for all your time :)

emichristiansen commented 4 years ago

Thanks guys! I think I'm gonna cry! I've lost days trying to make this work!!

s-murtadha commented 4 years ago

Dears, I have tried this solution on PlatformIO framework and still, it is not working (setting the frequency to 100KHz). Also, I have solved it several weeks ago by adding delays in the read and write functions in Adafruit_PN532.cpp and Adafruit_SPIDevice.cpp nevertheless, it does not work anymore... Does anyone still have the same issue yet? #80

emitategh commented 4 years ago

@s-murtadha which pins are you using? (Sorry I don't know what is PlatformIO) I'm using Arduino IDE 1.8.12 I'll leave my configuration. I'm using an ESP32 with the following pinout:

image

The PN532 is on VSPI, with the before mentioned configuration. On HSPI I have an SD card module, but, instead of having MISO on pin 12, I've connected it to pin 27.

I'll paste the relevant code sections.

My Code

...
#define SD_CS 15
#define NFC_CS 5

#define PN532_SCK  (18)
#define PN532_MOSI (23)
#define PN532_SS   (NFC_CS)
#define PN532_MISO (19)

#define SD_SCK (14)
#define SD_MISO (27)
#define SD_MOSI (13)
...
SPIClass SPI_SD(HSPI);
SPIClass SPI_NFC(VSPI);
...
Adafruit_PN532 nfc(PN532_SS);
....
SPI_NFC.begin(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);  
nfc.begin();
....
 SPI_SD.begin(SD_SCK, SD_MISO, SD_MOSI, -1);
 if(!SD.begin(SD_CS,SPI_SD)){
....

and on Adafruit_PN532.cpp I've made the changes as @reeganm suggested.

Please check for any loose wire. Hope it helps!

s-murtadha commented 4 years ago

@emitategh I am using this set of pins:

#define PN532_SCK 21
#define PN532_MISO 22
#define PN532_MOSI 23
#define PN532_SS_1 25 // Reader 1
#define PN532_SS_2 26 // Reader 2

What I have noticed is that when I turn on the debugger in Adafruit_PN532.cpp, the code works and when I turn it off the ESP is no longer able to identify the NFC readers!

#define PN532DEBUG
// #define MIFAREDEBUG

// If using Native Port on Arduino Zero or Due define as SerialUSB
#define PN532DEBUGPRINT Serial
//#define PN532DEBUGPRINT SerialUSB

I have checked every line added by the debugger, all of them are for printing values only, what do you think the reason behind that? My guess is that extra time taken by the ESP to print the messages is giving the NFC readers the time to send their messages, but really not sure about it..

reeganm commented 4 years ago

@s-murtadha looking at the commit history, the software spi used to have a bunch of delays in the code but someone took them out. Adding them back might help.

Update on my original comment: I dug out my logic analyzer and measured the spi clock frequency with the original 1 MHz spi frequency code. image It is running at the proper 1 MHz so we can rule out improper frequency as an issue :( I wonder if it is also just an issue of time between commands that is causing issues with hardware SPI.

pdockery commented 4 years ago

[New commenter.]

I'm experiencing a similar issue with the bitrate when using this library with the Arduino Nano Every.

I am using the hardware SPI,

define PN532_SS (8)

Adafruit_PN532 nfc(PN532_SS);

At a bitrate of 1000000 I experience intermittent communication issues. When I reduce the bitrate to 100000, the intermittent issue connecting to the PN532 board and reading NFC cards works.

kami83 commented 3 years ago

Hi,

this doesn't work for me. I just have to put a small delay(10) in the "sendCommandCheckAck" command. Now everything works fine.

`bool Adafruit_PN532::sendCommandCheckAck(uint8_t *cmd, uint8_t cmdlen, uint16_t timeout) { // uint16_t timer = 0;

// write the command writecommand(cmd, cmdlen);

// Wait for chip to say its ready! if (!waitready(timeout)) { return false; } delay(10);

ifdef PN532DEBUG

if (spi_dev == NULL) { PN532DEBUGPRINT.println(F("IRQ received")); }

endif

// read acknowledgement if (!readack()) {

ifdef PN532DEBUG

PN532DEBUGPRINT.println(F("No ACK frame received!"));

endif

return false;

}

// For SPI only wait for the chip to be ready again. // This is unnecessary with I2C. if (spi_dev != NULL) { if (!waitready(timeout)) { return false; } }

return true; // ack'd command }`

kami83 commented 3 years ago

Hi, have to correct my reply. For now it only works if i set the SPIFrequence to 100000, put a delay in the sendCommandCheckAck function and also i have to activate the PN532DEBUG function. if i do this 3 steps everytime when i replug the USB ESP32 port or just REBOOT it. Everything is stable and fine. Can someone help why the ESP32 is doing this and is not working with out the 3 steps?

Thx a lot.

Cu kami

Gregwar commented 3 years ago

Hello,

I have my PN532 connected to my ESP32 through VSPI, and it is working fine with Mifare Classic (4 bytes UID) but not Ultralight (7 bytes UID). (Note that in my application I am just reading UIDs to detect objects presence.)

It appears that the following piece of code is reading 20 bytes, 13+ being the UID. However, looks like there is more data after the UID, making the FIFO not empty and subsequent calls failing.

Increasing this 20 to 32 works for me (again, I am only reading UIDs).

// Adafruit_PN532.cpp L570

bool Adafruit_PN532::readDetectedPassiveTargetID(uint8_t *uid,
                                                 uint8_t *uidLength) {
  // read data packet
  readdata(pn532_packetbuffer, 20); // <--- XXX Isue#80: Try Increasing to 32
  // check some basic stuff

  /* ISO14443A card response should be in the following format:

    byte            Description
    -------------   ------------------------------------------
    b0..6           Frame header and preamble
    b7              Tags Found
    b8              Tag Number (only one used in this example)
    b9..10          SENS_RES
    b11             SEL_RES
    b12             NFCID Length
    b13..NFCIDLen   NFCID                                      */

Adding delay in sendCommandCheckAck also works, even though I am not sure why.

mengguang commented 3 years ago

Same SPI speed problem.
In my test on ESP32: The fastest software SPI speed works reliable is 300000.

  spi_dev = new Adafruit_SPIDevice(ss, clk, miso, mosi, 300000,
                                   SPI_BITORDER_LSBFIRST, SPI_MODE0);

The fastest hardware SPI speed works reliable is also 300000.

  spi_dev =
      new Adafruit_SPIDevice(ss, 300000, SPI_BITORDER_LSBFIRST, SPI_MODE0);
Vividious commented 2 years ago

I have tried all of proposed adjustments to the library, none worked for me. Is there an another way to make it work with ESP32?

schieck0 commented 2 years ago

Same problem here with 1.2.2 version. Changing the frequency didn't fix it. With version 1.0.4 works fine. My ports are:

#define PN532_MOSI (23)
#define PN532_SS   (22)
#define PN532_MISO (19)
#define PN532_SCK  (18)
braysonjohn148 commented 2 years ago

I have tried all of proposed adjustments to the library, none worked for me. Is there an another way to make it work with ESP32?

Did you get any solution. I tried all the above, nothing worked. I have my RST connected to GIO27. Am wondering if I should unplug it.

braysonjohn148 commented 2 years ago

I have tried all of proposed adjustments to the library, none worked for me. Is there an another way to make it work with ESP32?

Did you get any solution. I tried all the above, nothing worked. I have my RST connected to GIO27. Am wondering if I should unplug it.

I got it to work. After failing to do all the above. I found out there is a switch on your module PN532 switch it to the mode of communication you are using.

johnhmccauley commented 1 year ago

I have tried 1.2.3, 1.2.2 and 1.04. Made the changes suggested, still not able to get it to work.

`

define PN532_SCK (SCK) // 18

define PN532_MOSI (MOSI) // 23

define PN532_SS (SS) // 5

define PN532_MISO (MISO) // 19

Adafruit_PN532 nfc(PN532_SS); `

caternuson commented 1 year ago

Should be fixed with recent updates. Confirmed working with a Feather ESP32 V2 and readMifare example.

jerryg2003 commented 1 year ago

@caternuson I have PN532 board that works fine when connected to Arduino using SPI, identifies firmware with ESP32 (SPI pins defined as above) but won’t recognize cards (with debug on in Adafruit library, gets a TIMEOUT every time it loops through). I tried all the changes suggested above to modify Adafruit_PN532.cpp with the same result. Is anyone else having this problem? [Using version 1.3.1 of the library]

jef-sure commented 1 year ago

I am so glad that I found your discussion here :) I fought the same problem in my own PN532 module for ESP-IDF. Delay between wait_ready and read_ack really helped me.

jerryg2003 commented 1 year ago

Unfortunately, I tried that and still does not work for me.