pn532 rfid/nfc shield
Moderators: adafruit_support_bill, adafruit

pn532 rfid/nfc shield

by ewokkillah on Tue Nov 20, 2012 1:52 am

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
ewokkillah
 
Posts: 9
Joined: Fri Nov 16, 2012 2:32 am

Re: pn532 rfid/nfc shield

by adafruit_support_bill on Tue Nov 20, 2012 8:07 am

Code: Select all | TOGGLE FULL SIZE

#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");
  }
}
User avatar
adafruit_support_bill
 
Posts: 30887
Joined: Sat Feb 07, 2009 10:11 am

Re: pn532 rfid/nfc shield

by ewokkillah on Thu Nov 22, 2012 1:46 am

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 | TOGGLE FULL SIZE
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
ewokkillah
 
Posts: 9
Joined: Fri Nov 16, 2012 2:32 am

Re: pn532 rfid/nfc shield

by adafruit_support_bill on Thu Nov 22, 2012 7:34 am

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

Change:
Code: Select all | TOGGLE FULL SIZE
sucess = nfc.readPassiveTargetID(PN532_MIFARE_IOS14443A, uid, &uidLength, 10)

to:
Code: Select all | TOGGLE FULL SIZE
sucess = nfc.readPassiveTargetID(PN532_MIFARE_IOS14443A, uid, &uidLength)
User avatar
adafruit_support_bill
 
Posts: 30887
Joined: Sat Feb 07, 2009 10:11 am

Re: pn532 rfid/nfc shield

by ewokkillah on Sat Nov 24, 2012 1:58 am

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
ewokkillah
 
Posts: 9
Joined: Fri Nov 16, 2012 2:32 am

Re: pn532 rfid/nfc shield

by adafruit_support_bill on Sat Nov 24, 2012 7:44 am

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 | TOGGLE FULL SIZE

#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 46 times
Adafruit_NFCShield_I2C.cpp
(33.13 KiB) Downloaded 44 times
User avatar
adafruit_support_bill
 
Posts: 30887
Joined: Sat Feb 07, 2009 10:11 am

Re: pn532 rfid/nfc shield

by gordiegii on Sat Feb 02, 2013 1:05 am

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

Gordie.
Logic is the art of going wrong with confidence. -- Morris Kline
User avatar
gordiegii
 
Posts: 29
Joined: Fri Jan 04, 2013 8:26 pm
Location: Toronto, Canada

Re: pn532 rfid/nfc shield

by adafruit_support_bill on Sat Feb 02, 2013 8:08 am

Yes, you would need to know the authorized UIDs and check the detected one against the list.
User avatar
adafruit_support_bill
 
Posts: 30887
Joined: Sat Feb 07, 2009 10:11 am

Re: pn532 rfid/nfc shield

by javooooo on Sat Apr 06, 2013 1:23 am

How would you modify the code to only allow certain tags to activate the servo?
javooooo
 
Posts: 13
Joined: Mon Mar 11, 2013 5:06 am

Re: pn532 rfid/nfc shield

by adafruit_support_bill on Sat Apr 06, 2013 6:49 am

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.
User avatar
adafruit_support_bill
 
Posts: 30887
Joined: Sat Feb 07, 2009 10:11 am

Re: pn532 rfid/nfc shield

by javooooo on Tue Apr 09, 2013 7:36 am

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.
javooooo
 
Posts: 13
Joined: Mon Mar 11, 2013 5:06 am

Re: pn532 rfid/nfc shield

by adafruit_support_bill on Tue Apr 09, 2013 8:42 am

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 | TOGGLE FULL SIZE
  // 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.
User avatar
adafruit_support_bill
 
Posts: 30887
Joined: Sat Feb 07, 2009 10:11 am

Re: pn532 rfid/nfc shield

by javooooo on Tue Apr 09, 2013 5:23 pm

Thanks so much!
javooooo
 
Posts: 13
Joined: Mon Mar 11, 2013 5:06 am

Re: pn532 rfid/nfc shield

by javooooo on Sun Apr 14, 2013 11:27 pm

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.
javooooo
 
Posts: 13
Joined: Mon Mar 11, 2013 5:06 am

Re: pn532 rfid/nfc shield

by adafruit_support_bill on Mon Apr 15, 2013 7:59 am

If you use the "readMifare" example, it prints the UID to the serial monitor.
The UID is the number that follows "UID Value: "
User avatar
adafruit_support_bill
 
Posts: 30887
Joined: Sat Feb 07, 2009 10:11 am