Arduino-PN532 dengan komunikasi I2C

Sebelumnya telah dibahas mengenai penggunaan modul PN532 dan ESP32 yang dapat berkomunikasi dengan baik dengan menggunakan komunikasi SPI. Nah untuk selanjutnya saya akan mencoba memaparkan sedikit gambaran penggunaan modul PN532 di Arduino UNO dengan komunikasi I2C. Alasan menggunakan I2C karena untuk meminimalkan penggunaan pin I/O dan memudahkan dalam pengembangan selanjutnya.

1. Wiring
Ubah posisi dip Switch ke mode I2C (SW1=ON, SW2=OFF). Pin yang digunakan adalah pin I2C yaitu SDA dan SCL, selain itu digunakan juga pin RQ dan RST.
Arduino-PN532 I2C communication

2. Program
Sebelumnya silahkan terlebih dahulu install library modul PN532. Library yang digunakan adalah Adafruit PN532 by Adafruit.
Arduino-PN532 I2C communication

Setelah install library selesai, kita bisa melakukan percobaan dengan sampel program yang tersedia. pastikan konfigurasi pin sudah sesuai dengan wiring diagram. Selanjutnya langsung upload programnya ke arduino. Sebagai contoh adalah program berikut:

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_PN532.h>

#define PN532_IRQ   (2)
#define PN532_RESET (3)  // Not connected by default on the NFC Shield

Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);

void setup(void) {
  Serial.begin(115200);
  Serial.println("Hello!");

  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    while (1); // halt
  }
  // 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);
  
  // configure board to read RFID tags
  nfc.SAMConfig();
  
  Serial.println("Waiting for an ISO14443A Card ...");
}


void loop(void) {
  uint8_t success;
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
  uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
    
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
  
  if (success) {
    // Display some basic information about the card
    Serial.println("Found an ISO14443A card");
    Serial.print("  UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
    Serial.print("  UID Value: ");
    nfc.PrintHex(uid, uidLength);
    Serial.println("");
    
    if (uidLength == 4){
      Serial.println("Seems to be a Mifare Classic card (4 byte UID)");
   
      Serial.println("Trying to authenticate block 4 with default KEYA value");
      uint8_t keya[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
   
     success = nfc.mifareclassic_AuthenticateBlock(uid, uidLength, 4, 0, keya);
   
      if (success){
        Serial.println("Sector 1 (Blocks 4..7) has been authenticated");
        uint8_t data[16];
  
        success = nfc.mifareclassic_ReadDataBlock(4, data);
  
        if (success){
          Serial.println("Reading Block 4:");
          nfc.PrintHexChar(data, 16);
          Serial.println("");
        delay(1000);
        }
        else{
          Serial.println("Ooops ... unable to read the requested block.  Try another key?");
        }
      }
      else{
        Serial.println("Ooops ... authentication failed: Try another key?");
      }
    }
    
    if (uidLength == 7){
      // We probably have a Mifare Ultralight card ...
      Serial.println("Seems to be a Mifare Ultralight tag (7 byte UID)");
   
      // Try to read the first general-purpose user page (#4)
      Serial.println("Reading page 4");
      uint8_t data[32];
      success = nfc.mifareultralight_ReadPage (4, data);
      if (success)
      {
        // Data seems to have been read ... spit it out
        nfc.PrintHexChar(data, 4);
        Serial.println("");
  
        // Wait a bit before reading the card again
        delay(1000);
      }
      else{
        Serial.println("Ooops ... unable to read the requested page!?");
      }
    }
  }
}

Program diatas merupakan contoh program yang digunakan untuk membaca kartu jenis mifare. Biasanya setiap pembelian modul PN532 akan mendapatkan 1 buah kartu dan 1 buah tag id yang keduanya merupakan kartu jenis mifare classic. Secara spesifik program akan membaca ID kartu yang terdiri dari 4 byte data yang ditampilkan dalam bilangan hexadesimal (UID Value) dan selanjutnya akan membaca data yang tersimpan di dalam kartu yang terletak pada sektor 1 blok 4.  Untuk hasilnya dapat dilihat pada serial monitor (setting baudrate pada 115200).
Arduino PN532 NFC

3. Momory Map
Dari gambar diatas dapat dilihat bahwa pada sektor 1 blok 4 masih belum terdapat data/kosong. Nah kita dapat mengisi area tersebut dengan data yang kita inginkan. Untuk lebih mudahnya kita harus memahami struktur dari jenis kartu yang kita gunakan (misalnya mifare classic 1K).
Arduino dengan PN532
Kartu jenis Mifare Classic 1K memiliki 16 Sector dengan setiap sectornya terdiri dari 4 blok. Setiap blok dapat menyimpan data sebanyak 16 byte. Setiap sector memiliki sector trailer yang biasanya blok ke empat di suatu sector. sector trailer berisi kunci autentifikasi yang digunakan untuk membaca/menulis blok dalam sector tersebut (kecuali sector trailer). Blok disusun secara berurutan dari 1 sampai 63. Untuk membaca/menulis data kita hanya fokus ke letak blok. Misalkan apabila kita ingin membaca data pada sektor 14 blok pertama(0) maka kita hanya perlu menuliskan perintah untuk membaca/menulis pada blok 56. Default key untuk kartu jenis mifare classic adalah  0xFF FF FF FF FF FF

4. Menyimpan data dalam kartu
Struktur program yang akan kita coba adalah menulis data kemudian membaca datanya. Kita akan menyimpan data di sector 2 blok pertama atau dengan kata lain adalah blok 8.

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_PN532.h>

#define PN532_IRQ   (2)
#define PN532_RESET (3)  // Not connected by default on the NFC Shield
Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);


void setup(void) {
  Serial.begin(115200);
  Serial.println("Hello!");

  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    while (1); // halt
  }
  // 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);
  
  // configure board to read RFID tags
  nfc.SAMConfig();
  
  Serial.println("Waiting for an ISO14443A Card ...");
}


void loop(void) {
  uint8_t success;
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
  uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
    
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
  
  if (success) {
    // Display some basic information about the card
    Serial.println("Found an ISO14443A card");
    Serial.print("  UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
    Serial.print("  UID Value: ");
    nfc.PrintHex(uid, uidLength);
    Serial.println("");
    
    if (uidLength == 4){
      // We probably have a Mifare Classic card ... 
      Serial.println("Seems to be a Mifare Classic card (4 byte UID)");
   
      Serial.println("Trying to authenticate block 8 with default KEYA value");
      uint8_t keya[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
     success = nfc.mifareclassic_AuthenticateBlock(uid, uidLength, 8, 0, keya);
   
      if (success)
      {
        Serial.println("Sector 2 (Blocks 8..11) has been authenticated");
        uint8_t data[16];

        Serial.println("Writing Block 8:...");
        //menulis data
        memcpy(data, (const uint8_t[]){ 'a', 'r', 'd', 'u','c', 'o', 'd', 'i', 'n', 'g', '.', 'c', 'o', 'm', 0, 0 }, sizeof data);
        success = nfc.mifareclassic_WriteDataBlock (8, data); //blok 8
        Serial.println("Writing Block 8: OK");
        Serial.println("");
        
        // Try to read the contents of block 8
        success = nfc.mifareclassic_ReadDataBlock(8, data);
  
        if (success){
          // Data seems to have been read ... spit it out
          Serial.println("Reading Block 8:");
          nfc.PrintHexChar(data, 16);
          Serial.println("");
    
          // Wait a bit before reading the card again
          delay(1000);
        }
        else{
          Serial.println("Ooops ... unable to read the requested block.  Try another key?");
        }
      }
      else{
        Serial.println("Ooops ... authentication failed: Try another key?");
      }
    }
  }
}
Arduino dengan PN532

Nah, Asyik bukan. Masih banyak lagi lho, trik trik dan projek yang berhubungan dengan smart card ini. Mari sharing dan belajar bersama.

Pencarian Terkait: