簡體   English   中英

PN532-在同一草圖中與Mifare標簽和NFC電話通信

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

我試圖在同一草圖中將PN532與mifare標簽和一個android應用程序一起使用。 但是問題似乎是mifare模塊以及NFC模塊都檢測到了android手機。 因此,在大約一半的情況下,它會嘗試與手機進行通信,就好像它是mifare標簽一樣。 僅此一項就不成問題,但畢竟所有這些都不再能檢測到電話。

作為一個小示例,如果我放置一個標簽幾次並在一段時間后將其刪除,則會得到以下輸出:

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

但是,如果我放下手機,輸出將如下所示:

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

如您所見,我第二次嘗試使其與手機通信時,mifare模塊會識別出該錯誤,並顯示一條錯誤消息。

這是我的代碼:

#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

經過大量的實驗之后,我找到了一個解決方案:我只是使用inListPassiveTarget()函數來查找是否放置了任何東西。 在這種情況下,我通過inDataExchange() AID進行身份驗證來檢查放置的手機,如果inDataExchange() ,則僅通過readPassiveTargetID()檢查mifareclassic。

萬一將來有人遇到相同的問題,這是我的代碼(正在工作):

#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);
}

手機

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM