NFC Arduino

In questi giorni ho fatto il mio primo test con l’NFC arduino usando una shield della DF Robot ed un arduino MEGA 2560

NFC Arduino

come ogni primo test delle nuove schede ho cercato e trovato la documentazione della shield per studiare come deve essere collegata ed avere un primo esempio di sketch da utlizzare.

Ho trovato la consueta wiki realizzata dal produttore della shield.

La scelta per realizzare il test dell’NFC arduino è caduta sull’arduinio MEGA 2560 in quanto dotata di quattro porte seriali:

arduino MEGA 2560 serial

anche se per il test ne userai soltanto 2:

  • la Serial: per comunicare con il monitor seriale
  • la Serial1: per comunicare con l’NFC arduino shield.

Il collegamento dell’NFC arduino

Il collegamento dell’NFC arduino è abbastanza semplice, basta seguire la wiki o semplicemnete conoscere come funziona la comunicazione seriale tra dispositivi.

Nell’esempio collega il TXD del dispositivo al pin Rx di arduino ed il contatto RXD del dispositivo al pin Tx di arduino.

In pratica ti troverai i collegamenti lato arduino:

NFC Arduino collegamenti mega

ed i collegamenti lato NFC arduino shield invertiti:

NFC Arduino collehamenti nfc

da cui puoi notare che il filo verde trasmette l’impulso seriale dall’NFC ad arduino ed il filo blu fa l’opposto.

Inoltre puoi notare che ho alimentato l’NFC a 3,3v anche se il dispositivo nfc è dotato di un circuito di alimentazione che accetta sia i 3,3v sia i 5v.

Lo sketch

Lo sketch di test dell’nfc arduino è quello fornito dal produttore della shield e copiato dalla wiki ufficiale.

Lo scopo dello sketch è inizializzare l’nfc arduino shield e leggere i tag nfc mostrando sul monitor seriale il valore del tag letto.

/*
 
 # Editor : Adrian
 # Date   : 2013.04.18
 # Ver    : 0.1
 # Product: NFC Module for Arduino
 # SKU    : DFR0231
    
 # Description:    
 # When the a card close to the device , the PC will receive the data
 # Connect the NFC Card's TXD, RXD, GND, +3.3V to Nano's D0RX, D1TX, GND, +3.3V
 # Or connect the NFC Card's TXD, RXD, GND, +5V to Nano's D0RX, D1TX, GND, +5V
 
  
 PN532 reads the tag by Arduino mega/Leonardo
 command list:
  
 #wake up reader
 send: 55 55 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff 03 fd d4 14 01 17 00
 return: 00 00 FF 00 FF 00 00 00 FF 02 FE D5 15 16 00
  
 #get firmware
 send: 00 00 FF 02 FE D4 02 2A 00
 return: 00 00 FF 00 FF 00 00 00 FF 06 FA D5 03 32 01 06 07 E8 00
  
 #read the tag
 send: 00 00 FF 04 FC D4 4A 01 00 E1 00
 return: 00 00 FF 00 FF 00 00 00 FF 0C F4 D5 4B 01 01 00 04 08 04 XX XX XX XX 5A 00
 XX is tag.
  
 */
  
 //************* start **************
 
const unsigned char wake[24]={
  0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0xfd, 0xd4, 0x14, 0x01, 0x17, 0x00};//wake up NFC module
const unsigned char firmware[9]={
  0x00, 0x00, 0xFF, 0x02, 0xFE, 0xD4, 0x02, 0x2A, 0x00};//
const unsigned char tag[11]={
  0x00, 0x00, 0xFF, 0x04, 0xFC, 0xD4, 0x4A, 0x01, 0x00, 0xE1, 0x00};//detecting tag command
const unsigned char std_ACK[25] = {
  0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x0C, \
0xF4, 0xD5, 0x4B, 0x01, 0x01, 0x00, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x00};
unsigned char old_id[5];
 
unsigned char receive_ACK[25];//Command receiving buffer
//int inByte = 0;               //incoming serial byte buffer
 
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#define print1Byte(args) Serial1.write(args)
#define print1lnByte(args)  Serial1.write(args),Serial1.println()
#else
#include "WProgram.h"
#define print1Byte(args) Serial1.print(args,BYTE)
#define print1lnByte(args)  Serial1.println(args,BYTE)
#endif
 
void setup()
{
  Serial.begin(9600);   // open serial with PC
  Serial1.begin(115200);    //open serial1 with device
  //Serial2.begin(115200);
  wake_card();
  delay(100);
  read_ACK(15);
  delay(100);
  display(15);
 
 
}
 
void loop()
{
  send_tag();
  read_ACK(25);
  delay(100);
  if (!cmp_id ()) {
    if (test_ACK ()) {
      display (25);
      delay (100);
    }
  }
  copy_id ();
}
 
 
void copy_id (void)
{//save old id
  int ai, oi;
  for (oi=0, ai=19; oi<5; oi++,ai++) {
    old_id[oi] = receive_ACK[ai];
  }
}
 
  
char cmp_id (void)
{//return true if find id is old
  int ai, oi;
  for (oi=0,ai=19; oi<5; oi++,ai++) {
    if (old_id[oi] != receive_ACK[ai])
      return 0;
  }
  return 1;
}
 
 
int test_ACK (void)
{// return true if receive_ACK accord with std_ACK
  int i;
  for (i=0; i<19; i++) {
    if (receive_ACK[i] != std_ACK[i])
      return 0;
  }
  return 1;
}
 
 
void send_id (void)
{//send id to PC
  int i;
  Serial.print ("ID: ");
  for (i=19; i<= 23; i++) {
    Serial.print (receive_ACK[i], HEX);
    Serial.print (" ");
  }
  Serial.println ();
}
 
 
void UART1_Send_Byte(unsigned char command_data)
{//send byte to device
  print1Byte(command_data);
#if defined(ARDUINO) && ARDUINO >= 100
  Serial1.flush();// complete the transmission of outgoing serial data
#endif
}
 
 
void UART_Send_Byte(unsigned char command_data)
{//send byte to PC
  Serial.print(command_data,HEX);
  Serial.print(" ");
}
 
 
void read_ACK(unsigned char temp)
{//read ACK into reveive_ACK[]
  unsigned char i;
  for(i=0;i<temp;i++) {
    receive_ACK[i]= Serial1.read();
  }
}
 
 
void wake_card(void)
{//send wake[] to device
  unsigned char i;
  for(i=0;i<24;i++) //send command
    UART1_Send_Byte(wake[i]);
}
 
 
void firmware_version(void)
{//send fireware[] to device
  unsigned char i;
  for(i=0;i<9;i++) //send command
    UART1_Send_Byte(firmware[i]);
}
 
 
void send_tag(void)
{//send tag[] to device
  unsigned char i;
  for(i=0;i<11;i++) //send command
    UART1_Send_Byte(tag[i]);
}
 
 
void display(unsigned char tem)
{//send receive_ACK[] to PC
  unsigned char i;
  for(i=0;i<tem;i++) //send command
    UART_Send_Byte(receive_ACK[i]);
  Serial.println();
}
 
 
//*********** end *************

le linee 036-048: definisci le costanti wake, firmware, tag, std_ACK, come array di tipo char ciascuno con una sequenza specifica di codici esadecimali utili ad una funzione che vedrai in seguito;

linee 049-051: definisci due variabili come array di char in cui memorizzerai i valori ricevuti dall’nfc arduino shield;

linee 054-062: rappresentano la possibilità di includere la libreria Arduino.h o la libreria WProgram.h in funzione della versione di IDE che stai utilizzanto, come sai dalla versione dell’IDE 1.0 la libreria Arduino.h sostituisce la WProgram.h;

linee 066-067: inizializza le due comunicazioni seriali sulla Serial e sulla Serial1 ( ecco perchè la scelta dell’arduino MEGA rende più semplice la riproduzione del progetto ). Nota che la velocità di comunicazione verso il monitor seriale è impostata a 9600 e quella verso l’NFC è impostata a 115200;

linee 069-073: richiami in sequenza le funzioni:

  • wake_card()
  • read_ACK(15)
  • display(15)

intervallando ciascuna funzione da 100 millisecondi di delay;

linea 078: inizia la funzione loop(), decisamente compatta, io la preferisco in quanto fa uso di altre funzioni definite dopo;

linea 080: richiami la funzione send_tag() definita alla linea 177;

linea 081: invoca la funzione read_ACK(25) definita alla linea 152;

linea 083: controlla il return code della funzione cmp_id(9 e se false procede ad eseguire le linee successive;

linee 084-087: esegui il test_ACK() e verifica il codice restituito, in caso di test positivo richiami la funzione display() e attendi 100 millisecondi;

linea 089: richiama la funzione copy_id() definita alla linea 093;

linea 093: definisci la prima delle funzioni personalizzate dello sketch copy_id() richiamata dalla loop();

linea 095: crea due variabili di tipo integer ai e oi che userai di seguito;

linee 096-098: definisci un ciclo for con due variabili ( ai ed oi ) in cui ai parte da 19, la condizione di verifica è impostata solo sul valore massimo di oi (5) e sia ai sia oi vengono incrementate contemporaneamente. In questo modo inserirai i valori dell’indice 19,20,21,22 e 23 restituiti dalla funzione receive_ACK nella variabile old_id alla posizione 0,1,2,3,4;

linea 102: crea la funzione cmp_id() che ha lo scopo di comparare l’id ricevuto con l’old id memorizzato;

linee 105-109: inizia un ciclo a due variabili ed una condizione simile a quello definito alla linea 096 la cui finalità è descritta dalla condizione di if presente alla linea 106 in cui confronti i valori presenti nell’old_id con quelli del receive_id per gli ultimi 5 digit al primo digit differente la funzione restituisce 0 altrimenti restituisce 1;

linee 113-121: crea la funzione test_ACK() che restituisce true ( 1 ) se il confronto tra i valori ricevuti dall’nfc arduino ha i primi 19 digit compatibili con lo standard definito mediante la str_ACK() definita alla line 045;

linee 124-133: la funzione send_id() scrive sul monitor seriale il valore dell’id nfc letto dalla shield. Il funzionamento è molto semplice se conosci com funziona un ciclo for ed il monitor seriale di arduino;

linee 136-142: è una delle due funzioni di comunicazione seriale. la UART1_Send_Byte quando viene invocata invia 1 byte alla Serial1 ossia verso l’nfc arduino;

linee 145-149; la UART_Send_Byte è una funzione identica alla precedente il cui scopo è inviare il valore passato in input alla porta Serial;

linee 152-158: definisci la funzione read_ACK() che si occupa di impostare il valore dell’array receive_ACK per la lunghezza passata come argomento dello stesso e prelevati dalla Serial1;

linee 161-166: la funzione wake_card() si occupa di inviare byte per byte alla shield nfc arduino il codice di inizializzazione presente nell’array wake ed utilizzando la funzione UART1_Send_Byte;

linee 169-174: la funzione firmware invia il valore della variabile firmware all’NFC un byte alla volta mediante la funzione UART1_Send_Byte. Non viene richiamata da nessun’altra funzione in questo sketch;

linee 177-182: definisci la funzione send_tag() richiamata dalla loop() alla linea 080 il cui scopo è inviare il comando definito nella costante tag alla shield nfc arduino;

linee 185-191: è la funzione display() che si preoccupa di visualizzare sul monitor seriale i valori del tag letto dall’NFC scrivendolo byte per byte grazie alla funzione UART_Send_Byte;

Deduzioni dallo sketch

Osservando l’analisi linea per linea dello sketch avrai notato che i primi 19 byte del tag NFC si riferiscono alla tipologia di tag e che solo i restanti 5 sono considerati significativi per il riconoscimento del tag.

Questa informazione può tornarti utile nel momento in cui andrai a memorizzare i tag in un file o altro sistema in grado di eseguire il confronto tra il valore letto e quelli memorizzati.

Il video

Ho realizzato un video in cui puoi vedere diversi tipi di tag NFC ossia le chiavi che possono essere riconosciute dalla shield nfc arduino.

Il video mostra nelle prime righe il riconoscimento dei TAG e nella parte finale ho ripetuto la lettura dell’ultimo Tag Nfc arduino per controllare che il codice letto fosse sempre il medesimo.

Prima di inserire un commento, per favore, leggi il regolamento

Permanent link to this article: https://www.mauroalfieri.it/elettronica/nfc-arduino.html

17 pings

Skip to comment form

  1. […] passato hai letto dei miei test con una shield simile della DF Robot: NFC Arduino in cui avevo testato la mia shield NFC prodotta dalla DF […]

Lascia un commento

Your email address will not be published.

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.