pn532 rfid/nfc shield

Adafruit Ethernet, Motor, Proto, Wave, Datalogger, GPS Shields - etc!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
ewokkillah
 
Posts: 9
Joined: Fri Nov 16, 2012 2:32 am

pn532 rfid/nfc shield

Post by ewokkillah »

hi there,
Im wanting to use an RFID tag to activate a servo. I have the PN532 stacked on an arduino uno and Im looking for some eample sketches to work from. If anyone has any suggestions on where to start i would appreciate it.
Thanks

User avatar
adafruit_support_bill
 
Posts: 88087
Joined: Sat Feb 07, 2009 10:11 am

Re: pn532 rfid/nfc shield

Post by adafruit_support_bill »

Code: Select all


#include <Wire.h>
#include <Adafruit_NFCShield_I2C.h>
#include <Servo.h> 
 
Servo myservo;  // create servo object to control a servo 
                // a maximum of eight servo objects can be created 
 
int pos = 0;    // variable to store the servo position 
 
#define IRQ   (2)
#define RESET (3)  // Not connected by default on the NFC Shield

Adafruit_NFCShield_I2C nfc(IRQ, RESET);

void setup(void) {
  Serial.begin(9600);
  Serial.println("Hello!");
 myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
 myservo.write(0);
  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    while (1); // halt
  }
  // Got ok data, print it out!
  Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX); 
  Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC); 
  Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
  
  // configure board to read RFID tags
  nfc.SAMConfig();
  
  Serial.println("Waiting for an ISO14443A Card ...");
}


void loop(void) 
{
  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)
    
  // 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)
    Serial.print(".");
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 10);
  
  if (success) 
  {
    // 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: ");
    nfc.PrintHex(uid, uidLength);
    Serial.println("");
    
    if (uidLength == 4)
    {
      // We probably have a Mifare Classic card ... 
      Serial.println("Seems to be a Mifare Classic card (4 byte UID)");
	  
      // Now we need to try to authenticate it for read/write access
      // Try with the factory default KeyA: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
      Serial.println("Trying to authenticate block 4 with default KEYA value");
      uint8_t keya[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
	  
	  // Start with block 4 (the first block of sector 1) since sector 0
	  // contains the manufacturer data and it's probably better just
	  // to leave it alone unless you know what you're doing
      success = nfc.mifareclassic_AuthenticateBlock(uid, uidLength, 4, 0, keya);
    }  
    digitalWrite(11,HIGH);
    //------------------------------------------------------------------------ opens door
    for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees 
    {                                  // in steps of 1 degree 
      myservo.write(pos);              // tell servo to go to position in variable 'pos' 
      delay(15);                       // waits 15ms for the servo to reach the position 
    } 
    //------------
    delay(3000);                        // wait 3 seconds
    //------------
    for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees 
    {                                
      myservo.write(pos);              // tell servo to go to position in variable 'pos' 
      delay(15);                       // waits 15ms for the servo to reach the position 
    } 
    digitalWrite(11,LOW);
  }
  else
  {
      Serial.println("No Card Detected");
  }
}

ewokkillah
 
Posts: 9
Joined: Fri Nov 16, 2012 2:32 am

Re: pn532 rfid/nfc shield

Post by ewokkillah »

Thanks for your reply.
I don't if I'm doing something wrong, but when i try to upload your sketch I get this error on line

Code: Select all

sucess = nfc.readPassiveTargetID(PN532_MIFARE_IOS14443A, uid, &uidLength, 10)
The error is: no match function for call 'Adafruit_I2C::readPasiveTargetID(int, uint8_t[7], unit8_t*,int)'

Thanks for you help

User avatar
adafruit_support_bill
 
Posts: 88087
Joined: Sat Feb 07, 2009 10:11 am

Re: pn532 rfid/nfc shield

Post by adafruit_support_bill »

Sorry, I was using a hacked version of the library.

Change:

Code: Select all

sucess = nfc.readPassiveTargetID(PN532_MIFARE_IOS14443A, uid, &uidLength, 10)
to:

Code: Select all

sucess = nfc.readPassiveTargetID(PN532_MIFARE_IOS14443A, uid, &uidLength)

ewokkillah
 
Posts: 9
Joined: Fri Nov 16, 2012 2:32 am

Re: pn532 rfid/nfc shield

Post by ewokkillah »

thanks that worked great. I was wondering if you could tell me how to authorize only cretin RFID cards. Also before the servo is set back to the "0" position if it could check if a RFID card is still present.
Thanks again for your help and hope you had a nice Thanksgiving. :D

User avatar
adafruit_support_bill
 
Posts: 88087
Joined: Sat Feb 07, 2009 10:11 am

Re: pn532 rfid/nfc shield

Post by adafruit_support_bill »

I was wondering if you could tell me how to authorize only cretin RFID cards.
Check the UID returned by readPassiveTargetID(). Each card has a unique UID.
Also before the servo is set back to the "0" position if it could check if a RFID card is still present.
This sketch does that:

Code: Select all


#include <Wire.h>
#include <Adafruit_NFCShield_I2C.h>
#include <Servo.h> 
 
Servo myservo;  // create servo object to control a servo 
                // a maximum of eight servo objects can be created 
 
int pos = 0;    // variable to store the servo position 
 
#define IRQ   (2)
#define RESET (3)  // Not connected by default on the NFC Shield

Adafruit_NFCShield_I2C nfc(IRQ, RESET);

boolean doorOpen;

void setup(void) {
  pinMode(11, OUTPUT);
  Serial.begin(9600);
  Serial.println("Hello!");
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
  myservo.write(180);
  delay(500);
  myservo.detach();
  doorOpen = false;
  
  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    while (1); // halt
  }
  // Got ok data, print it out!
  Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX); 
  Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC); 
  Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
  
  // configure board to read RFID tags
  nfc.SAMConfig();
  
  Serial.println("Waiting for an ISO14443A Card ...");
  
}


void loop(void) 
{
  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)
    
  // 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)
    Serial.print(".");
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 10);
  
  if (success) 
  {
    // 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: ");
    nfc.PrintHex(uid, uidLength);
    Serial.println("");
    
    if (uidLength == 4)
    {
      // We probably have a Mifare Classic card ... 
      Serial.println("Seems to be a Mifare Classic card (4 byte UID)");
	  
      // Now we need to try to authenticate it for read/write access
      // Try with the factory default KeyA: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
      Serial.println("Trying to authenticate block 4 with default KEYA value");
      uint8_t keya[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
	  
	  // Start with block 4 (the first block of sector 1) since sector 0
	  // contains the manufacturer data and it's probably better just
	  // to leave it alone unless you know what you're doing
      success = nfc.mifareclassic_AuthenticateBlock(uid, uidLength, 4, 0, keya);
    }  
    //------------------------------------------------------------------------ opens door
    OpenDoor();
  }
  else
  {
      Serial.println("No Card Detected");
      CloseDoor();
  }
}

void OpenDoor()
{
  if (doorOpen)
    return;
  else
  {
    digitalWrite(11,HIGH);
    myservo.attach(9);
    Serial.println("Open Door");

    for(pos = 180; pos>=0; pos-=1)     // goes from 180 degrees to 0 degrees 
    {                                
      myservo.write(pos);              // tell servo to go to position in variable 'pos' 
      delay(15);                       // waits 15ms for the servo to reach the position 
    } 
    doorOpen = true;
  }
}

void CloseDoor()
{
  if (!doorOpen)
    return;
  else
  {
    Serial.println("Close Door");
    
    for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees 
    {                                  // in steps of 1 degree 
      myservo.write(pos);              // tell servo to go to position in variable 'pos' 
      delay(15);                       // waits 15ms for the servo to reach the position 
    } 
    digitalWrite(11,LOW);
    doorOpen = false;
    myservo.detach();
  }
}
But it requires my hacked version of the library (files attached)
Attachments
Adafruit_NFCShield_I2C.h
(7.83 KiB) Downloaded 129 times
Adafruit_NFCShield_I2C.cpp
(33.13 KiB) Downloaded 99 times

User avatar
gordiegii
 
Posts: 137
Joined: Fri Jan 04, 2013 8:26 pm

Re: pn532 rfid/nfc shield

Post by gordiegii »

Wouldn't you need a list of authorized UIDs to compare the found tag against?

Gordie.

User avatar
adafruit_support_bill
 
Posts: 88087
Joined: Sat Feb 07, 2009 10:11 am

Re: pn532 rfid/nfc shield

Post by adafruit_support_bill »

Yes, you would need to know the authorized UIDs and check the detected one against the list.

javooooo
 
Posts: 13
Joined: Mon Mar 11, 2013 5:06 am

Re: pn532 rfid/nfc shield

Post by javooooo »

How would you modify the code to only allow certain tags to activate the servo?

User avatar
adafruit_support_bill
 
Posts: 88087
Joined: Sat Feb 07, 2009 10:11 am

Re: pn532 rfid/nfc shield

Post by adafruit_support_bill »

Define an array of valid tag UIDs and compare the UID reported by the card with the UIDs in the array. If no match, don't activate the servo.

javooooo
 
Posts: 13
Joined: Mon Mar 11, 2013 5:06 am

Re: pn532 rfid/nfc shield

Post by javooooo »

I'm new to Arduinos but I'll give it a shot. I don't suppose you could give me any more guidance?

I know it isn't part of your support requirements but I'd love some help. Cheers.

User avatar
adafruit_support_bill
 
Posts: 88087
Joined: Sat Feb 07, 2009 10:11 am

Re: pn532 rfid/nfc shield

Post by adafruit_support_bill »

Have you looked at the BabelFish project? That uses UIDs to trigger sounds for specific cards wen they are recognized. You might want to read through that to get an idea of how that works. Your project is not so much different. Instead of triggering sounds, you will trigger servo movement.

The code here is a good place to start: http://learn.adafruit.com/babel-fish/programming

You can skip all the initialization for the Wave Shield. And when you get to this part:

Code: Select all

  // repeat this for loop as many times as you have RFID cards
    if (cardidentifier == 2588581390) { // this is the card's unique identifier
      playcomplete("1.WAV"); // these are file names for the sample audio files - change them to your own file names
    }
  
    if (cardidentifier == 2146122274) {
      playcomplete("2.WAV");
    }
You will need to replace the UIDs in the "if" statements with the UIDs of your cards.
Then you can replace the "playcomplete" with your servo code.

javooooo
 
Posts: 13
Joined: Mon Mar 11, 2013 5:06 am

Re: pn532 rfid/nfc shield

Post by javooooo »

Thanks so much!

javooooo
 
Posts: 13
Joined: Mon Mar 11, 2013 5:06 am

Re: pn532 rfid/nfc shield

Post by javooooo »

Hi Bill,

How do I find my UID? I used the sample code provided in your package which scans mifare cards but it gave me a much longer result.

Also, how do I define the cardintentifier tag, it isn't elsewhere in my code.

Thanks.

User avatar
adafruit_support_bill
 
Posts: 88087
Joined: Sat Feb 07, 2009 10:11 am

Re: pn532 rfid/nfc shield

Post by adafruit_support_bill »

If you use the "readMifare" example, it prints the UID to the serial monitor.
The UID is the number that follows "UID Value: "

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino Shields from Adafruit”