Pages: [1]   Go Down
Author Topic: NFC Success! - Interfacing with Mifare  (Read 2404 times)
0 Members and 1 Guest are viewing this topic.
Australia
Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am very much a novice with arduino and want to share my success with anyone thinking of a similar project with NFC.
I am building a card reader for my primary school classroom that records when students enter the room using their "smart cards", then a random good morning message is played using a wav shield also attached to the UNO.
After a LOT smiley-mad of searching on the web, I actually found the code that works... almost!
Code:
//This example reads all MIFARE memory block from 0x00 to 0x63.
//It is tested with a new MIFARE 1K cards. Uses default keys for authenication.
//Contributed by Seeed Technology Inc (www.seeedstudio.com)

#include <PN532.h>
#include <SPI.h>

/*Chip select pin can be connected to D10 or D9 which is hareware optional*/
/*if you the version of NFC Shield from SeeedStudio is v2.0.*/
#define PN532_CS 10

PN532 nfc(PN532_CS);

#define  NFC_DEMO_DEBUG 1

void setup(void) {
#ifdef NFC_DEMO_DEBUG
  Serial.begin(9600);
  Serial.println("Hello!");
#endif
  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
#ifdef NFC_DEMO_DEBUG
    Serial.print("Didn't find PN53x board");
#endif
    while (1); // halt
  }
#ifdef NFC_DEMO_DEBUG
  // 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);
  Serial.print("Supports ");
  Serial.println(versiondata & 0xFF, HEX);
#endif
  // configure board to read RFID tags and cards
  nfc.SAMConfig();
}

void loop(void) {
  uint32_t id;
  // look for MiFare type cards
  id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);

  if (id != 0)
  {
#ifdef NFC_DEMO_DEBUG
    Serial.print("Read card #");
    Serial.println(id);
    Serial.println();
#endif
    uint8_t keys[]= { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF };// default key of a fresh card
    for(uint8_t blockn=0;blockn<64;blockn++)
    {
      if(nfc.authenticateBlock(1, id ,blockn,KEY_A,keys)) //authenticate block blockn
      {
        //if authentication successful
        uint8_t block[16];
        //read memory block blockn
        if(nfc.readMemoryBlock(1,blockn,block))
        {
#ifdef NFC_DEMO_DEBUG
          //if read operation is successful
          for(uint8_t i=0;i<16;i++)
          {
            //print memory block
            Serial.print(block[i],HEX);
            if(block[i] <= 0xF) //Data arrangement / beautify
            {
              Serial.print("  ");
            }
            else
            {
              Serial.print(" ");
            }
          }

          Serial.print("| Block ");
          if(blockn <= 9) //Data arrangement / beautify
          {
            Serial.print(" ");
          }
          Serial.print(blockn,DEC);
          Serial.print(" | ");

          if(blockn == 0)
          {
            Serial.println("Manufacturer Block");
          }
          else
          {
            if(((blockn + 1) % 4) == 0)
            {
              Serial.println("Sector Trailer");
            }
            else
            {
              Serial.println("Data Block");
            }
          }
#endif
        }
      }
    }
  }
  delay(2000);
}

On the console a dec. id is printed out but it does not work with the "if" statements I am trying!
This is the console monitor printout:
Hello!
Found chip PN532
Firmware ver. 1.6
Supports 7
Found 1 tags
Sens Response: 0x4
Sel Response: 0x8
 0x4A 0x3 0xD5 0xD6Read card #1241765334

A little tweaking of code is required - of the card's decimal ID (1241765334) to enable an if/else statement to work. Here is the MIfare code THAT I HAVE WRITTEN onto line 56:
Code:
//This changes the crazy id into an integer that actually works

int x;
x = id;
Serial.print("New card id # is");
Serial.println(x);

The serial monitor now says
Hello!
Found chip PN532
Firmware ver. 1.6
Supports 7
Found 1 tags
Sens Response: 0x4
Sel Response: 0x8
 0x4A 0x3 0xD5 0xD6Read card #1241765334

New card id # is-10794


Now that you have that new id (-10794), it works with if statements, like say good morning to a particular student whereas I could not get anything to happen with the old id (1241765334).

If anyone can tell me what is happening here I would appreciate your comments.





Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Truncating a 32 bit value to fit in 16 bits doesn't seem like a good idea.

Quote
Now that you have that new id (-10794), it works with if statements, like say good morning to a particular student whereas I could not get anything to happen with the old id (1241765334).
The if statements that you didn't bother to show?

Quote
If anyone can tell me what is happening here I would appreciate your comments.
What is happening is that you didn't post all of your code, apparently.
Logged

Australia
Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I know I left out a lot of information this morning. I was pretty wrapped to actually make something happen the way I wanted it to.

Firstly I forgot to say which  shield I am using:
http://littlebirdelectronics.com/search?type=product&q=nfc
I purchased 25 book tags as well for the students in my class.

Secondly I am using PN532 library http://www.seeedstudio.com/wiki/File:PN532_SPI_V2.zip

As I am a novice at arduino, my latest sketch is still reading and printing my card ids ( I know all of my 25 ids now so I will take that code out tomorrow. Here it is in its entirety...

Code:
//This example reads all MIFARE memory block from 0x00 to 0x63.
//It is tested with a new MIFARE 1K cards. Uses default keys for authenication.
//Contributed by Seeed Technology Inc (www.seeedstudio.com)

#include <PN532.h>
#include <SPI.h>

/*Chip select pin can be connected to D10 or D9 which is hareware optional*/
/*if you the version of NFC Shield from SeeedStudio is v2.0.*/
#define PN532_CS 10

PN532 nfc(PN532_CS);

#define  NFC_DEMO_DEBUG 1

void setup(void) {
#ifdef NFC_DEMO_DEBUG
  Serial.begin(9600);
  Serial.println("Hello!");
#endif
  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
#ifdef NFC_DEMO_DEBUG
    Serial.print("Didn't find PN53x board");
#endif
    while (1); // halt
  }
#ifdef NFC_DEMO_DEBUG
  // 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);
  Serial.print("Supports ");
  Serial.println(versiondata & 0xFF, HEX);
#endif
  // configure board to read RFID tags and cards
  nfc.SAMConfig();
}

void loop(void) {
  uint32_t id;
  // look for MiFare type cards
  id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);

  if (id != 0)
  {
#ifdef NFC_DEMO_DEBUG
    Serial.print("Read card #");
    Serial.println(id);
    Serial.println();
int x;
x = id;
Serial.print("New card id # is");
Serial.println(x);
if (id = -10794)
{
  Serial.print("Good Morning John");
}

#endif
    uint8_t keys[]= { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF };// default key of a fresh card
    for(uint8_t blockn=0;blockn<64;blockn++)
    {
      if(nfc.authenticateBlock(1, id ,blockn,KEY_A,keys)) //authenticate block blockn
      {
        //if authentication successful
        uint8_t block[16];
        //read memory block blockn
        if(nfc.readMemoryBlock(1,blockn,block))
        {
#ifdef NFC_DEMO_DEBUG
          //if read operation is successful
          for(uint8_t i=0;i<16;i++)
          {
            //print memory block
            Serial.print(block[i],HEX);
            if(block[i] <= 0xF) //Data arrangement / beautify
            {
              Serial.print("  ");
            }
            else
            {
              Serial.print(" ");
            }
          }

          Serial.print("| Block ");
          if(blockn <= 9) //Data arrangement / beautify
          {
            Serial.print(" ");
          }
          Serial.print(blockn,DEC);
          Serial.print(" | ");

          if(blockn == 0)
          {
            Serial.println("Manufacturer Block");
          }
          else
          {
            if(((blockn + 1) % 4) == 0)
            {
              Serial.println("Sector Trailer");
            }
            else
            {
              Serial.println("Data Block");
            }
          }
#endif
        }
      }
    }
  }
  delay(2000);
}

I added is these lines to the code I found:

    Serial.print("Read card #");
    Serial.println(id);
    Serial.println();
int x;
x = id;
Serial.print("New card id # is");
Serial.println(x);
if (id = -10794)
{
  Serial.print("Good Morning John");
}

It works great and prints Good Morning John on the serial monitor.
Next I will try lighting a led if the card id is correct - I think I need more power as the leds I have connected glow very dim - maybe it is the usb power.

The reason I am writing all of this down is I think this information will assist others who have a similar project in mind. I found it difficult to locate the code I needed and am happy it has worked out. This is a great learning experience and I would like to see schools facilitating learning through mistakes - just as I have done.
I am sure there are many other ways to activate an output from mifare card but at the moment this is working fine.
 
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I added is these lines to the code I found:

    Serial.print("Read card #");
    Serial.println(id);
    Serial.println();
int x;
x = id;
Serial.print("New card id # is");
Serial.println(x);
if (id = -10794)
{
  Serial.print("Good Morning John");
}
In place of?

Let me guess. You had something like:
Code:
if(id == 1241765334)
{
   // Do something
}
and that didn't work, because none of the if blocks ever evaluated to true.

Try this:
if(id == 1241765334UL)
{
   // Do something
}

The first snippet fails because, in the absence of directives to the contrary, literal constants are treated as ints. 1241765334 is not an int. In the second snippet, there is a directive to the contrary that tells the compiler to treat the literal constant as an unsigned long, rather than an int. Since 1241765334 is a valid unsigned long, it will match id, and the block will be executed.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I think I need more power as the leds I have connected glow very dim - maybe it is the usb power.
Or the pin that the LED is connected to needs to be defined (using pinMode()) as an OUTPUT pin.
Logged

Australia
Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Paul S. Your advice is very much appreciated. I am going to rewrite:
if(id == 1241765334UL)
{
   // Do something
}

and

(using pinMode())

for my led.


Cheers again!!!!
Logged

Pages: [1]   Go Up
Jump to: