Libelium's library
It is mandatory to include the RFID library when using this module. The following line must be introduced at the beginning of the code:
1
#include <WaspRFID13.h>
Copied!
Waspmote's API RFID/NFC files:
  • WaspRFID13.cpp
  • WaspRFID13.h
API functions
  • Private functions:
    The following functions are executed inside the API functions. In normal conditions, the user must NOT manage or use them.
Function
Brief description
bool configureSAM(void);
set internal parameters of the PN532
sendTX(uint8_t *dataTX, uint8_t length, uint8_t outLength);
Send data stored in dataTX
getACK(void);
Wait for ACK response
waitResponse(void);*
Wait the response of the module
getData(uint8_t outLength);
Get data from the module
checkSum(uint8_t *dataTX);
Calculates the checksum
uint8_t lengthCheckSum(uint8_t *dataTX);
Calculates the length checksum
*To avoid the hang of the module this function will wait for 5 seconds approximately. If no tag is detected, the program will continue after this time. The waiting time can be configured in the library.

Library constructor

It is the class constructor. It is only executed inside the API's function init().
  • Public functions:
    The following functions are public and therefore they can be executed in the loop() or setup() functions. They provide the tools to perform all the features of the RFID/NFC module.
Function
Brief description
OFF()
switches the module off
ON(socket)
switches the module on, in one of the 2 sockets
init(UID, ATQ)
inits the module, configures it and searches for new cards
authenticate(UID, ad, key)
authenticates one card’s sector
bool getFirmware(void)
The PN532 sends back the version of the embedded firmware.
read(ad ,*data)
reads one card’s block
readWithAuth(UID, key, *data, ad)
authenticates one card's sector and reads one block
write(ad, *data)
writes one card’s block
writeWithAuth(UID, key, *data, ad)
authenticates one card's sector and writes one block
writeAndCheck(*data, ad)
writes one card's block and checks that
writeAndCheckWithAuth(UID, key, *data, ad)
authenticates one card's sector, writes one block and checks that
uint8_t powerDown(void)
put the module into Power Down mode
wakeUp(void)
wake up from power dowm mode.
print( *data, length)
print data stored in vectors
setKeys(UID, keyOld, keyA, keyB, cfg, data, ad
changes both keys and access conditions to one card's sector
equalUIDs(UID1, UID2)
compares 2 UIDs
searchUID(vCards, UID, nCards)
searches one UID inside one group of UIDs
string2vector(inp, outp)
converts from a string to a uint8_t vector
vector2int(*inp)
converts from a uint8_t vector to a integer

Switching the module on

This function takes the RFID/NFC module out of the power-down mode by starting the wake up procedure.
If you connected the RFID/NFC module into the usual XBee socket, please use SOCKET0; if you connected the RFID/NFC module into the Expansion Board, you must use SOCKET1.
Example of use:
1
{
2
RFID13.ON(SOCKET0); // switches the module on with the socket 0 (the normal socket, without
3
// using the Expansion Board)
4
}
Copied!
https://development.libelium.com/RFID1356-01-basic-example
development.libelium.com

Switching the module off

This function takes the RFID/NFC module to the software power-down mode.
Example of use:
1
{
2
RFID13.OFF(); // switches the module off
3
}
Copied!
https://development.libelium.com/RFID1356-01-basic-example
development.libelium.com

Initiating the module

This function initializes the necessary variables, requests if there is an ISO/IEC 14443-A card in the field, does the anti-collision loop and selects the card to operate.
This function is enough for those applications which just require to get the UID of cards, since most of the ISO/IEC 14443-A processes are executed inside.
It is highly advised to execute this function in the beginning of each loop, just as shown in any of the examples. Even if the module is already initialized, it is good to start from the same point every time.
This function initializes many internal registers and variables. All the settings are optimized for the best operation. Changing those settings may result in a defective operation.
Example of use:
1
{
2
uint8_t state; // stores the status of the executed command
3
uint8_t ATQ[2]; // stores the ATQ-A (answer to request, type 14443- A). Generally stored in a
4
// bigger buffer (16B)
5
uint8_t UID[4]; // stores the UID (unique identification) of a card
6
...
7
state = RFID13.init(UID, ATQ); // The goal of this command is to detect as many targets // (maximum MaxTg) as possible in passive mode.
8
}
Copied!
https://development.libelium.com/RFID1356-01-basic-example
development.libelium.com

Authenticating a sector

This function authenticates a sector of the card thanks to the key or password. It is important to remark that before doing any read or write in a block, it is mandatory to authenticate us in it.
The only exception is the UID, which can be read without authentication; it is returned by the init() function.
One authentication is enough to validate all the 4 blocks in a sector.
Example of use:
1
{
2
uint8_t state; // stores the status of the executed command
3
uint8_t ATQ[2]; // stores the ATQ-A
4
uint8_t UID[4]; // stores the UID (unique identification) of a card
5
uint8_t key[6]; // stores the key or password
6
...
7
memset(key, 0xFF, 6); // the key by default, edit if needed
8
state = RFID13.init(UID, ATQ); // inits systems and look for cards
9
state = RFID13.authenticate(UID, 2, key); // authenticates block number 2 (all sector 0
10
// actually)of the selected card. State of the executed
11
// function is stored.
12
}
Copied!
https://development.libelium.com/RFID1356-01-basic-example
development.libelium.com

Reading a block

This function reads the 16 bytes stored in a block. This block must have been authenticated before reading.
Example of use:
1
{
2
uint8_t state; // stores the status of the executed command
3
uint8_t aux[16]; // auxiliar buffer
4
uint8_t UID[4]; // stores the UID (unique identification) of a card
5
uint8_t key[6]; // stores the key or password
6
...
7
memset(key, 0xFF, 6); // the key by default, edit if needed
8
state = RFID13.init(UID, aux); // inits systems and look for cards
9
state = RFID13.authenticate(UID, 2, key);// authenticates block 2
10
state = RFID13.read(2, aux);// reads the block 2. Data is stored in aux.
11
}
Copied!
https://development.libelium.com/RFID1356-02-read-all-blocks
development.libelium.com

Reading a block with authentication

This function authenticates a block of the card first, and then reads the 16 bytes stored in a block. This function is useful to do these 2 steps in just one.
Example of use:
1
{
2
uint8_t state; // stores the status of the executed command
3
uint8_t aux[16]; // auxiliar buffer
4
uint8_t UID[4]; // stores the UID (unique identification) of a card
5
uint8_t key[6]; // stores the key or password
6
...
7
memset(key, 0xFF, 6); // the key by default, edit if needed
8
state = RFID13.init(UID, aux); // inits systems and look for cards
9
state = RFID13.readWithAuth(UID, key, aux, 2); // authenticates block 2, then reads it. Data
10
// is stored in aux.
11
}
Copied!

Writing in a block

This function writes 16 bytes in a block. This block must have been authenticated before writing.
Example of use:
1
{
2
uint8_t state; // stores the status of the executed command
3
uint8_t aux[16]; // auxiliar buffer
4
uint8_t UID[4]; // stores the UID (unique identification) of a card
5
uint8_t key[6]; // stores the key or password
6
...
7
memset(key, 0xFF, 6); // the key by default, edit if needed
8
state = RFID13.init(UID, aux); // inits systems and look for cards
9
state = RFID13.authenticate(UID, 2, key);// authenticates block 2
10
memset(aux, 0x00, 16); // stores 0\'s in aux, 16 bytes
11
state = RFID13.write(2, aux); // writes the content of aux in block number 2
12
}
Copied!
https://development.libelium.com/RFID1356-03-bus-ticketing
development.libelium.com

Writing in a block with authentication

This function authenticates a block of the card first, and then writes 16 bytes in the block. This function is useful to do these 2 steps in just one.
Example of use:
1
{
2
uint8_t state; // stores the status of the executed command
3
uint8_t aux[16]; // auxiliar buffer
4
uint8_t UID[4]; // stores the UID (unique identification) of a card
5
uint8_t key[6]; // stores the key or password
6
...
7
memset(key, 0xFF, 6); // the key by default, edit if needed
8
state = RFID13.init(UID, aux); // inits systems and look for cards
9
memset(aux, 0x00, 16); // stores 0\'s in aux, 16 bytes
10
state = RFID13.writeWithAuth(UID, key, aux, 2); // authenticates block 2, then writes the
11
// content of aux in it
12
}
Copied!

Writing in a block and checking it

This function writes 16 bytes in a block, and then checks the correct data was written. This block must be authenticated before writing. This function is useful to do these 2 steps in just one.
Example of use:
1
{
2
uint8_t state; // stores the status of the executed command
3
uint8_t aux[16]; // auxiliar buffer
4
uint8_t UID[4]; // stores the UID (unique identification) of a card
5
uint8_t key[6]; // stores the key or password
6
...
7
memset(key, 0xFF, 6); // the key by default, edit if needed
8
state = RFID13.init(UID, aux); // inits systems and look for cards
9
state = RFID13.authenticate(UID, 2, key);// authenticates block 2
10
memset(aux, 0x00, 16); // stores 0\'s in aux, 16 bytes
11
state = RFID13.writeAndCheck(aux, 2); // writes the content of aux in block 2, then checks // its content is OK
12
}
Copied!

Writing in a block with authentication and checking it

This function authenticates a block of the card first, then writes 16 bytes in the block, and then checks the correct data was written. It is useful to do these 3 steps in just one.
Example of use:
1
{
2
uint8_t state; // stores the status of the executed command
3
uint8_t aux[16]; // auxiliar buffer
4
uint8_t UID[4]; // stores the UID (unique identification) of a card
5
uint8_t key[6]; // stores the key or password
6
...
7
memset(key, 0xFF, 6); // the key by default, edit if needed
8
state = RFID13.init(UID, aux); // inits systems and look for cards
9
state = RFID13.authenticate(UID, 2, key);// authenticates block 2
10
memset(aux, 0x00, 16); // stores 0\'s in aux, 16 bytes
11
writeAndCheckWithAuth(UID, key, aux, 2); // authenticates block 2, then writes the content of
12
// aux in it and checks its content is OK
13
}
Copied!

Setting keys in a sector

This function authenticates a block of the card first, then sets the new keys A and B, and the access bits for a sector. After that, it authenticates again and reads the trailer block. This function is useful to do these 4 steps in just one.
This function should be executed with care because if any of the internal functions is not successfully executed, then the sector could be damaged or left unaccessible. That is why it is highly recommended to read the output status in order to check if all the process was completed. Please place the card still and close distance from the RFID/NFC module's antenna when setting new keys; if the whole process is not properly completed, the access to that sector might be lost forever.
There are many options for the configuration of the access bits. We suggest to use the same options that the card has by default: {0xFF, 0x07, 0x80, 0x69}. With this configuration:
  • data blocks must be authenticated with the key A, and then can be read/written
  • key A can only be changed (written) after an authentication with key A
  • access bits can be read or written after an authentication with key A
  • in the sector trailer, the key B has no use and can be read/written after an authentication with key A. It can be used as additional storage space, for instance.
With any configuration, the key A can never be read (the module returns 0's instead of the key) for security reasons. As we can see, the key A of each RFID/NFC card is the master key and we must avoid losing or sharing this information.
Any new card is delivered with the same A and B keys by default: 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF. That is to say, 48 logic 1's.
As shown, the key length is 6 bytes so there are more than 2.8·10¹⁴ different possible passwords.
Example of use:
1
{
2
uint8_t state; // stores the status of the executed command
3
uint8_t aux[16]; // auxiliar buffer
4
uint8_t UID[4]; // stores the UID (unique identification) of a card
5
uint8_t keyA_old[6]; // stores the old key A
6
uint8_t keyA_new[6]; // stores the new key A
7
uint8_t keyB_new[6]; // stores the new key B
8
uint8_t config_new[4] = {0xFF, 0x07, 0x80, 0x00}; // same cfg
9
...
10
memset(keyA_old, 0xFF, 6); // the key by default, edit if needed
11
memset(keyA_new, 0x88, 6); // the new key A, edit if needed
12
memset(keyB_new, 0x99, 6); // the new key B, edit if needed
13
state = RFID13.init(UID, aux); // inits systems and look for cards
14
state = RFID13.setKeys(UID, keyA_old, keyA_new, keyB_new, config_new, aux, 2); //
15
// authenticates block 2, then writes the new trailer block, with new key A
16
// and B. The access bits are the same.
17
}
Copied!
https://development.libelium.com/RFID1356-05-password-simple
development.libelium.com

Powering down

This function puts the module into Power Down mode in order to save power consumption.
Example of use:
1
{
2
RFID.powerDown(); // After this function you must wake up the module.
3
}
Copied!

Waking up

This function wakes up the module from power down mode.
Example of use:
1
{
2
RFID.wakeUp(); //Wake Up from Power Down mode.
3
}
Copied!

Printing data

This function is very useful for viewing data content in vectors when you are debugging the code.
Example of use:
1
{
2
RFID.print(readData , 16); // Print data read and stored in readData vector in the serial monitor
3
}
Copied!
https://development.libelium.com/RFID1356-01-basic-example
development.libelium.com

Comparing UIDs

This function compares 2 UIDs to check if they are equal. It is useful to check if the UID we have just detected is the same than a predetermined UID. One logic application could be access control for a single person.
Example of use:
1
{
2
uint8_t state; // stores the status of the executed command
3
uint8_t ATQ[2]; // stores the ATQ-A
4
uint8_t UID[4]; // stores the UID (unique identification) of a card
5
uint8_t card[] = {0xXY, 0xXY, 0xXY, 0xXY}; // the UID of the card that we want to find
6
boolean tr = false;
7
...
8
state = RFID13.init(UID, ATQ); // inits systems and look for cards
9
tr = RFID13.equalUIDs(card, UID); // if the read UID is the same than the original card, tr
10
// will be true
11
}
Copied!
https://development.libelium.com/RFID1356-06-single-cards-counter
development.libelium.com

Searching a UID among a group of UIDs

This function tests if a certain UID is contained in a set or vector of UIDs. It is useful to check if the UID we have just detected is inside a predetermined set or group of UIDs. One logic application could be access control for a group of people.
Example of use:
1
{
2
#define nCards 3 // edit: number of possible cards
3
uint8_t state; // stores the status of the executed command
4
uint8_t ATQ[2]; // stores the ATQ-A
5
uint8_t UID[4]; // stores the UID (unique identification) of a card
6
// edit: vector with the UIDs of all the cards
7
uint8_t vCards [nCards*4] = {0xXY, 0xXY, 0xXY, 0xXY,
8
0xXY, 0xXY, 0xXY, 0xXY,
9
0xXY, 0xXY, 0xXY, 0xXY};
10
int card = -1; // stores the index of the present card
11
...
12
state = RFID13.init(UID, ATQ); // inits systems and look for cards
13
card = RFID13.searchUID(vCards, UID, nCards); // looks for the read card inside the data
14
// base. If so, it returns its index in the vector.
15
// If not, -1.
16
}
Copied!
https://development.libelium.com/RFID1356-06-single-cards-counter
development.libelium.com

Converting from a string to a uint8_t pointer

This function converts from a string to a pointer to uint8_t's. When we want to write a word or phrase in an RFID card, this function is useful to convert from ASCII code to the format the RFID/NFC module can understand.
Example of use:
1
{
2
uint8_t aux[16]; // auxiliar uint8_t pointer
3
char text [16]; // auxiliar string
4
int number = 3; // stores numbers
5
...
6
sprintf(text ,\"Its a test %d \", number*4); // add a number to a string (dynamic !! )
7
RFID13.string2vector(text, aux); // converts from string to a uint8_t pointer
8
}
Copied!
https://development.libelium.com/RFID1356-03-bus-ticketing
development.libelium.com

Converting from a uint8_t pointer to an integer

This function converts from a pointer to uint8_t's to an integer. When we want to read a number from an RFID card, this function is useful to convert from ASCII code to the format we can understand, an integer.
Example of use:
1
{
2
uint8_t aux[16] = {0x51, 0x52, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00,
3
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // auxiliar uint8_t pointer
4
int number = 0; // stores numbers
5
...
6
number = vector2int(aux); // converts from a uint8_t pointer to an integer
7
}
Copied!
https://development.libelium.com/RFID1356-03-bus-ticketing
development.libelium.com