Example of using the Adafruit PN532 RFID/NFC board to read Mifare Classic cards.

Dependencies:   mbed pn532

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "pn532/pn532.h"
00003 
00004 #define NOTE_A4  440
00005 #define NOTE_G7  3136
00006 
00007 BusOut leds(LED1, LED2, LED3, LED4);
00008 PN532 rfid(p5, p6, p7, p8);
00009 Timer readTimer;
00010 PwmOut speaker(p21);
00011 
00012 void loop();
00013 
00014 int main() {
00015     printf("Hello!\r\n");
00016 
00017     uint32_t versiondata = rfid.getFirmwareVersion();
00018     if (!versiondata) {
00019         printf("Didn't find PN53x board\r\n");
00020         while (1); // halt
00021     }
00022 
00023     printf("Found chip PN5%lx\r\n", ((versiondata>>24) & 0xFF));
00024     printf("Firmware ver. %lu.%lu\r\n", (versiondata>>16) & 0xFF,
00025            (versiondata>>8) & 0xFF);
00026 
00027     rfid.SAMConfig();
00028 
00029     printf("Waiting for an ISO14443A Card ...\r\n");
00030 
00031     while (1) {
00032         loop();
00033     }
00034 }
00035 
00036 void beep(uint16_t note, uint16_t duration) {
00037     speaker.period(1.0/float(note));
00038     speaker = 0.25;
00039     wait_ms(duration);
00040     speaker = 0;
00041 }
00042 
00043 void loop() {
00044     uint8_t success, i;
00045     uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
00046     uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
00047     static uint8_t lastUID[7];
00048     static uint8_t lastUIDLength;
00049     uint8_t newCardFound;
00050 
00051     // Wait for an ISO14443A type cards (Mifare, etc.).  When one is found
00052     // 'uid' will be populated with the UID, and uidLength will indicate
00053     // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
00054     success = rfid.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
00055 
00056     // Compare and see if we are seeing a new card
00057     newCardFound = 0;
00058     if (success) {
00059         if (readTimer.read_ms() > 400) {
00060             newCardFound = 1;
00061         }
00062         readTimer.reset();
00063 
00064         if (uidLength != lastUIDLength) {
00065             newCardFound = 1;
00066         } else {
00067             for (i = 0; i < uidLength; i++) {
00068                 if (uid[i] != lastUID[i]) {
00069                     newCardFound = 1;
00070                     break;
00071                 }
00072             }
00073         }
00074     }
00075 
00076     if (newCardFound) {
00077         for (i = 0; i < uidLength; i++) {
00078             lastUID[i] = uid[i];
00079         }
00080         lastUIDLength = uidLength;
00081 
00082         leds = 0xF;
00083 
00084         if (uidLength == 4) {
00085             // We probably have a Mifare Classic card ...
00086             uint32_t cardid = uid[0];
00087             cardid <<= 8;
00088             cardid |= uid[1];
00089             cardid <<= 8;
00090             cardid |= uid[2];
00091             cardid <<= 8;
00092             cardid |= uid[3];
00093 
00094 
00095             // Now we need to try to authenticate it for read/write access
00096             // Try with the factory default KeyA: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
00097             uint8_t keya[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
00098 
00099             // Start with block 4 (the first block of sector 1) since sector 0
00100             // contains the manufacturer data and it's probably better just
00101             // to leave it alone unless you know what you're doing
00102             success = rfid.mifareclassic_AuthenticateBlock(uid, uidLength, 4, 0, keya);
00103 
00104             if (success) {
00105                 uint8_t data[16];
00106 
00107                 // If you want to write something to block 4 to test with, uncomment
00108                 // the following line and this text should be read back in a minute
00109                 // memcpy(data, (const uint8_t[]){ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xE, 0xC, 0xE, 4, 1, 8, 0 }, sizeof data);
00110                 // success = rfid.mifareclassic_WriteDataBlock (4, data);
00111 
00112                 // Try to read the contents of block 4
00113                 success = rfid.mifareclassic_ReadDataBlock(4, data);
00114 
00115                 // printf("Seems to be a Mifare Classic card #%lu\r\n", cardid);
00116                 if (success) {
00117                     // Data seems to have been read ... spit it out
00118                     leds = 0x6;
00119                     beep(NOTE_G7, 200);
00120 
00121                     // Display some basic information about the card
00122                     printf("Found an ISO14443A card\r\n");
00123                     printf("  UID Length: %d bytes\r\n", uidLength);
00124                     printf("  UID Value: ");
00125                     rfid.PrintHex(uid, uidLength);
00126 
00127                     printf("Seems to be a Mifare Classic card #%lu\r\n", cardid);
00128 
00129                     printf("Reading Block 4: ");
00130                     rfid.PrintHexChar(data, 16);
00131                     printf("\r\n");
00132                 } else {
00133                     leds = 0x9;
00134                     beep(NOTE_A4, 800);
00135 
00136                     printf("Found an ISO14443A card\r\n");
00137                     printf("  UID Length: %d bytes\r\n", uidLength);
00138                     printf("  UID Value: ");
00139                     rfid.PrintHex(uid, uidLength);
00140 
00141                     printf("Seems to be a Mifare Classic card #%lu\r\n", cardid);
00142                     printf("Ooops ... unable to read the requested block.  Try another key?\r\n");
00143                     printf("\r\n");
00144                 }
00145             } else {
00146                 leds = 0x9;
00147                 beep(NOTE_A4, 800);
00148 
00149                 printf("Found an ISO14443A card\r\n");
00150                 printf("  UID Length: %d bytes\r\n", uidLength);
00151                 printf("  UID Value: ");
00152                 rfid.PrintHex(uid, uidLength);
00153 
00154                 printf("Seems to be a Mifare Classic card #%lu\r\n", cardid);
00155                 printf("Ooops ... authentication failed: Try another key?\r\n");
00156                 printf("\r\n");
00157             }
00158         } else {
00159             leds = 0x9;
00160             beep(NOTE_A4, 800);
00161 
00162             printf("Found an ISO14443A card\r\n");
00163             printf("  UID Length: %d bytes\r\n", uidLength);
00164             printf("  UID Value: ");
00165             rfid.PrintHex(uid, uidLength);
00166 
00167             printf("Unsupported card type\r\n");
00168             printf("\r\n");
00169         }
00170 
00171         wait_ms(200);
00172         leds = 0;
00173 
00174         readTimer.reset();
00175         readTimer.start();
00176     }
00177 }