2

I am trying to use an arduino board with NFC shield to be able to unlock the door of my car.

Board: Arduino UNO Rev 3 NFC Shield: v2.0b by Seeed Studio

So when a NFC tag is present a signal turns a servo 180 degrees to unlock the door. Currently the problem is that I would like only one NFC tag to be able to unlock/lock the door, not just any.

At the moment any NFC tag can turn the servo.

Does anyone know which function to call to only return the UID of the NFC tag, which it can then compare to a known NFC tag.

http://www.seeedstudio.com/wiki/NFC_Shield_V2.0

#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);
}

This code works.

Michael Roland
  • 39,663
  • 10
  • 99
  • 206
user3599457
  • 21
  • 1
  • 2

3 Answers3

3

You indicate that you are currently unlocking upon detection of just any tag. So you must already be polling for tags. If you are using the original seeedstudio library, you can either just perform a polling for any passive target using the inListPassiveTarget() method or (as commesan already indicated) the readPassiveTargetID() method.

While inListPassiveTarget() just returns a boolean value indicating if there is any target present, the readPassiveTargetID() method provides you with a set of configuration parameters and also permits you to retrieve the anti-collision identifier (e.g. UID for ISO 14443 Type A):

bool PN532::readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint16_t timeout);

You can use the method like this:

uint8_t uid[16] = { 0 };
uint8_t uidLen = 0;

if (nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLen)) {
    // uid will now contain uidLen bytes of the anti-collision identifier
}

If you want to poll for other cards than ISO 14443 Type A, you can use the following defines instead of PN532_MIFARE_ISO14443A:

// ISO 14443 Type B
#define PN532_BAUD_ISO14443B   (0x03)
// FeliCa 212 kbps
#define PN532_BAUD_FELICA212   (0x01)
// FeliCa 424 kbps
#define PN532_BAUD_FELICA424   (0x02)
// Jewel Tag (NFC Forum Type 1)
#define PN532_BAUD_JEWEL       (0x04)

Finally, my usual note on using a tag's UID for access control: Don't do this! This has been proven to be a very bad idea in many existing systems. See these posts for further information:

Community
  • 1
  • 1
Michael Roland
  • 39,663
  • 10
  • 99
  • 206
  • Thank you for the information and the warning. I understand that an NFC tag can be cloned, however no one will know my car can be unlocked that way. Its a car from the 1992 ;) I will try the code tomorrow. – user3599457 May 03 '14 at 19:38
2

I'm doing this too and, using the example ReadTag from the NFC library examples, I have the UID with this:

Serial.println("\nScan electronic key\n");
if (nfc.tagPresent())
{
    NfcTag tag = nfc.read();
    Serial.println(tag.getTagType());
    String idnumber = tag.getUidString();
    Serial.print("UID: ");Serial.println(idnumber);

This gives, for example, 30 5C 6F 80 from a Mifare Classic 'pill' tag. After a little analysis, this comes back from the library as a formatted character string 11, so I compare it with

String valid = ("30 5C 6F 80") ;

And this comparison works:

 if (valid == idnumber) {
    Serial.println("Yes") ;
    // simulate door open by turning LED on
    digitalWrite(lockopen, HIGH);
    delay(lockopen_interval);
    digitalWrite(lockopen, LOW); 

    } else {
      Serial.println("No") ;
    }  
Hugh Barnard
  • 352
  • 2
  • 12
0

I believe you can use:

readPassiveTargetID(PN532_MIFARE_ISO14443A)

to get the id.

commesan
  • 526
  • 5
  • 12