NFC (Near Field Communication) is a technology that is widely used. Some of NFC's applications include wireless access control systems (e.g. keyless doors, and locks), and mobile device payments (e.g. store registers that receive payment information via a phone application).
The NFC Shield features a transceiver module, PN532, which handles wireless communication at 13.56MHz, this means that you can read and write a 13.56MHz tag with this shield or implement point to point (P2P) data exchange between the shield and a smart phone.
For this new version of the shield we have created a separate, independent, PCB antenna area which allows you to more easily stretch the NFC interface outside of your main circuit enclosure.
Buy it from Bazaar: SLD01097P
The NFC shield's pins and other terminals are described below.
The NFC shield's antenna, included with the shield, is a separate PCB module that is attached to the shield via a cable. The antenna is the area used to receive and transmit information.
This example will show you how to use the NFC shield to scan an NFC tag and display its information/data.
#include <SPI.h> #include "PN532_SPI.h" #include "PN532.h" #include "NfcAdapter.h" PN532_SPI interface(SPI, 10); // create a PN532 SPI interface with the SPI CS terminal located at digital pin 10 NfcAdapter nfc = NfcAdapter(interface); // create an NFC adapter object void setup(void) { Serial.begin(115200); // begin serial communication Serial.println("NDEF Reader"); nfc.begin(); // begin NFC communication } void loop(void) { Serial.println("\nScan an NFC tag\n"); if (nfc.tagPresent()) // Do an NFC scan to see if an NFC tag is present { NfcTag tag = nfc.read(); // read the NFC tag into an object, nfc.read() returns an NfcTag object. tag.print(); // prints the NFC tags type, UID, and NDEF message (if available) } delay(500); // wait half a second (500ms) before scanning again (you may increment or decrement the wait time) }
To test the code:
This example will show you how to use an NFC tag as a key to unlock a door or a lock. The door/lock mechanism will be left to your imagination, we'll only cover the NFC part of the code.
#include <SPI.h> #include "PN532_SPI.h" #include "PN532.h" #include "NfcAdapter.h" String const myUID = "1B B3 C6 EF"; // replace this UID with your NFC tag's UID int const greenLedPin = 3; // green led used for correct key notification int const redLedPin = 4; // red led used for incorrect key notification PN532_SPI interface(SPI, 10); // create a SPI interface for the shield with the SPI CS terminal at digital pin 10 NfcAdapter nfc = NfcAdapter(interface); // create an NFC adapter object void setup(void) { Serial.begin(115200); // start serial comm Serial.println("NDEF Reader"); nfc.begin(); // begin NFC comm // make LED pins outputs pinMode(greenLedPin,OUTPUT); pinMode(redLedPin,OUTPUT); // turn off the LEDs digitalWrite(greenLedPin,LOW); digitalWrite(redLedPin,LOW); } void loop(void) { Serial.println("Scanning..."); if (nfc.tagPresent()) // check if an NFC tag is present on the antenna area { NfcTag tag = nfc.read(); // read the NFC tag String scannedUID = tag.getUidString(); // get the NFC tag's UID if( myUID.compareTo(scannedUID) == 0) // compare the NFC tag's UID with the correct tag's UID (a match exists when compareTo returns 0) { // The correct NFC tag was used Serial.println("Correct Key"); // Blink the green LED and make sure the RED led is off digitalWrite(greenLedPin,HIGH); digitalWrite(redLedPin,LOW); delay(500); digitalWrite(greenLedPin,LOW); delay(500); digitalWrite(greenLedPin,HIGH); delay(500); digitalWrite(greenLedPin,LOW); // put your here to trigger the unlocking mechanism (e.g. motor, transducer) }else{ // an incorrect NFC tag was used Serial.println("Incorrect key"); // blink the red LED and make sure the green LED is off digitalWrite(greenLedPin,LOW); digitalWrite(redLedPin,HIGH); delay(500); digitalWrite(redLedPin,LOW); delay(500); digitalWrite(redLedPin,HIGH); delay(500); digitalWrite(redLedPin,LOW); // DO NOT UNLOCK! an incorrect NFC tag was used. // put your code here to trigger an alarm (e.g. buzzard, speaker) or do something else } } delay(2000); }
To test the code/application:
Although the code is Example #2 above does what we need there is a more elegant approach to handling NFC tag detections. In this example we'll show you how to make use of the interrupt pin in the NFC shield so that instead of polling the shield (asking "is there a tag present?") we wait for the shield to tell the Arduino that a tag is available to be read. Why would you want to do this? There are many reasons and interrupts are a whole different topic, but one reason that may convince you is that your project/circuit will save battery since we are not triggering the shield circuit continuously.
The NFC shield’s interrupt pin (IRQ) is disconnect from the Arduino's digital pin 2 (D2), to connect the IRQ and D2 pin together go ahead and solder the pad on the shield labeled "D2/INT0 IRQ".
Upload the following code to your Arduino board:
#include <SPI.h> #include "PN532_SPI.h" #include "PN532.h" #include "NfcAdapter.h" // FLAG_NONE used to signal nothing needs to be done #define FLAG_NONE 0 // FLAG_IRQ_TRIGGERED used to signal an interrupt trigger #define FLAG_IRQ_TRIGGERED 1 // FLAG_RESET_IRQ used to signal that the interrupt needs to be reset #define FLAG_RESET_IRQ 2 // flags variable used to store the present flag volatile int flags = FLAG_NONE; String const myUID = "1B B3 C6 EF"; // replace this UID with your NFC tag's UID // LED pins int const greenLedPin = 3; // green led used for correct key notification int const redLedPin = 4; // red led used for incorrect key notification // the interrupt we'll be using (interrupt 0) is located at digital pin 2 int const irqPin = 2; // interrupt pin PN532_SPI interface(SPI, 10); // create a SPI interface for the shield with the SPI CS terminal at digital pin 10 NfcAdapter nfc = NfcAdapter(interface); // create an NFC adapter object String scannedUID = ""; // this is where we'll store the scanned tag's UID void setup(void) { // make LED pins outputs pinMode(greenLedPin,OUTPUT); pinMode(redLedPin,OUTPUT); Serial.begin(115200); // start serial comm Serial.println("NDEF Reader"); nfc.begin(); // begin NFC comm // turn off the LEDs digitalWrite(greenLedPin,LOW); digitalWrite(redLedPin,LOW); // attach the function "irq" to interrupt 0 on the falling edges attachInterrupt(0,irq,FALLING);// digital pin 2 is interrupt 0, we'll call the irq function (below) on the falling edge of this pin } void loop(void) { int flag = getFlag(); // get the present flag switch(flag) // check which flag/signal we are on { case FLAG_NONE: // nothing needs to be done break; case FLAG_IRQ_TRIGGERED: // the interrupt pin has been triggered Serial.println("Interrupt Triggered"); if (nfc.tagPresent()) { // an NFC tag is present NfcTag tag = nfc.read(); // read the NFC tag scannedUID = tag.getUidString(); // get the NFC tag's UID if(myUID.compareTo(scannedUID) == 0) // compare the NFC tag's UID with the correct tag's UID (a match exists when compareTo returns 0) { // the scanned NFC tag matches the saved myUID value Serial.println("Correct tag/key"); blinkLed(greenLedPin,200,4); // blink the green led // put your here to trigger the unlocking mechanism (e.g. motor, transducer) }else{ // the scanned NFC tag's UDI does not match the myUID value Serial.println("Incorrect tag/key"); blinkLed(redLedPin,200,4); // blink the red led // DO NOT UNLOCK! an incorrect NFC tag was used. // put your code here to trigger an alarm (e.g. buzzard, speaker) or do something else } // return to the original state setFlag(FLAG_NONE); reset_PN532_IRQ_pin(); }else{ // a tag was not present (the IRQ was triggered by some other action) setFlag(FLAG_NONE); } break; default: // do any other stuff for flags not handled above break; } } /* * Name: setFlat * Description: used to set actions/flags to be executed in the loop(void) function * Parameters: * int flag - the action/flag to store * Returns: void */ void setFlag(int flag) { flags = flag; } /* * Name: getFlag * Description: used to get the present flag/action * Parameters: void * Returns: int - the flags variable. The action/flag set by setFlag */ int getFlag() { return flags; } /* * Name: irq * Description: Interrupt service routine (ISR). This function will be executed whenever there is a falling edge on digital pin 2 (the interrupt 0 pin) * Parameters: void * Returns: void */ void irq() { if(getFlag()==FLAG_NONE){ setFlag(FLAG_IRQ_TRIGGERED); } } /* * Name: reset_PN532_IRQ_pin * Description: used to reset the PN532 interrupt request (IRQ) pin * Parameters: void * Returns: void */ void reset_PN532_IRQ_pin() { nfc.tagPresent(); } /* * Name: blinkLed * Description: used to toggle a pin to blink an LED attached to the pin * Parameters: * ledPin - the pin where the led is connected to * delayTime - the time in milliseconds between HIGH and LOW * times - the number of times to toggle the pin * Returns: void */ void blinkLed(int ledPin,int delayTime,int times) { for(int i=0;i<times;i++){ digitalWrite(ledPin,HIGH); delay(delayTime); digitalWrite(ledPin,LOW); delay(delayTime); } }
To test the code/application:
The serial window from our test of this code is displayed below, yours should be similar.
NFC tags are capable of storing data, the amount of data is dependent on each tag. In this example we will store two strings/messages on a tag, you will then be able to read this message with the code in Example #6: Read an NDEF Message From a Tag.
Note: If your NFC tag is not properly formatted ("Message write failed" will be displayed in the serial comm window) you'll need to see if you tag can be formatted with the code in Example #5: Format a Tag as NDEF
#include <SPI.h> #include "PN532_SPI.h" #include "PN532.h" #include "NfcAdapter.h" PN532_SPI interface(SPI, 10); // create a SPI interface for the shield with the SPI CS terminal at digital pin 10 NfcAdapter nfc = NfcAdapter(interface); // create an NFC adapter object void setup(void) { Serial.begin(115200); // start serial comm Serial.println("NDEF Reader"); nfc.begin(); // begin NFC comm } void loop(void) { Serial.println("Place a formatted Mifare Classic NFC tag on the reader."); if(nfc.tagPresent()) { NdefMessage message = NdefMessage(); message.addUriRecord("Hello, world!"); message.addUriRecord("How are you today?"); bool success = nfc.write(message); if(success) { Serial.println("The message was successfully written to the tag.");Ho }else{ Serial.println("Message write failed."); } } delay(5000); }
To test the code above:
Your brand new NFC tag might not be NDEF formatted initially. To format a tag as NDEF upload the following code to your Arduino development board:
#include <SPI.h> #include "PN532_SPI.h" #include "PN532.h" #include "NfcAdapter.h" PN532_SPI interface(SPI, 10); // create a SPI interface for the shield with the SPI CS terminal at digital pin 10 NfcAdapter nfc = NfcAdapter(interface); // create an NFC adapter object void setup(void) { Serial.begin(115200); // start serial comm Serial.println("NDEF Reader"); nfc.begin(); // begin NFC comm } void loop(void) { Serial.println("Place an unformatted Mifare Classic tag on the reader."); if (nfc.tagPresent()) { bool success = nfc.format(); if (success) { Serial.println("Success, tag formatted as NDEF."); } else { Serial.println("Format failed."); } } delay(5000); }
To test/run the code:
Note: If your tag failed to be formatted try again, if it fails your tag is not capable to be formatted as NDEF.
As you have seen in the example's above, the NFC shield is capable of writing messages to NFC tags. The NFC is also capable of reading NDEF messages from tags, in this example we'll show you how.
#include <SPI.h> #include "PN532_SPI.h" #include "PN532.h" #include "NfcAdapter.h" PN532_SPI interface(SPI, 10); // create a SPI interface for the shield with the SPI CS terminal at digital pin 10 NfcAdapter nfc = NfcAdapter(interface); // create an NFC adapter object void setup(void) { Serial.begin(115200); // start serial comm Serial.println("NDEF Reader"); nfc.begin(); // begin NFC comm } void loop(void) { Serial.println("\nScan an NFC tag\n"); if (nfc.tagPresent()) // Do an NFC scan to see if an NFC tag is present { NfcTag tag = nfc.read(); // read the NFC tag if(tag.hasNdefMessage()) { NdefMessage message = tag.getNdefMessage(); for(int i=0;i<message.getRecordCount();i++) { NdefRecord record = message.getRecord(i); int payloadLength = record.getPayloadLength(); byte payload[payloadLength]; record.getPayload(payload); Serial.write(payload,payloadLength); } } } delay(500); // wait half a second (500ms) before scanning again (you may increment or decrement the wait time) }
To test code above:
You can then use the same code in the examples above but with pin 9 instead of 10 for the PN532 interface:
PN532_SPI interface(SPI, 9); // create a SPI interface for the shield with the SPI CS terminal at digital pin 9
You may now create two separate NFC objects, one for each shield, as follows:
PN532_SPI interface_shield_1(SPI, 10); // create a SPI interface for the shield with the SPI CS terminal at digital pin 10 PN532_SPI interface_shield_2(SPI, 9); // create a SPI interface for the shield with the SPI CS terminal at digital pin 9 NfcAdapter nfc_shield_1 = NfcAdapter(interface_shield_1); // create an NFC adapter object for shield one NfcAdapter nfc_shield_2 = NfcAdapter(interface_shield_2); // create an NFC adapter object for shield two
NFC Shield v2.0 Schematic
NFC Shield v2.0 Eagle File
NFC Shield v2.1 Schematic
NFC Shield v2.1 Eagle File
PN532_SPI Library For NFC Shield v2.0
PN532 Datasheet
If you want to make some awesome projects by NFC Shield V2.0, here's some projects for reference.
This is a demo make by NFC Shield V2.0.
Paper Man brings an interesting way to communicate with Android through NFC technology. You can send a message to the Paper Man by touching its header with a NFC enabled Android device, and the paper man will spit it out by printing with the thermal printer.
More Awesome Projects by NFC Shield V2.0
Copyright (c) 2008-2016 Seeed Development Limited (www.seeedstudio.com / www.seeed.cc)