0% found this document useful (0 votes)
118 views

Rfid

This document contains Arduino code for a RFID access control system using an MFRC522 RFID reader module and LCD display. It includes functions to initialize the hardware, read RFID tags, display the tag ID on the LCD, and control a buzzer and door lock based on whether the tag is authorized. If an authorized tag is detected, it unlocks the door and displays a welcome message. Otherwise, it sounds an alarm and denies access.

Uploaded by

Miki Sauvester
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
118 views

Rfid

This document contains Arduino code for a RFID access control system using an MFRC522 RFID reader module and LCD display. It includes functions to initialize the hardware, read RFID tags, display the tag ID on the LCD, and control a buzzer and door lock based on whether the tag is authorized. If an authorized tag is detected, it unlocks the door and displays a welcome message. Otherwise, it sounds an alarm and denies access.

Uploaded by

Miki Sauvester
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 15

#include <SPI.

h>
#include <MFRC522.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);
int pinBuzzer = 8;
int doorLock = 6;
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

void setup()
{
Serial.begin(9600); // Initiate a serial communication
SPI.begin(); // Initiate SPI bus
mfrc522.PCD_Init(); // Initiate MFRC522

pinMode(pinBuzzer, OUTPUT);
pinMode(doorLock, OUTPUT);
digitalWrite(pinBuzzer, HIGH);

// set up the LCD's number of columns and rows:


lcd.begin(20, 4);
lcd.backlight();
delay(250);
lcd.noBacklight();
delay(250);
lcd.backlight();
lcd.clear();
lcd.setCursor(0,1);
lcd.print(" Insert Your");
delay(300);
lcd.setCursor(0,2);
lcd.print(" ID CARD");
delay(500);
}
void loop()
{
lcd.display();
delay(500);

// Look for new cards


if ( ! mfrc522.PICC_IsNewCardPresent())
{
return;
}
//Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial())
{
return;
}
//Show UID on serial monitor
lcd.setCursor(0,0);
Serial.print("UID tag :");
lcd.print("UID:");
String content= "";
byte letter;
for (byte i = 0; i < mfrc522.uid.size; i++)
{
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i], HEX);
lcd.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
lcd.print(mfrc522.uid.uidByte[i], HEX);
content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
content.concat(String(mfrc522.uid.uidByte[i], HEX));
}
lcd.print(" Message : ");
content.toUpperCase();
if (content.substring(1) =="50 2B 06 10") //rubah UID nya disini sesuai ID card yang boleh di
access
{
lcd.clear();
lcd.setCursor(0,1);
lcd.print(" Hai Jogjarobotika");
delay(300);
lcd.setCursor(0,2);
lcd.print(" Selamat Datang");
delay(500);
digitalWrite(pinBuzzer, LOW);
delay(500);
digitalWrite(pinBuzzer, HIGH);
delay(500);
digitalWrite(doorLock, HIGH);
lcd.clear();
lcd.setCursor (0,1);
lcd.print(F(" Silahkan Masuk "));
lcd.setCursor (0,2);
lcd.print(F(" AutoLock after "));
for(int i=5; i>0; i--)
{
lcd.setCursor (17,2); lcd.print(i);
delay (1000);
}
digitalWrite(doorLock, LOW);
digitalWrite(pinBuzzer, HIGH);
lcd.clear();
lcd.setCursor(0,1);
lcd.print(" Insert Your");
delay(300);
lcd.setCursor(0,2);
lcd.print(" ID CARD");
delay(500);
}

else {
lcd.setCursor(0,2);
lcd.clear();
lcd.print(" Access Denied ");
delay(500);
digitalWrite(pinBuzzer, HIGH);
delay(300);
digitalWrite(pinBuzzer, LOW);
delay(300);
digitalWrite(pinBuzzer, HIGH);
delay(300);
digitalWrite(pinBuzzer, LOW);
delay(300);
digitalWrite(pinBuzzer, HIGH);
delay(300);
digitalWrite(pinBuzzer, LOW);
delay(300);
digitalWrite(pinBuzzer, HIGH);
delay(1000);

lcd.clear();
lcd.setCursor(0,1);
lcd.print(" Insert Your");
delay(300);
lcd.setCursor(0,2);
lcd.print(" ID CARD");
delay(500);
}
}

Yyyy

#include <Arduino.h>
#include "MFRC522.h"

/////////////////////////////////////////////////////////////////////////////////////
// Functions for setting up the Arduino
/////////////////////////////////////////////////////////////////////////////////////
/**
* Constructor.
*/
MFRC522::MFRC522(): MFRC522(SS, UINT8_MAX) { // SS is defined in pins_arduino.h,
UINT8_MAX means there is no connection from Arduino to MFRC522's reset and power down
input
} // End constructor

/**
* Constructor.
* Prepares the output pins.
*/
MFRC522::MFRC522( byte resetPowerDownPin ///< Arduino pin connected to MFRC522's
reset and power down input (Pin 6, NRSTPD, active low). If there is no connection from the CPU
to NRSTPD, set this to UINT8_MAX. In this case, only soft reset will be used in PCD_Init().
): MFRC522(SS, resetPowerDownPin) { // SS is defined in pins_arduino.h
} // End constructor

/**
* Constructor.
* Prepares the output pins.
*/
MFRC522::MFRC522( byte chipSelectPin, ///< Arduino pin connected to MFRC522's SPI
slave select input (Pin 24, NSS, active low)
byte resetPowerDownPin ///< Arduino pin connected to MFRC522's
reset and power down input (Pin 6, NRSTPD, active low). If there is no connection from the CPU
to NRSTPD, set this to UINT8_MAX. In this case, only soft reset will be used in PCD_Init().
){
_chipSelectPin = chipSelectPin;
_resetPowerDownPin = resetPowerDownPin;
} // End constructor

/////////////////////////////////////////////////////////////////////////////////////
// Basic interface functions for communicating with the MFRC522
/////////////////////////////////////////////////////////////////////////////////////

/**
* Writes a byte to the specified register in the MFRC522 chip.
* The interface is described in the datasheet section 8.1.2.
*/
void MFRC522::PCD_WriteRegister( PCD_Register reg, ///< The register to write to. One of the
PCD_Register enums.
byte value ///< The value to write.
){
SPI.beginTransaction(SPISettings(MFRC522_SPICLOCK, MSBFIRST, SPI_MODE0)); //
Set the settings to work with SPI bus
digitalWrite(_chipSelectPin, LOW); // Select slave
SPI.transfer(reg); // MSB == 0 is for writing. LSB is not used in
address. Datasheet section 8.1.2.3.
SPI.transfer(value);
digitalWrite(_chipSelectPin, HIGH); // Release slave again
SPI.endTransaction(); // Stop using the SPI bus
} // End PCD_WriteRegister()

/**
* Writes a number of bytes to the specified register in the MFRC522 chip.
* The interface is described in the datasheet section 8.1.2.
*/
void MFRC522::PCD_WriteRegister( PCD_Register reg, ///< The register to write to. One of the
PCD_Register enums.
byte count, ///< The number of bytes to
write to the register
byte *values ///< The values to write. Byte
array.
){
SPI.beginTransaction(SPISettings(MFRC522_SPICLOCK, MSBFIRST, SPI_MODE0)); //
Set the settings to work with SPI bus
digitalWrite(_chipSelectPin, LOW); // Select slave
SPI.transfer(reg); // MSB == 0 is for writing. LSB is not used in
address. Datasheet section 8.1.2.3.
for (byte index = 0; index < count; index++) {
SPI.transfer(values[index]);
}
digitalWrite(_chipSelectPin, HIGH); // Release slave again
SPI.endTransaction(); // Stop using the SPI bus
} // End PCD_WriteRegister()

/**
* Reads a byte from the specified register in the MFRC522 chip.
* The interface is described in the datasheet section 8.1.2.
*/
byte MFRC522::PCD_ReadRegister( PCD_Register reg ///< The register to read from. One of
the PCD_Register enums.
){
byte value;
SPI.beginTransaction(SPISettings(MFRC522_SPICLOCK, MSBFIRST, SPI_MODE0)); //
Set the settings to work with SPI bus
digitalWrite(_chipSelectPin, LOW); // Select slave
SPI.transfer(0x80 | reg); // MSB == 1 is for reading. LSB is not used in
address. Datasheet section 8.1.2.3.
value = SPI.transfer(0); // Read the value back. Send 0 to stop reading.
digitalWrite(_chipSelectPin, HIGH); // Release slave again
SPI.endTransaction(); // Stop using the SPI bus
return value;
} // End PCD_ReadRegister()

/**
* Reads a number of bytes from the specified register in the MFRC522 chip.
* The interface is described in the datasheet section 8.1.2.
*/
void MFRC522::PCD_ReadRegister( PCD_Register reg, ///< The register to read from. One of
the PCD_Register enums.
byte count, ///< The number of bytes to read
byte *values, ///< Byte array to store the values in.
byte rxAlign ///< Only bit positions rxAlign..7 in
values[0] are updated.
){
if (count == 0) {
return;
}
//Serial.print(F("Reading ")); Serial.print(count); Serial.println(F(" bytes from register."));
byte address = 0x80 | reg; // MSB == 1 is for reading. LSB is not used in
address. Datasheet section 8.1.2.3.
byte index = 0; // Index in values array.
SPI.beginTransaction(SPISettings(MFRC522_SPICLOCK, MSBFIRST, SPI_MODE0)); //
Set the settings to work with SPI bus
digitalWrite(_chipSelectPin, LOW); // Select slave
count--; // One read is performed outside of the loop
SPI.transfer(address); // Tell MFRC522 which address we want to read
if (rxAlign) { // Only update bit positions rxAlign..7 in values[0]
// Create bit mask for bit positions rxAlign..7
byte mask = (0xFF << rxAlign) & 0xFF;
// Read value and tell that we want to read the same address again.
byte value = SPI.transfer(address);
// Apply mask to both current value of values[0] and the new data in value.
values[0] = (values[0] & ~mask) | (value & mask);
index++;
}
while (index < count) {
values[index] = SPI.transfer(address); // Read value and tell that we want to read the
same address again.
index++;
}
values[index] = SPI.transfer(0); // Read the final byte. Send 0 to stop reading.
digitalWrite(_chipSelectPin, HIGH); // Release slave again
SPI.endTransaction(); // Stop using the SPI bus
} // End PCD_ReadRegister()

/**
* Sets the bits given in mask in register reg.
*/
void MFRC522::PCD_SetRegisterBitMask( PCD_Register reg, ///< The register to update. One
of the PCD_Register enums.
byte mask ///< The bits to set.
){
byte tmp;
tmp = PCD_ReadRegister(reg);
PCD_WriteRegister(reg, tmp | mask); // set bit mask
} // End PCD_SetRegisterBitMask()

/**
* Clears the bits given in mask from register reg.
*/
void MFRC522::PCD_ClearRegisterBitMask( PCD_Register reg, ///< The register to update.
One of the PCD_Register enums.
byte mask ///< The bits to clear.
){
byte tmp;
tmp = PCD_ReadRegister(reg);
PCD_WriteRegister(reg, tmp & (~mask)); // clear bit mask
} // End PCD_ClearRegisterBitMask()

/**
* Use the CRC coprocessor in the MFRC522 to calculate a CRC_A.
*
* @return STATUS_OK on success, STATUS_??? otherwise.
*/
MFRC522::StatusCode MFRC522::PCD_CalculateCRC( byte *data, ///< In: Pointer to
the data to transfer to the FIFO for CRC calculation.
byte length, ///< In: The number of
bytes to transfer.
byte *result ///< Out: Pointer to
result buffer. Result is written to result[0..1], low byte first.
){
PCD_WriteRegister(CommandReg, PCD_Idle); // Stop any active command.
PCD_WriteRegister(DivIrqReg, 0x04); // Clear the CRCIRq interrupt request
bit
PCD_WriteRegister(FIFOLevelReg, 0x80); // FlushBuffer = 1, FIFO initialization
PCD_WriteRegister(FIFODataReg, length, data); // Write data to the FIFO
PCD_WriteRegister(CommandReg, PCD_CalcCRC); // Start the calculation

// Wait for the CRC calculation to complete. Each iteration of the while-loop takes 17.73μs.
// TODO check/modify for other architectures than Arduino Uno 16bit

// Wait for the CRC calculation to complete. Each iteration of the while-loop takes 17.73us.
for (uint16_t i = 5000; i > 0; i--) {
// DivIrqReg[7..0] bits are: Set2 reserved reserved MfinActIRq reserved CRCIRq
reserved reserved
byte n = PCD_ReadRegister(DivIrqReg);
if (n & 0x04) { // CRCIRq bit set -
calculation done
PCD_WriteRegister(CommandReg, PCD_Idle); // Stop calculating CRC for new
content in the FIFO.
// Transfer the result from the registers to the result buffer
result[0] = PCD_ReadRegister(CRCResultRegL);
result[1] = PCD_ReadRegister(CRCResultRegH);
return STATUS_OK;
}
}
// 89ms passed and nothing happend. Communication with the MFRC522 might be down.
return STATUS_TIMEOUT;
} // End PCD_CalculateCRC()
/////////////////////////////////////////////////////////////////////////////////////
// Functions for manipulating the MFRC522
/////////////////////////////////////////////////////////////////////////////////////

/**
* Initializes the MFRC522 chip.
*/
void MFRC522::PCD_Init() {
bool hardReset = false;

// Set the chipSelectPin as digital output, do not select the slave yet
pinMode(_chipSelectPin, OUTPUT);
digitalWrite(_chipSelectPin, HIGH);

// If a valid pin number has been set, pull device out of power down / reset state.
if (_resetPowerDownPin != UNUSED_PIN) {
// First set the resetPowerDownPin as digital input, to check the MFRC522 power down
mode.
pinMode(_resetPowerDownPin, INPUT);

if (digitalRead(_resetPowerDownPin) == LOW) { // The MFRC522 chip is in power


down mode.
pinMode(_resetPowerDownPin, OUTPUT); // Now set the
resetPowerDownPin as digital output.
digitalWrite(_resetPowerDownPin, LOW); // Make sure we have a clean
LOW state.
delayMicroseconds(2); // 8.8.1 Reset timing requirements says
about 100ns. Let us be generous: 2μsl
digitalWrite(_resetPowerDownPin, HIGH); // Exit power down mode. This
triggers a hard reset.
// Section 8.8.2 in the datasheet says the oscillator start-up time is the start up time
of the crystal + 37,74μs. Let us be generous: 50ms.
delay(50);
hardReset = true;
}
}

if (!hardReset) { // Perform a soft reset if we haven't triggered a hard reset above.


PCD_Reset();
}

// Reset baud rates


PCD_WriteRegister(TxModeReg, 0x00);
PCD_WriteRegister(RxModeReg, 0x00);
// Reset ModWidthReg
PCD_WriteRegister(ModWidthReg, 0x26);

// When communicating with a PICC we need a timeout if something goes wrong.


// f_timer = 13.56 MHz / (2*TPreScaler+1) where TPreScaler =
[TPrescaler_Hi:TPrescaler_Lo].
// TPrescaler_Hi are the four low bits in TModeReg. TPrescaler_Lo is TPrescalerReg.
PCD_WriteRegister(TModeReg, 0x80); // TAuto=1; timer starts automatically
at the end of the transmission in all communication modes at all speeds
PCD_WriteRegister(TPrescalerReg, 0xA9); // TPreScaler =
TModeReg[3..0]:TPrescalerReg, ie 0x0A9 = 169 => f_timer=40kHz, ie a timer period of 25μs.
PCD_WriteRegister(TReloadRegH, 0x03); // Reload timer with 0x3E8 = 1000, ie
25ms before timeout.
PCD_WriteRegister(TReloadRegL, 0xE8);

PCD_WriteRegister(TxASKReg, 0x40); // Default 0x00. Force a 100 % ASK


modulation independent of the ModGsPReg register setting
PCD_WriteRegister(ModeReg, 0x3D); // Default 0x3F. Set the preset value for the CRC
coprocessor for the CalcCRC command to 0x6363 (ISO 14443-3 part 6.2.4)
PCD_AntennaOn(); // Enable the antenna driver pins TX1 and
TX2 (they were disabled by the reset)
} // End PCD_Init()

/**
* Initializes the MFRC522 chip.
*/
void MFRC522::PCD_Init( byte resetPowerDownPin ///< Arduino pin connected to
MFRC522's reset and power down input (Pin 6, NRSTPD, active low)
){
PCD_Init(SS, resetPowerDownPin); // SS is defined in pins_arduino.h
} // End PCD_Init()

/**
* Initializes the MFRC522 chip.
*/
void MFRC522::PCD_Init( byte chipSelectPin, ///< Arduino pin connected to MFRC522's
SPI slave select input (Pin 24, NSS, active low)
byte resetPowerDownPin ///< Arduino pin connected to
MFRC522's reset and power down input (Pin 6, NRSTPD, active low)
){
_chipSelectPin = chipSelectPin;
_resetPowerDownPin = resetPowerDownPin;
// Set the chipSelectPin as digital output, do not select the slave yet
PCD_Init();
} // End PCD_Init()

/**
* Performs a soft reset on the MFRC522 chip and waits for it to be ready again.
*/
void MFRC522::PCD_Reset() {
PCD_WriteRegister(CommandReg, PCD_SoftReset); // Issue the SoftReset command.
// The datasheet does not mention how long the SoftRest command takes to complete.
// But the MFRC522 might have been in soft power-down mode (triggered by bit 4 of
CommandReg)
// Section 8.8.2 in the datasheet says the oscillator start-up time is the start up time of the
crystal + 37,74μs. Let us be generous: 50ms.
uint8_t count = 0;
do {
// Wait for the PowerDown bit in CommandReg to be cleared (max 3x50ms)
delay(50);
} while ((PCD_ReadRegister(CommandReg) & (1 << 4)) && (++count) < 3);
} // End PCD_Reset()

/**
* Turns the antenna on by enabling pins TX1 and TX2.
* After a reset these pins are disabled.
*/
void MFRC522::PCD_AntennaOn() {
byte value = PCD_ReadRegister(TxControlReg);
if ((value & 0x03) != 0x03) {
PCD_WriteRegister(TxControlReg, value | 0x03);
}
} // End PCD_AntennaOn()

/**
* Turns the antenna off by disabling pins TX1 and TX2.
*/
void MFRC522::PCD_AntennaOff() {
PCD_ClearRegisterBitMask(TxControlReg, 0x03);
} // End PCD_AntennaOff()

/**
* Get the current MFRC522 Receiver Gain (RxGain[2:0]) value.
* See 9.3.3.6 / table 98 in http://www.nxp.com/documents/data_sheet/MFRC522.pdf
* NOTE: Return value scrubbed with (0x07<<4)=01110000b as RCFfgReg may use reserved
bits.
*
* @return Value of the RxGain, scrubbed to the 3 bits used.
*/
byte MFRC522::PCD_GetAntennaGain() {
return PCD_ReadRegister(RFCfgReg) & (0x07<<4);
} // End PCD_GetAntennaGain()

/**
* Set the MFRC522 Receiver Gain (RxGain) to value specified by given mask.
* See 9.3.3.6 / table 98 in http://www.nxp.com/documents/data_sheet/MFRC522.pdf
* NOTE: Given mask is scrubbed with (0x07<<4)=01110000b as RCFfgReg may use reserved
bits.
*/
void MFRC522::PCD_SetAntennaGain(byte mask) {
if (PCD_GetAntennaGain() != mask) { // only bother if there is a
change
PCD_ClearRegisterBitMask(RFCfgReg, (0x07<<4)); // clear needed to allow 000
pattern
PCD_SetRegisterBitMask(RFCfgReg, mask & (0x07<<4));// only set RxGain[2:0] bits
}
} // End PCD_SetAntennaGain()

/**
* Performs a self-test of the MFRC522
* See 16.1.1 in http://www.nxp.com/documents/data_sheet/MFRC522.pdf
*
* @return Whether or not the test passed. Or false if no firmware reference is available.
*/
bool MFRC522::PCD_PerformSelfTest() {
// This follows directly the steps outlined in 16.1.1
// 1. Perform a soft reset.
PCD_Reset();

// 2. Clear the internal buffer by writing 25 bytes of 00h


byte ZEROES[25] = {0x00};
PCD_WriteRegister(FIFOLevelReg, 0x80); // flush the FIFO buffer
PCD_WriteRegister(FIFODataReg, 25, ZEROES); // write 25 bytes of 00h to FIFO
PCD_WriteRegister(CommandReg, PCD_Mem); // transfer to internal buffer

// 3. Enable self-test
PCD_WriteRegister(AutoTestReg, 0x09);

// 4. Write 00h to FIFO buffer


PCD_WriteRegister(FIFODataReg, 0x00);
// 5. Start self-test by issuing the CalcCRC command
PCD_WriteRegister(CommandReg, PCD_CalcCRC);

// 6. Wait for self-test to complete


byte n;
for (uint8_t i = 0; i < 0xFF; i++) {
// The datasheet does not specify exact completion condition except
// that FIFO buffer should contain 64 bytes.
// While selftest is initiated by CalcCRC command
// it behaves differently from normal CRC computation,
// so one can't reliably use DivIrqReg to check for completion.
// It is reported that some devices does not trigger CRCIRq flag
// during selftest.
n = PCD_ReadRegister(FIFOLevelReg);
if (n >= 64) {
break;
}
}
PCD_WriteRegister(CommandReg, PCD_Idle); // Stop calculating CRC for new
content in the FIFO.

// 7. Read out resulting 64 bytes from the FIFO buffer.


byte result[64];
PCD_ReadRegister(FIFODataReg, 64, result, 0);

// Auto self-test done


// Reset AutoTestReg register to be 0 again. Required for normal operation.
PCD_WriteRegister(AutoTestReg, 0x00);

// Determine firmware version (see section 9.3.4.8 in spec)


byte version = PCD_ReadRegister(VersionReg);

// Pick the appropriate reference values


const byte *reference;
switch (version) {
case 0x88: // Fudan Semiconductor FM17522 clone
reference = FM17522_firmware_reference;
break;
case 0x90: // Version 0.0
reference = MFRC522_firmware_referenceV0_0;
break;
case 0x91: // Version 1.0
reference = MFRC522_firmware_referenceV1_0;
break;
case 0x92: // Version 2.0
reference = MFRC522_firmware_referenceV2_0;
break;
default: // Unknown version
return false; // abort test
}

// Verify that the results match up to our expectations


for (uint8_t i = 0; i < 64; i++) {
if (result[i] != pgm_read_byte(&(reference[i]))) {
return false;
}
}

// Test passed; all is good.


return true;
} // End PCD_PerformSelfTest()

/////////////////////////////////////////////////////////////////////////////////////
// Power control
/////////////////////////////////////////////////////////////////////////////////////

//IMPORTANT NOTE!!!!
//Calling any other function that uses CommandReg will disable soft power down mode !!!
//For more details about power control, refer to the datasheet - page 33 (8.6)

void MFRC522::PCD_SoftPowerDown(){//Note : Only soft power down mode is available


throught software
byte val = PCD_ReadRegister(CommandReg); // Read state of the command register
val |= (1<<4);// set PowerDown bit ( bit 4 ) to 1
PCD_WriteRegister(CommandReg, val);//write new value to the command register
}

void MFRC522::PCD_SoftPowerUp(){
byte val = PCD_ReadRegister(CommandReg); // Read state of the command register
val &= ~(1<<4);// set PowerDown bit ( bit 4 ) to 0
PCD_WriteRegister(CommandReg, val);//write new value to the command register
// wait until PowerDown bit is cleared (this indicates end of wake up procedure)
const uint32_t timeout = (uint32_t)millis() + 500;// create timer for timeout (just in case)

while(millis()<=timeout){ // set timeout to 500 ms


val = PCD_ReadRegister(CommandReg);// Read state of the command register
if(!(val & (1<<4))){ // if powerdown bit is 0
break;// wake up procedure is finished
}
}
}

/////////////////////////////////////////////////////////////////////////////////////
// Functions for communicating with PICCs
/////////////////////////////////////////////////////////////////////////////////////

/**
* Executes the Transceive command.
* CRC validation can only be done if backData and backLen are specified.
*
* @return STATUS_OK on success, STATUS_??? otherwise.
*/
MFRC522::StatusCode MFRC522::PCD_TransceiveData( byte *sendData, ///< Pointer
to the data to transfer to the FIFO.
byte sendLen, ///< Number
of bytes to transfer to the FIFO.
byte *backData, ///<
nullptr or pointer to buffer if data should be read back after executing the command.
byte *backLen, ///< In:
Max number of bytes to write to *backData. Out: The number of bytes returned.
byte *validBits, ///< In/Out:
The number of valid bits in the last byte. 0 for 8 valid bits. Default nullptr.
byte rxAlign, ///< In:
Defines the bit position in backData[0] for the first bit received. Default 0.
bool checkCRC ///< In:
True => The last two bytes of the response is assumed to be a CRC_A that must be validated.
){
byte waitIRq = 0x30; // RxIRq and IdleIRq
return PCD_CommunicateWithPICC(PCD_Transceive, waitIRq, sendData, sendLen,
backData, backLen, validBits, rxAlign, checkCRC);
} // End PCD_Tr

You might also like