I bought the NFC module from DFRobot and I'm using their example program with some changes since I only want to read the UID of my tag. It works great with the tag that came with it but it doesn't recognize any of my NFC Whiztags (which contain a Topaz 512 chip).
Does anyone know how can I fix this?
This is my code:
#include <SoftwareSerial.h>
/*
# 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};
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) mySerial.write(args)
#define print1lnByte(args) mySerial.write(args),mySerial.println()
#else
#include "WProgram.h"
#define print1Byte(args) mySerial.print(args,BYTE)
#define print1lnByte(args) mySerial.println(args,BYTE)
#endif
SoftwareSerial mySerial(10, 11); // RX, TX
unsigned char myUID[12] = "70 89 7E 43";
void setup()
{
Serial.begin(9600); // open serial with PC
mySerial.begin(115200); //open mySerial with device
wake_card();
delay(200);
Serial.println("Scanning...");
}
void loop()
{
send_tag();
read_ACK(25);
delay(100);
if (test_ACK ()) {
copy_id ();
displayuid ();
delay (10000);
}
}
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];
}
}
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
mySerial.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 receive_ACK[]
unsigned char i;
for(i=0;i<temp;i++) {
receive_ACK[i]= mySerial.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 send_tag(void)
{//send tag[] to device
unsigned char i;
for(i=0;i<11;i++) //send command
UART1_Send_Byte(tag[i]);
}
void displayuid(void)
{//send receive_ACK[] to PC
unsigned char i;
for(i=0;i<4;i++) //send command
UART_Send_Byte(old_id[i]);
Serial.println();
}
//*********** end *************
Your reader module contains an NXP PN532 NFC transmission module IC. You currently use the following command to poll for tags:
tag = { 0x00, 0x00, 0xFF, 0x04, 0xFC, 0xD4, 0x4A, 0x01, 0x00, 0xE1, 0x00};
This command is an InListPassiveTarget command (command code D4 4A
) with the parameters
0x01
) and0x00
).Hence, you can only detect tags that speak the full type A protocol defined in ISO/IEC 14443-3 (including anti-collision). Such tags are, for instance,
The Whiztags contain a Topaz 512 chip (which is an NFC Forum Type 1 tag). This tag type only partially implements ISO/IEC 14443 Type A (anti-collision mechanism not supported). Consequently, the above polling command won't enumerate such tags. Instead, you would need to switch the BrTy parameter to "Innovision Jewel tag at 106 kbps" (0x04
). The modified command (including the update checksum byte) would look like this:
tag = { 0x00, 0x00, 0xFF, 0x04, 0xFC, 0xD4, 0x4A, 0x01, 0x04, 0xDD, 0x00};
You can find further details in the PN532 user manual.