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
pn532 rfid/nfc shield
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- adafruit_support_bill
- Posts: 88154
- Joined: Sat Feb 07, 2009 10:11 am
Re: pn532 rfid/nfc shield
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");
}
}
-
- Posts: 9
- Joined: Fri Nov 16, 2012 2:32 am
Re: pn532 rfid/nfc shield
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
The error is: no match function for call 'Adafruit_I2C::readPasiveTargetID(int, uint8_t[7], unit8_t*,int)'
Thanks for you help
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)
Thanks for you help
- adafruit_support_bill
- Posts: 88154
- Joined: Sat Feb 07, 2009 10:11 am
Re: pn532 rfid/nfc shield
Sorry, I was using a hacked version of the library.
Change:
to:
Change:
Code: Select all
sucess = nfc.readPassiveTargetID(PN532_MIFARE_IOS14443A, uid, &uidLength, 10)
Code: Select all
sucess = nfc.readPassiveTargetID(PN532_MIFARE_IOS14443A, uid, &uidLength)
-
- Posts: 9
- Joined: Fri Nov 16, 2012 2:32 am
Re: pn532 rfid/nfc shield
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.
Thanks again for your help and hope you had a nice Thanksgiving.
- adafruit_support_bill
- Posts: 88154
- Joined: Sat Feb 07, 2009 10:11 am
Re: pn532 rfid/nfc shield
Check the UID returned by readPassiveTargetID(). Each card has a unique UID.I was wondering if you could tell me how to authorize only cretin RFID cards.
This sketch does that:Also before the servo is set back to the "0" position if it could check if a RFID card is still present.
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();
}
}
- Attachments
-
- Adafruit_NFCShield_I2C.h
- (7.83 KiB) Downloaded 135 times
-
- Adafruit_NFCShield_I2C.cpp
- (33.13 KiB) Downloaded 108 times
- gordiegii
- Posts: 137
- Joined: Fri Jan 04, 2013 8:26 pm
Re: pn532 rfid/nfc shield
Wouldn't you need a list of authorized UIDs to compare the found tag against?
Gordie.
Gordie.
- adafruit_support_bill
- Posts: 88154
- Joined: Sat Feb 07, 2009 10:11 am
Re: pn532 rfid/nfc shield
Yes, you would need to know the authorized UIDs and check the detected one against the list.
-
- Posts: 13
- Joined: Mon Mar 11, 2013 5:06 am
Re: pn532 rfid/nfc shield
How would you modify the code to only allow certain tags to activate the servo?
- adafruit_support_bill
- Posts: 88154
- Joined: Sat Feb 07, 2009 10:11 am
Re: pn532 rfid/nfc shield
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.
-
- Posts: 13
- Joined: Mon Mar 11, 2013 5:06 am
Re: pn532 rfid/nfc shield
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.
I know it isn't part of your support requirements but I'd love some help. Cheers.
- adafruit_support_bill
- Posts: 88154
- Joined: Sat Feb 07, 2009 10:11 am
Re: pn532 rfid/nfc shield
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:
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.
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");
}
Then you can replace the "playcomplete" with your servo code.
-
- Posts: 13
- Joined: Mon Mar 11, 2013 5:06 am
Re: pn532 rfid/nfc shield
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.
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.
- adafruit_support_bill
- Posts: 88154
- Joined: Sat Feb 07, 2009 10:11 am
Re: pn532 rfid/nfc shield
If you use the "readMifare" example, it prints the UID to the serial monitor.
The UID is the number that follows "UID Value: "
The UID is the number that follows "UID Value: "
Please be positive and constructive with your questions and comments.