简体   繁体   English

PN532-在同一草图中与Mifare标签和NFC电话通信

[英]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. 我试图在同一草图中将PN532与mifare标签和一个android应用程序一起使用。 But the problem seems to be that the android phone is detected by the mifare module as well as by the NFC module. 但是问题似乎是mifare模块以及NFC模块都检测到了android手机。 So it happens in about half of the cases that it tries to communicate with the phone as if it was a mifare tag. 因此,在大约一半的情况下,它会尝试与手机进行通信,就好像它是mifare标签一样。 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. 如您所见,我第二次尝试使其与手机通信时,mifare模块会识别出该错误,并显示一条错误消息。

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 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 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 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. 经过大量的实验之后,我找到了一个解决方案:我只是使用inListPassiveTarget()函数来查找是否放置了任何东西。 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. 在这种情况下,我通过inDataExchange() AID进行身份验证来检查放置的手机,如果inDataExchange() ,则仅通过readPassiveTargetID()检查mifareclassic。

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 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 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 手机

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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