logo elektroda
logo elektroda
X
logo elektroda

ESP32-S3-WROOM-1 with PN532: no reading of NFC tags in I2C and SPI mode. What to do?

Heweliusz03 2445 10
Best answers LABEL_AI_GENERATED

How can I get a PN532 reader to reliably read NFC tags with an ESP32-S3 over I2C or SPI when the reader is detected but tags are not read?

Try the PN532 on 3.3 V and add external pull-up resistors on SDA and SCL, because the board may not have usable pull-ups on its I2C lines and the reader board often uses about 4.7 kΩ pull-ups internally [#21442713][#21444281] One suggested fix was to parallel the existing pull-ups with another 4.7 kΩ on each line to strengthen I2C signalling [#21442713] In the reported case, adding 2.35 kΩ pull-ups made the scanner stop detecting the module, so the I2C connection remained unstable rather than fully solved [#21453309] Later the poster said there was no unequivocal solution and that communication with the PN532 on the ESP32-S3 could be very capricious, so if the setup must be dependable they fell back to using an Arduino [#21768393]
AI summary based on the discussion. May contain errors.
ADVERTISEMENT
Treść została przetłumaczona polish » english Zobacz oryginalną wersję tematu
  • PN532 detected on I2C but no tag reads on ESP32-S3

    #1 21439390
    Heweliusz03
    Level 5  
    Posts: 108
    Help: 1
    Rate: 6
    Hello,
    I have a PN532 RFID reader
    RFID reader PN532 on a red PCB board .
    I have used it before, connecting it to an Arduino Nano. Now I have switched to ESP32, specifically ESP32-S3-WROOM-1, and a problem arises. In I2C mode, the scanner detects the reader, but in no way am I able to read any tag. Example program on I2C:
    #include <Wire.h>
    #include <Adafruit_PN532.h>
    
    // Definiujemy piny I2C dla ESP32-S3
    #define SDA_PIN 12
    #define SCL_PIN 13
    
    // Definiujemy piny IRQ i RESET (jeśli nie podłączone, zostaw -1)
    #define IRQ_PIN -1
    #define RESET_PIN -1
    
    // Inicjalizacja PN532 przez I2C
    Adafruit_PN532 nfc(IRQ_PIN, RESET_PIN);
    
    void setup() {
        Serial.begin(115200);
        while (!Serial) delay(10); // Czekaj na otwarcie portu szeregowego
    
        Serial.println("Inicjalizacja PN532 (I2C)...");
    
        // Inicjalizacja I2C na ESP32-S3
        Wire.begin(SDA_PIN, SCL_PIN);
        Wire.setClock(100000);  // Ustawienie prędkości I2C na 100 kHz
    
        // Opóźnienie na stabilizację
        delay(100);
    
        // Inicjalizacja PN532
        nfc.begin();
    
        // Sprawdzenie komunikacji z PN532
        uint32_t versiondata = nfc.getFirmwareVersion();
        if (!versiondata) {
            Serial.println(" Błąd: NIE WYKRYTO PN532 przez I2C!");
            Serial.println(" Sprawdź połączenia SDA/SCL i tryb pracy modułu.");
            while (1);  // Zatrzymujemy program
        }
    
        Serial.print(" PN532 wykryty! Wersja firmware: 0x");
        Serial.println((versiondata >> 24) & 0xFF, HEX);
        Serial.print("Firmware ver. ");
        Serial.print((versiondata >> 16) & 0xFF, DEC);
        Serial.print('.');
        Serial.println((versiondata >> 8) & 0xFF, DEC);
    
        // Ustawienie czytnika w tryb odczytu kart NFC
        nfc.SAMConfig();
        Serial.println(" PN532 gotowy! Przyłóż kartę NFC...");
    }
    
    void loop() {
        uint8_t uid[7];  // Tablica na UID karty
        uint8_t uidLength;
    
        Serial.println(" Czekam na kartę...");
    
        // Sprawdzenie, czy karta jest w zasięgu
        if (nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength)) {
            Serial.println(" Karta wykryta!");
    
            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(uid[i], HEX);
                Serial.print(" ");
            }
            Serial.println("\n");
    
            delay(2000);  // Poczekaj przed kolejnym odczytem
        } else {
            Serial.println(" Brak karty w zasięgu.");
        }
    
        delay(500);  // Krótkie opóźnienie przed kolejnym sprawdzeniem
    }
    
    .
    After switching to SPI, zero communication, example program:
    #include <SPI.h>
    #include <Adafruit_PN532.h>
    
    // Definiujemy piny SPI dla ESP32-S3
    #define SS_PIN 42   // Chip Select (CS) – Możesz zmienić
    #define SCK_PIN 12
    #define MISO_PIN 13
    #define MOSI_PIN 11
    
    // Tworzymy obiekt PN532 dla SPI
    Adafruit_PN532 nfc(SS_PIN, &SPI);
    
    void setup() {
        Serial.begin(115200);
        Serial.println("Inicjalizacja PN532 (SPI)...");
    
        // Inicjalizacja SPI z wymuszeniem pinów
        SPI.begin(SCK_PIN, MISO_PIN, MOSI_PIN, SS_PIN);
        SPI.beginTransaction(SPISettings(100000, MSBFIRST, SPI_MODE0)); // Zmniejszona prędkość SPI
    
        // Inicjalizacja czytnika PN532
        nfc.begin();
    
        uint32_t versiondata = nfc.getFirmwareVersion();
        if (!versiondata) {
            Serial.println("Błąd: NIE WYKRYTO PN532 przez SPI!");
            Serial.println("Sprawdź połączenia i tryb SPI.");
            while (1);  // Zatrzymujemy program
        }
    
        Serial.print("PN532 wykryty! Wersja firmware: 0x");
        Serial.println((versiondata >> 16) & 0xFF, HEX);
    
        // Ustawienie czytnika w tryb odczytu NFC
        nfc.SAMConfig();
        Serial.println("PN532 gotowy! Przyłóż kartę NFC...");
    }
    
    void loop() {
        uint8_t uid[7];  // UID karty
        uint8_t uidLength;
    
        Serial.println("Czekam na kartę...");
    
        // Sprawdzenie obecności karty
        if (nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength)) {
            Serial.println("Karta wykryta!");
    
            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(uid[i], HEX);
                Serial.print(" ");
            }
            Serial.println("\n");
    
            delay(2000);  // Poczekaj przed kolejnym odczytem
        } else {
            Serial.println("Brak karty w zasięgu.");
        }
    
        delay(500);  // Krótkie opóźnienie przed kolejnym sprawdzeniem
    }
    
    .
    But interestingly leaving exactly the same pins and changing the reader to RC522 everything works without any problem, code for RC522:
    /*
     * --------------------------------------------------------------------------------------------------------------------
     * Example showing how to read data from a PICC to serial.
     * --------------------------------------------------------------------------------------------------------------------
     * This is a MFRC522 library example; for further details and other examples see: https://github.com/OSSLibraries/Arduino_MFRC522v2
     * 
     * Example sketch/program showing how to read data from a PICC (that is: a RFID Tag or Card) using a MFRC522 based RFID
     * Reader on the Arduino SPI interface.
     * 
     * When the Arduino and the MFRC522 module are connected (see the pin layout below), load this sketch into Arduino IDE
     * then verify/compile and upload it. To see the output: use Tools, Serial Monitor of the IDE (hit Ctrl+Shift+M). When
     * you present a PICC (that is: a RFID Tag or Card) at reading distance of the MFRC522 Reader/PCD, the serial output
     * will show the ID/UID, type and any data blocks it can read. Note: you may see "Timeout in communication" messages
     * when removing the PICC from reading distance too early.
     * 
     * If your reader supports it, this sketch/program will read all the PICCs presented (that is: multiple tag reading).
     * So if you stack two or more PICCs on top of each other and present them to the reader, it will first output all
     * details of the first and then the next PICC. Note that this may take some time as all data blocks are dumped, so
     * keep the PICCs at reading distance until complete.
     * 
     * @license Released into the public domain.
     * 
     * Typical pin layout used:
     * -----------------------------------------------------------------------------------------
     *             MFRC522      Arduino       Arduino   Arduino    Arduino          Arduino
     *             Reader/PCD   Uno/101       Mega      Nano v3    Leonardo/Micro   Pro Micro
     * Signal      Pin          Pin           Pin       Pin        Pin              Pin
     * -----------------------------------------------------------------------------------------
     * SPI SS      SDA(SS)      10            53        D10        10               10
     * SPI MOSI    MOSI         11 / ICSP-4   51        D11        ICSP-4           16
     * SPI MISO    MISO         12 / ICSP-1   50        D12        ICSP-1           14
     * SPI SCK     SCK          13 / ICSP-3   52        D13        ICSP-3           15
     *
     * Not found? For more see: https://github.com/OSSLibraries/Arduino_MFRC522v2#pin-layout
     */
    
    #include <MFRC522v2.h>
    #include <MFRC522DriverSPI.h>
    //#include <MFRC522DriverI2C.h>
    #include <MFRC522DriverPinSimple.h>
    #include <MFRC522Debug.h>
    
    MFRC522DriverPinSimple ss_pin(42); // Configurable, see typical pin layout above.
    
    MFRC522DriverSPI driver{ss_pin}; // Create SPI driver.
    //MFRC522DriverI2C driver{}; // Create I2C driver.
    MFRC522 mfrc522{driver};  // Create MFRC522 instance.
    
    void setup() {
      Serial.begin(115200);  // Initialize serial communications with the PC for debugging.
      while (!Serial);     // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4).
      mfrc522.PCD_Init();  // Init MFRC522 board.
      MFRC522Debug::PCD_DumpVersionToSerial(mfrc522, Serial);   // Show details of PCD - MFRC522 Card Reader details.
       Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
    }
    
    void loop() {
       // Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
       if ( !mfrc522.PICC_IsNewCardPresent()) {
          return;
       }
    
       // Select one of the cards.
       if ( !mfrc522.PICC_ReadCardSerial()) {
          return;
       }
    
       // Dump debug info about the card; PICC_HaltA() is automatically called.
      MFRC522Debug::PICC_DumpToSerial(mfrc522, Serial, &(mfrc522.uid));
    }
    
    .
    I found several threads on Reddit on this subject, but none of these solutions helped.
  • ADVERTISEMENT
  • #2 21442458
    Anonymous
    Level 1  
  • ADVERTISEMENT
  • #3 21442580
    Heweliusz03
    Level 5  
    Posts: 108
    Help: 1
    Rate: 6
    I checked both on 5V and on 3.3V
  • ADVERTISEMENT
  • #4 21442713
    Anonymous
    Level 1  
  • ADVERTISEMENT
  • #5 21444176
    Heweliusz03
    Level 5  
    Posts: 108
    Help: 1
    Rate: 6
    Here it is straightforward to identify these resistors:
    Electronic module with a red laminate, featuring integrated circuits and connectors labeled GND, VCC, SDA, SCL. .
    However, on my board it is no longer so colourful and it seems to me that the scl and sda go straight to the circuit:
    Red printed circuit board with various electronic components, including resistors and an integrated circuit. .
  • #6 21444281
    Anonymous
    Level 1  
  • #7 21453309
    Heweliusz03
    Level 5  
    Posts: 108
    Help: 1
    Rate: 6
    Adding the 2.35k pull-up resistors, unfortunately only caused it to stop detecting anything on the scanner. I would like to communicate with this reader in any way possible
  • #8 21768069
    princekakkad10
    Level 2  
    Posts: 2
    Have You found any solution to this problem? If yes then please could you share it with us as well...

    Added after 8 [minutes]:

    @Heweliusz03 Could you Please share the code which you where using with arduino which was working for you and please could you share what mode you have used as well..
  • #9 21768393
    Heweliusz03
    Level 5  
    Posts: 108
    Help: 1
    Rate: 6
    I have not found an unequivocal solution. After a few attempts I have managed to communicate, but this connection can be very capricious. So where the circuit requires me to use a PN532, I usually just connect it to the Arduino
  • #10 21768686
    princekakkad10
    Level 2  
    Posts: 2
    >>21453309 Could you please share any example code which are working for you in Arduino any simple example code so that I can get idea how it is being created, and also if there is any hardware change you have made then please also share that as well.
  • PN532 initialization retry loop with ESP32 restart

    #11 21769512
    Heweliusz03
    Level 5  
    Posts: 108
    Help: 1
    Rate: 6
    
    #include <Wire.h>
    #include <PN532_I2C.h>
    #include <PN532.h>
    #include <esp_system.h> // <-- do restartu ESP32
    
    #define SDA_PIN 8
    #define SCL_PIN 9
    #define RELAY_PIN_1 42
    
    TwoWire myWire(0);  // I2C bus 0
    PN532_I2C pn532i2c(myWire);
    PN532 nfc(pn532i2c);
    
    const int analogPin = 1;       // GPIO19 - wejście analogowe
    const int relayPin_2 = 41;     // GPIO41 - przekaźnik
    const int threshold = 3700;    // Próg wykrycia
    const int requiredTriggers = 10; // Ile razy trzeba przekroczyć próg
    
    int triggerCount = 0;
    bool relayActive = false;
    bool analogActive = false; // <- tylko po RFID
    
    // Lista znanych UID (w tablicy bajtów)
    const uint8_t validUIDs[][7] = {
      {0xC3, 0x0E, 0x70, 0x1A},
      {0x05, 0x1D, 0x28, 0x40},
      {0x79, 0x42, 0xF1, 0x97},
      {0xC5, 0x38, 0xFC, 0xA9},
      {0xF3, 0xCE, 0x7F, 0x34}
    };
    const size_t uidCount = sizeof(validUIDs) / sizeof(validUIDs[0]);
    
    void setup() {
      Serial.begin(115200);
      pinMode(RELAY_PIN_1, OUTPUT);
      digitalWrite(RELAY_PIN_1, LOW);
      pinMode(relayPin_2, OUTPUT);
      digitalWrite(relayPin_2, LOW);
      delay(2000);
    
      myWire.begin(SDA_PIN, SCL_PIN);
      myWire.setClock(400000); // szybkie I2C
    
      nfc.begin();
    
      bool initOK = false;
      for (int i = 0; i < 5; i++) {
        uint32_t versiondata = nfc.getFirmwareVersion();
        if (versiondata) {
          Serial.print("PN532 firmware: 0x");
          Serial.println(versiondata, HEX);
          initOK = true;
          break;
        }
        Serial.println("PN532 brak odpowiedzi – ponawiam...");
        delay(500);
      }
    
      if (!initOK) {
        Serial.println("Nie wykryto PN532 po 5 próbach. Restart ESP32...");
        delay(1000);
        ESP.restart();
      }
    
      nfc.SAMConfig();
    }
    
    void loop() {
      // RFID odczyt
      uint8_t uid[7];
      uint8_t uidLength;
    
      if (!analogActive && nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 30)) {
        Serial.print("Wykryto UID: ");
        for (uint8_t i = 0; i < uidLength; i++) {
          Serial.print(uid[i], HEX);
          Serial.print(" ");
        }
        Serial.println();
    
        bool match = false;
        for (size_t i = 0; i < uidCount; i++) {
          if (uidLength == 4 || uidLength == 7) {
            bool equal = true;
            for (uint8_t j = 0; j < uidLength; j++) {
              if (uid[j] != validUIDs[i][j]) {
                equal = false;
                break;
              }
            }
            if (equal) {
              match = true;
              break;
            }
          }
        }
    
        if (match) {
          Serial.println("✅ Dozwolony tag – włączam przekaźnik i aktywuję odczyt analogowy.");
          digitalWrite(RELAY_PIN_1, HIGH);
          delay(5000);
          analogActive = true; // <- aktywacja analogu
        } else {
          Serial.println("Nieznany tag – brak akcji.");
        }
    
        delay(1500); // opóźnienie po karcie
      }
    
      // Odczyt analogowy tylko po RFID
      if (analogActive && !relayActive) {
        int sensorValue = analogRead(analogPin);
        Serial.print("Analog: ");
        Serial.println(sensorValue);
    
        if (sensorValue < threshold) {
          triggerCount++;
          Serial.print("Detekcja: ");
          Serial.println(triggerCount);
    
          if (triggerCount >= requiredTriggers) {
            for (int i = 0; i < 4; i++) {
              digitalWrite(relayPin_2, HIGH);
              delay(500);
              digitalWrite(relayPin_2, LOW);
              delay(500);
            }
            digitalWrite(relayPin_2, HIGH);
            relayActive = true;
          }
        } else {
          if (triggerCount > 0) {
            Serial.println("Reset licznika");
          }
          triggerCount = 0;
        }
      }
    }
    

    Hardwearing I didn't change anything, I only set up communication over I2C

Topic summary

LABEL_AI_GENERATED
The discussion concerns a PN532 RFID/NFC reader that worked with an Arduino Nano but fails to read tags reliably when connected to an ESP32-S3-WROOM-1. The reader is detected on the I2C bus, but tag reading does not work in either I2C or SPI mode. Suggested troubleshooting focused on power supply level and I2C pull-up resistors: the module was tested at both 5 V and 3.3 V, then external pull-ups were recommended because the board appeared to have no obvious onboard SDA/SCL resistors. Adding 2.35 kΩ pull-ups caused the scanner to stop detecting the device. Later, a working Arduino example using PN532_I2C with a custom TwoWire bus on ESP32 was shared, but the connection was described as unstable and capricious, with the practical workaround being to use the Arduino instead of the ESP32 when PN532 communication is required.
AI summary based on the discussion. May contain errors.
ADVERTISEMENT