Go Down

Topic: NFC Success! - Interfacing with Mifare (Read 3000 times) previous topic - next topic

harbee

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 :0 of searching on the web, I actually found the code that works... almost!
Code: [Select]
//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: [Select]

//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.






PaulS

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.

harbee

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: [Select]

//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.

PaulS

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: [Select]
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.

PaulS

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.

harbee

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!!!!

Go Up