简体   繁体   中英

PN532 - Communicate with Mifare tag and NFC phone in the same sketch

I'm trying to use the PN532 with mifare tags and an android app in the same sketch. But the problem seems to be that the android phone is detected by the mifare module as well as by the NFC module. So it happens in about half of the cases that it tries to communicate with the phone as if it was a mifare tag. This alone wouldn't be a problem but the phone isn't detected anymore after all of that.

As a small demonstration, if I place a tag a few times and remove it after some time I get an output like this:

[5150] Mifare Placed
[7301] Mifare Removed
[10545] Mifare Placed
[11626] Mifare Removed

But if I place and remove my phone, the output looks like this:

[1821] Mobile Placed
[2951] Mobile Removed
[3615] Mifare Placed
[3692] Mifare Removed

As you can see, the second time I tried to let it communicate with the phone, the mifare module recognizes it and a wrong message is shown.

Here is my code:

#include <Adafruit_PN532.h>


#define PN532_IRQ   (2)
#define PN532_RESET (3)

Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);


static uint8_t lastType = 255;

#include "mifareclassic.h"
MifareClassic* mifare;
#include "nfc.h"
NFC* mobile;


void setup() {  
  Serial.begin(115200);

  nfc.begin();

  uint32_t versiondata;
  versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.println("Error!");
  }

  nfc.setPassiveActivationRetries(3); //else, it will endlessly try to retrieve the tag
  nfc.SAMConfig(); //read tags
}


void loop() {
  if(lastType==255){
    //MIFARE PLACED?
    if(mifare->isPlaced()){
      lastType = 0;
      Serial.println("["+String(millis())+"] Mifare Placed");
    }
    //NFC PLACED?
    else if(mobile->isPlaced()){
      lastType = 1;
      Serial.println("["+String(millis())+"] Mobile Placed");
    }
  } else {
    //MIFARE REMOVED?
    if(lastType==0){
      if(!mifare->isPlaced()){
        Serial.println("["+String(millis())+"] Mifare Removed");
        lastType = 255;
      }
    }
    //NFC REMOVED?
    else if(lastType==1){
      if(!mobile->isPlaced()){
        Serial.println("["+String(millis())+"] Mobile Removed");
        lastType = 255;
      }
    }
  }  
}

main.ino

#define block 4

class MifareClassic {
  public:
    MifareClassic(){}
    bool isPlaced();
};

bool MifareClassic::isPlaced(){
  uint8_t len;
  uint8_t uid[8] = {0};
  if(nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &len)){
    return true;
  } else {
    return false;
  }
}

mifareclassic.h

#define block 4

class NFC {
  public:
    NFC(){}
    bool isPlaced();
};

bool NFC::isPlaced(){
  if(lastType == 255){
    if(nfc.inListPassiveTarget()) {
      //nfc.inListPassiveTarget();
      //authentificate via AID
      uint8_t selectApdu[] = { 0x00, /* CLA */
                                0xA4, /* INS */
                                0x04, /* P1  */
                                0x00, /* P2  */
                                0x07, /* Length of AID  */
                                0xF0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, /* AID defined on Android App */
                                0x00  /* Le  */ };
      uint8_t uid[8];
      uint8_t len;

      if(nfc.inDataExchange(selectApdu, sizeof(selectApdu), uid, &len)) {
        return true;
      }
    }
  } else {
    uint8_t apdu[] = {0};
    uint8_t back[32];
    uint8_t len; 

    if(nfc.inDataExchange(apdu, sizeof(apdu), back, &len)) {
      return true;
    }
  }

  return false;
}

nfc.h

After a lot of expermienting I found a solution: I'm just using the inListPassiveTarget() function to find out if anything was placed at all. If that's the case, I check for a placed mobile phone by authenticating AID via inDataExchange() and do only check for mifareclassic via readPassiveTargetID() if that didn't work.

In case anybody faces the same problem sometime in the future, here's my (now working) code:

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_PN532.h>



#define PN532_IRQ   (2)
#define PN532_RESET (3)

Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);


enum { NONE, MIFARECLASSIC, MOBILE };
int lastType = NONE;

#include "mifareclassic.h"
#include "mobile.h"


void setup() {  
  Serial.begin(115200);

  nfc.begin();

  uint32_t versiondata;
  versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.println("Error!");
  }

  nfc.setPassiveActivationRetries(3); //else, it will endlessly try to retrieve the tag
  nfc.SAMConfig(); //read tags
}


void loop() {

  if(lastType==NONE){
    if(nfc.inListPassiveTarget()){
      //MOBILE PLACED?
      if(Mobile::isNewTagPut()){
        lastType = MOBILE;
        Serial.println("["+String(millis())+"] Mobile Placed");
      } 
      //MIFARECLASSIC PLACED?
      else if(MifareClassic::isNewTagPut()){
        lastType = MIFARECLASSIC;
        Serial.println("["+String(millis())+"] Mifare Placed");
      }
    }
  } else {
    //MOBILE REMOVED?
    if(lastType==MOBILE){
      if(!Mobile::isTagStillPlaced()){
        Serial.println("["+String(millis())+"] Mobile Removed");
        lastType = NONE;
      }
    }
    //MIFARECLASSIC REMOVED?
    else if(lastType==MIFARECLASSIC){
      if(!MifareClassic::isTagStillPlaced()){
        Serial.println("["+String(millis())+"] Mifare Removed");
        lastType = NONE;
      }
    }
  }
}

main.ino

#define block 4

class MifareClassic {
  public:
    static bool isNewTagPut();
    static bool isTagStillPlaced();
};

bool MifareClassic::isNewTagPut(){
  return isTagStillPlaced();
}

bool MifareClassic::isTagStillPlaced(){
  uint8_t len;
  uint8_t uid[8] = {0};
  return nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &len);
}

mifareclassic.h

class Mobile {
  public:
    static bool isNewTagPut();
    static bool isTagStillPlaced();
};

bool Mobile::isNewTagPut(){  
  //authentificate via AID
  uint8_t selectApdu[] = { 0x00, /* CLA */
                            0xA4, /* INS */
                            0x04, /* P1  */
                            0x00, /* P2  */
                            0x07, /* Length of AID  */
                            0xF0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, /* AID defined on Android App */
                            0x00  /* Le  */ };
  uint8_t uid[8];
  uint8_t len;

  return nfc.inDataExchange(selectApdu, sizeof(selectApdu), uid, &len);
}

bool Mobile::isTagStillPlaced(){
  uint8_t apdu[] = {0};
  uint8_t back[32];
  uint8_t len; 

  return nfc.inDataExchange(apdu, sizeof(apdu), back, &len);
}

mobile.h

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM