Example of using the Adafruit PN532 RFID/NFC board to read Mifare Classic cards.
Embed:
(wiki syntax)
Show/hide line numbers
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 }
Generated on Sat Aug 6 2022 00:57:20 by
1.7.2