1
votes

I am using an Arduino UNO with a low power blue tooth, and a PN532 RFID/NFC Shield.

I was having a problem where the loop in my sketch was not looping unless there was at least one card detected, and fixed that by modifying the library for the RFID shield readPassiveTargetID() function to be non blocking (changed a while loop to an if statement so it didn't get stuck).

Now the problem is that it doesn't seem able to read the tag id of any tags unless two are present.

My Sketch

#include <SPI.h>
#include "Adafruit_BLE_UART.h"
#include <Wire.h>
#include <Adafruit_NFCShield_I2C.h>

#define IRQ   (7)
#define IRQ2   (4)
#define RESET (3)  // Not connected by default on the NFC Shield

Adafruit_NFCShield_I2C nfc(IRQ, RESET);
//Adafruit_NFCShield_I2C nfc2(IRQ2, RESET);

// Connect CLK/MISO/MOSI to hardware SPI
// e.g. On UNO & compatible: CLK = 13, MISO = 12, MOSI = 11
#define ADAFRUITBLE_REQ 10
#define ADAFRUITBLE_RDY 3     // This should be an interrupt pin, on Uno thats #2 or #3
#define ADAFRUITBLE_RST 9

Adafruit_BLE_UART BTLEserial = Adafruit_BLE_UART(ADAFRUITBLE_REQ, ADAFRUITBLE_RDY, ADAFRUITBLE_RST);


uint8_t numChecks = 0;

String items[]= {"","","","","","","",""};

String lastList="";

/**************************************************************************/
/*!
 Configure the Arduino and start advertising with the radio
 */
/**************************************************************************/
void setup(void)
{ 

  Serial.begin(115200);


  //while(!Serial);
  startNFC();
  BTLEserial.begin();

  //startNFC(); 


  //while(!Serial); // Leonardo/Micro should wait for serial init



}

/**************************************************************************/
/*!
 Constantly checks for new events on the nRF8001
 */
/**************************************************************************/
aci_evt_opcode_t laststatus = ACI_EVT_DISCONNECTED;

void loop()
{
  //Serial.println("--------------------Loop begin-------------------");

  // Tell the nRF8001 to do whatever it should be working on.
  BTLEserial.pollACI();

  // Ask what is our current status
  aci_evt_opcode_t status = BTLEserial.getState();
  // If the status changed....
  if (status != laststatus) {
    // print it out!
    if (status == ACI_EVT_DEVICE_STARTED) {
      Serial.println(F("* Advertising started"));
    }
    if (status == ACI_EVT_CONNECTED) {
      Serial.println(F("* Connected!"));
      BTLEserial.print("Goodmorning");
    }
    if (status == ACI_EVT_DISCONNECTED) {
      Serial.println(F("* Disconnected or advertising timed out"));
    }
    // OK set the last status change to this one
    laststatus = status;
  }

  if(status == ACI_EVT_CONNECTED){
    if(numChecks<7){
      numChecks++;
    }
    else{
      updatePhone();
      numChecks =0;
    }


    uint8_t success;
    uint8_t uid[] = {0, 0, 0, 0, 0, 0, 0};  // Buffer to store the returned UID
    uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)

    Serial.println("CHECK #");Serial.print(numChecks,DEC);
    // Wait for an ISO14443A type cards (Mifare, etc.).  When one is found
    // 'uid' will be populated with the UID, and uidLength will indicate
    // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
    success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);

    items[numChecks] ="";
    Serial.println("----------SCANNING------");
    if (success) {
      Serial.println("Found one!");
      // Display some basic information about the card
      // Serial.println("Found an ISO14443A card");
      // Serial.print("  UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
      // Serial.print("  UID Value: ");
      String uidChar ="";

      for ( int i = 0; i < 7; i++ ) {
        uidChar += "x";
        uidChar +=  uid[i];

       }
       Serial.println("ID:"+uidChar);
      //Serial.println(uidChar);
      if(!itemAlreadyExists(uidChar)){
        Serial.println("Its New");

        items[numChecks] = uidChar;
      }

    }
    else{
      Serial.println("No Card found");
    }


 }

}

// Serial.println("************************Loop END*********************");


boolean itemAlreadyExists(String id){
  boolean result = false;
  for(int i=0; i<7; i++){
    String s = items[i];
    if(id.equals(s)){
      result = true;
    }
  }

  return result;
}



void startNFC(){
  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    //while (1); // halt
  }
  else{
    Serial.print("FOUND PN53x board");
  }

  nfc.SAMConfig(); 
}

void updatePhone(){

  String itemsList ="";


  for(int i = 0; i<8;i++){
    String s = items[i];
    Serial.println("handling::"+s);

    if(!s.equals("")){
      Serial.println("NOT EMPTY");

      if(itemsList.length()>0){
        itemsList +=",";
      };

      itemsList += s;


    }
    else{
      Serial.println("STRING EMPTY");

    }
  }



  if(itemsList.length()>0){
    Serial.println(itemsList); 

  }
  else{
    Serial.println("EMPTY");
  }

  numChecks = 0;
     items[0]="";
      items[1]="";
      items[2]="";
      items[3]="";
      items[4]="";
      items[5]="";
      items[6]="";
      items[7]="";
    delay(5000);

}

My Serial Output with NO Cards:

FOUND PN53x board* Advertising started
* Connected!
    Writing out to BTLE: 0x47 0x6F 0x6F 0x64 0x6D 0x6F 0x72 0x6E 0x69 0x6E 0x67
CHECK #
1----------SCANNING------
No Card found
CHECK #
2----------SCANNING------
No Card found
CHECK #
3----------SCANNING------
No Card found
CHECK #
4----------SCANNING------
No Card found
CHECK #
5----------SCANNING------
No Card found
CHECK #
6----------SCANNING------
No Card found
CHECK #
7----------SCANNING------
No Card found
handling::
STRING EMPTY
handling::
STRING EMPTY
handling::
STRING EMPTY
handling::
STRING EMPTY
handling::
STRING EMPTY
handling::
STRING EMPTY
handling::
STRING EMPTY
handling::
STRING EMPTY
EMPTY

With ONE Card

CHECK #
0----------SCANNING------
No Card found
CHECK #
1----------SCANNING------
No Card found
CHECK #
2----------SCANNING------
No Card found
CHECK #
3----------SCANNING------
No Card found
CHECK #
4----------SCANNING------
No Card found
CHECK #
5----------SCANNING------
No Card found
CHECK #
6----------SCANNING------
No Card found
CHECK #
7----------SCANNING------
No Card found
handling::
STRING EMPTY
handling::
STRING EMPTY
handling::
STRING EMPTY
handling::
STRING EMPTY
handling::
STRING EMPTY
handling::
STRING EMPTY
handling::
STRING EMPTY
handling::
STRING EMPTY
EMPTY

With Two Cards

CHECK #
2----------SCANNING------
Found one!
ID:x19x153x28x212x0x0x0
Its New
CHECK #
3----------SCANNING------
Found one!
ID:x19x52x39x212x0x0x0
Its New
CHECK #
4----------SCANNING------
Found one!
ID:x19x153x28x212x0x0x0
CHECK #
5----------SCANNING------
Found one!
ID:x19x52x39x212x0x0x0
CHECK #
6----------SCANNING------
Found one!
ID:x19x153x28x212x0x0x0
CHECK #
7----------SCANNING------
Found one!
ID:x19x52x39x212x0x0x0
handling::
STRING EMPTY
handling::
STRING EMPTY
handling::x19x153x28x212x0x0x0
NOT EMPTY
handling::x19x52x39x212x0x0x0
NOT EMPTY
handling::
STRING EMPTY
handling::
STRING EMPTY
handling::
STRING EMPTY
handling::
STRING EMPTY
x19x153x28x212x0x0x0,x19x52x39x212x0x0x0

That all said if i leave the two cards there they eventually go away??

Any ideas whats wrong?

1

1 Answers

1
votes

I use the Seeed-Studio PN532 drivers with my Adafruit NFC shields.

The Seeed-Studio version won't block and you can optionally set a timeout.

My NDEF library has higher level abstraction of a Tag object which you might find useful for reading NFC tags. Simple example. Extended Example.

if (nfc.tagPresent()){
  NfcTag tag = nfc.read();
  Serial.println(tag.getTagType());
  Serial.print("UID: ");Serial.println(tag.getUidString());
}