| 1 | /**************************************************************************/ |
| 2 | /*! |
| 3 | @file readMifare.pde |
| 4 | @author Adafruit Industries |
| 5 | @license BSD (see license.txt) |
| 6 | |
| 7 | This example will wait for any ISO14443A card or tag, and |
| 8 | depending on the size of the UID will attempt to read from it. |
| 9 | |
| 10 | If the card has a 4-byte UID it is probably a Mifare |
| 11 | Classic card, and the following steps are taken: |
| 12 | |
| 13 | - Authenticate block 4 (the first block of Sector 1) using |
| 14 | the default KEYA of 0XFF 0XFF 0XFF 0XFF 0XFF 0XFF |
| 15 | - If authentication succeeds, we can then read any of the |
| 16 | 4 blocks in that sector (though only block 4 is read here) |
| 17 | |
| 18 | If the card has a 7-byte UID it is probably a Mifare |
| 19 | Ultralight card, and the 4 byte pages can be read directly. |
| 20 | Page 4 is read by default since this is the first 'general- |
| 21 | purpose' page on the tags. |
| 22 | |
| 23 | |
| 24 | This is an example sketch for the Adafruit PN532 NFC/RFID breakout boards |
| 25 | This library works with the Adafruit NFC breakout |
| 26 | ----> https://www.adafruit.com/products/364 |
| 27 | |
| 28 | Check out the links above for our tutorials and wiring diagrams |
| 29 | These chips use SPI or I2C to communicate. |
| 30 | |
| 31 | Adafruit invests time and resources providing this open source code, |
| 32 | please support Adafruit and open-source hardware by purchasing |
| 33 | products from Adafruit! |
| 34 | |
| 35 | */ |
| 36 | /**************************************************************************/ |
| 37 | #include <Wire.h> |
| 38 | #include <SPI.h> |
| 39 | #include <Adafruit_PN532.h> |
| 40 | |
| 41 | // If using the breakout with SPI, define the pins for SPI communication. |
| 42 | #define PN532_SCK (2) |
| 43 | #define PN532_MOSI (3) |
| 44 | #define PN532_SS (4) |
| 45 | #define PN532_MISO (5) |
| 46 | |
| 47 | // If using the breakout or shield with I2C, define just the pins connected |
| 48 | // to the IRQ and reset lines. Use the values below (2, 3) for the shield! |
| 49 | #define PN532_IRQ (2) |
| 50 | #define PN532_RESET (3) // Not connected by default on the NFC Shield |
| 51 | |
| 52 | // Uncomment just _one_ line below depending on how your breakout or shield |
| 53 | // is connected to the Arduino: |
| 54 | |
| 55 | // Use this line for a breakout with a software SPI connection (recommended): |
| 56 | Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS); |
| 57 | |
| 58 | // Use this line for a breakout with a hardware SPI connection. Note that |
| 59 | // the PN532 SCK, MOSI, and MISO pins need to be connected to the Arduino's |
| 60 | // hardware SPI SCK, MOSI, and MISO pins. On an Arduino Uno these are |
| 61 | // SCK = 13, MOSI = 11, MISO = 12. The SS line can be any digital IO pin. |
| 62 | //Adafruit_PN532 nfc(PN532_SS); |
| 63 | |
| 64 | // Or use this line for a breakout or shield with an I2C connection: |
| 65 | //Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET); |
| 66 | |
| 67 | // Or use hardware Serial: |
| 68 | //Adafruit_PN532 nfc(PN532_RESET, &Serial1); |
| 69 | |
| 70 | void setup(void) { |
| 71 | Serial.begin(115200); |
| 72 | while (!Serial) delay(10); // for Leonardo/Micro/Zero |
| 73 | |
| 74 | Serial.println("Hello!"); |
| 75 | |
| 76 | nfc.begin(); |
| 77 | |
| 78 | uint32_t versiondata = nfc.getFirmwareVersion(); |
| 79 | if (! versiondata) { |
| 80 | Serial.print("Didn't find PN53x board"); |
| 81 | while (1); // halt |
| 82 | } |
| 83 | // Got ok data, print it out! |
| 84 | Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX); |
| 85 | Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC); |
| 86 | Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC); |
| 87 | |
| 88 | Serial.println("Waiting for an ISO14443A Card ..."); |
| 89 | } |
| 90 | |
| 91 | |
| 92 | void loop(void) { |
| 93 | uint8_t success; |
| 94 | uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID |
| 95 | uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type) |
| 96 | |
| 97 | // Wait for an ISO14443A type cards (Mifare, etc.). When one is found |
| 98 | // 'uid' will be populated with the UID, and uidLength will indicate |
| 99 | // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight) |
| 100 | success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength); |
| 101 | |
| 102 | if (success) { |
| 103 | // Display some basic information about the card |
| 104 | Serial.println("Found an ISO14443A card"); |
| 105 | Serial.print(" UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes"); |
| 106 | Serial.print(" UID Value: "); |
| 107 | nfc.PrintHex(uid, uidLength); |
| 108 | Serial.println(""); |
| 109 | |
| 110 | if (uidLength == 4) |
| 111 | { |
| 112 | // We probably have a Mifare Classic card ... |
| 113 | Serial.println("Seems to be a Mifare Classic card (4 byte UID)"); |
| 114 | |
| 115 | // Now we need to try to authenticate it for read/write access |
| 116 | // Try with the factory default KeyA: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF |
| 117 | Serial.println("Trying to authenticate block 4 with default KEYA value"); |
| 118 | uint8_t keya[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
| 119 | |
| 120 | // Start with block 4 (the first block of sector 1) since sector 0 |
| 121 | // contains the manufacturer data and it's probably better just |
| 122 | // to leave it alone unless you know what you're doing |
| 123 | success = nfc.mifareclassic_AuthenticateBlock(uid, uidLength, 4, 0, keya); |
| 124 | |
| 125 | if (success) |
| 126 | { |
| 127 | Serial.println("Sector 1 (Blocks 4..7) has been authenticated"); |
| 128 | uint8_t data[16]; |
| 129 | |
| 130 | // If you want to write something to block 4 to test with, uncomment |
| 131 | // the following line and this text should be read back in a minute |
| 132 | //memcpy(data, (const uint8_t[]){ 'a', 'd', 'a', 'f', 'r', 'u', 'i', 't', '.', 'c', 'o', 'm', 0, 0, 0, 0 }, sizeof data); |
| 133 | // success = nfc.mifareclassic_WriteDataBlock (4, data); |
| 134 | |
| 135 | // Try to read the contents of block 4 |
| 136 | success = nfc.mifareclassic_ReadDataBlock(4, data); |
| 137 | |
| 138 | if (success) |
| 139 | { |
| 140 | // Data seems to have been read ... spit it out |
| 141 | Serial.println("Reading Block 4:"); |
| 142 | nfc.PrintHexChar(data, 16); |
| 143 | Serial.println(""); |
| 144 | |
| 145 | // Wait a bit before reading the card again |
| 146 | delay(1000); |
| 147 | } |
| 148 | else |
| 149 | { |
| 150 | Serial.println("Ooops ... unable to read the requested block. Try another key?"); |
| 151 | } |
| 152 | } |
| 153 | else |
| 154 | { |
| 155 | Serial.println("Ooops ... authentication failed: Try another key?"); |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | if (uidLength == 7) |
| 160 | { |
| 161 | // We probably have a Mifare Ultralight card ... |
| 162 | Serial.println("Seems to be a Mifare Ultralight tag (7 byte UID)"); |
| 163 | |
| 164 | // Try to read the first general-purpose user page (#4) |
| 165 | Serial.println("Reading page 4"); |
| 166 | uint8_t data[32]; |
| 167 | success = nfc.mifareultralight_ReadPage (4, data); |
| 168 | if (success) |
| 169 | { |
| 170 | // Data seems to have been read ... spit it out |
| 171 | nfc.PrintHexChar(data, 4); |
| 172 | Serial.println(""); |
| 173 | |
| 174 | // Wait a bit before reading the card again |
| 175 | delay(1000); |
| 176 | } |
| 177 | else |
| 178 | { |
| 179 | Serial.println("Ooops ... unable to read the requested page!?"); |
| 180 | } |
| 181 | } |
| 182 | } |
| 183 | } |
| 184 | |