logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

ESP32-S3-WROOM-1 z PN532: brak odczytu tagów NFC w trybie I2C i SPI. Co robić?

Heweliusz03 14 Lut 2025 15:28 1848 10
REKLAMA
  • #1 21439390
    Heweliusz03
    Poziom 5  
    Posty: 108
    Pomógł: 1
    Ocena: 6
    Witam,
    mam czytnik RFID PN532
    Czytnik RFID PN532 na czerwonej płytce PCB
    Korzystałem już wcześniej z niego, łącząc go z Arduino Nano. Teraz przerzuciłem się na ESP32, a dokładnie ESP32-S3-WROOM-1 i pojawia się problem. W trybie I2C skaner wykrywa czytnik, ale w żaden sposób nie jestem w stanie odczytać żadnego tagu. Przykładowy program na 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
    }
    

    Po przełączeniu się na SPI, zero komunikacji, przykładowy 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
    }
    

    Ale co ciekawe pozostawiając dokładnie te same piny i zmieniając czytnik na RC522 wszystko działa bez problemu, kod dla 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));
    }
    

    Znalazłem kilka wątków na Reddicie na ten temat, ale nic z tych rozwiązań nie pomogło.
  • REKLAMA
  • #2 21442458
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #3 21442580
    Heweliusz03
    Poziom 5  
    Posty: 108
    Pomógł: 1
    Ocena: 6
    Sprawdzałem i na 5V i na 3,3V
  • REKLAMA
  • #4 21442713
    Konto nie istnieje
    Poziom 1  
  • #5 21444176
    Heweliusz03
    Poziom 5  
    Posty: 108
    Pomógł: 1
    Ocena: 6
    Tutaj prosto zidentyfikować te rezystory:
    Moduł elektroniczny z czerwonym laminatem, na którym znajdują się układy scalone i złącza, oznaczone m.in. jako GND, VCC, SDA, SCL.
    Jednak na mojej płytce już nie jest tak kolorowo i wydaje mi się, że scl i sda idą prosto na układ:
    Czerwona płytka drukowana z różnymi komponentami elektronicznymi, w tym rezystorami i układem scalonym.
  • #6 21444281
    Konto nie istnieje
    Poziom 1  
  • #7 21453309
    Heweliusz03
    Poziom 5  
    Posty: 108
    Pomógł: 1
    Ocena: 6
    Dołożenie rezystorów podciągających 2,35k, niestety spowodowało tylko, że na scanerze przestało wykrywa cokolwiek. Chciałbym się skomunikować z tym czytnikiem w jakikolwiek sposób
  • #8 21768069
    princekakkad10
    Poziom 2  
    Posty: 2
    Czy znalazłeś jakieś rozwiązanie tego problemu? Jeśli tak, to czy mógłbyś się nim z nami podzielić...

    Dodano po 8 [minutach]:

    @Heweliusz03, czy mógłbyś podzielić się kodem, którego używałeś z Arduino, który działał dla Ciebie i czy mógłbyś podzielić się również trybem, którego użyłeś...
  • REKLAMA
  • #9 21768393
    Heweliusz03
    Poziom 5  
    Posty: 108
    Pomógł: 1
    Ocena: 6
    Jednoznacznego rozwiązania nie znalazłem. Po kilku próbach udało mi się skomunikować, ale to połączenie bywa bardzo kapryśne. Tak gdzie układ wymaga stosowanie przeze mnie PN532, zazwyczaj łączę go po prostu z Arduino
  • #10 21768686
    princekakkad10
    Poziom 2  
    Posty: 2
    >>21453309 Czy mógłbyś udostępnić jakiś przykładowy kod, który działa dla Ciebie w Arduino, jakikolwiek prosty przykładowy kod, abym mógł zorientować się, jak jest tworzony, a także jeśli jest jakaś zmiana sprzętowa, którą wprowadziłeś, to również ją udostępnij?
  • #11 21769512
    Heweliusz03
    Poziom 5  
    Posty: 108
    Pomógł: 1
    Ocena: 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;
        }
      }
    }
    

    Hardwearowo nic nie zmieniałem, ustawiłem tylko komunikację po I2C

Podsumowanie tematu

✨ Problem dotyczy braku odczytu tagów NFC przez moduł PN532 podłączony do mikrokontrolera ESP32-S3-WROOM-1 w trybach I2C i SPI. W trybie I2C czytnik jest wykrywany, lecz nie odczytuje tagów. Zasilanie było testowane zarówno 5V, jak i 3,3V. Sugerowano dodanie zewnętrznych rezystorów podciągających do linii SDA i SCL, ponieważ na niektórych wersjach modułu PN532 rezystory te mogą być niewystarczające lub ich brak. Próba dołożenia rezystorów 2,35 kΩ spowodowała całkowitą utratę wykrywania czytnika. Komunikacja z PN532 na ESP32-S3 jest możliwa, ale niestabilna i kapryśna. W praktyce dla stabilnej pracy często rekomendowane jest użycie Arduino zamiast ESP32-S3 do obsługi PN532. Brak jednoznacznego rozwiązania problemu w dyskusji.
Wygenerowane przez model językowy.
REKLAMA