I am trying to find out if a PICC (RFID tag) still present on MFRC522 RFID reader.
/**
* Transmits a Wake-UP command, Type A. Invites PICCs in state IDLE and HALT to go to READY(*) and prepare for anticollision or selection. 7 bit frame.
* Beware: When two PICCs are in the field at the same time I often get STATUS_TIMEOUT - probably due do bad antenna design.
*
* @return STATUS_OK on success, STATUS_??? otherwise.
*/
byte MFRC522::PICC_WakeupA( byte *bufferATQA, ///< The buffer to store the ATQA (Answer to request) in
byte *bufferSize ///< Buffer size, at least two bytes. Also number of bytes returned if STATUS_OK.
) {
return PICC_REQA_or_WUPA(PICC_CMD_WUPA, bufferATQA, bufferSize);
} // End PICC_WakeupA()
int getID() {
if ( ! mfrc522.PICC_IsNewCardPresent()) { //If a new PICC placed to RFID reader continue
return 0;
}
if ( ! mfrc522.PICC_ReadCardSerial()) { //Since a PICC placed get Serial and continue
return 0;
}
for (int i = 0; i < mfrc522.uid.size; i++) { // for size of uid.size write uid.uidByte to readCard
readCard[i] = mfrc522.uid.uidByte[i];
}
mfrc522.PICC_HaltA(); // Stop reading
return 1;
}
and program looks EEPROM if readCard is known or not. If its a known card i want to run a program that does 1 wake up PICC which was previously Halted 2 if PICC still on reader do nothing (return 0) 3 else get back main loop (return 1) ```
*void RelayOn() {
do {
still = stillPresent();
delay(1000);
}
while (!still); // Do nothing until PICC removed
}
int stillPresent() {
1 ????
2 ????
3 ????
}* ``` I tried checking UID again and again, but this seemed stupid because of EEPROM wears out Thank you for your suggestions.
I tried checking UID again and again, but this seemed stupid because of EEPROM wears out
Writing to EEPROM wears it out. Reading from it does not. Of course, neither is necessary. Write only when there is new data (that is the value to write is different from what is there now). Read once and remember what you read.
I can't understand how WakeupA command works.
Does it matter that you understand it? Presumably, you are interested in having the function do something. So, just call it.
Not understanding the arguments it needs is a different story. The argument type is known - pointer to byte - which means that you need to define a byte array where the function will store some data. That data may, or more likely, may not, be of interest. The size of the array is up to you, but the comment suggests that 2 bytes is the minimum, which suggests that the function writes "OK" or "KO" there, depending on its ability to perform the requested function. Try a 10 byte array, first. See what the function actually writes into the array. Then, adjust the size of the array if needed.
Thank you for your reply. I understood, why i need byte array for buffer. I was confused by the how HaltA command works (i just call without checking Status if its succeed or failed)
I still cannot wake up PICC with this code,
#include <SPI.h> // RC522 Module uses SPI protocol
#include <MFRC522.h> // Library for Mifare RC522 D
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
void setup() {
// put your setup code here, to run once:
Serial.begin(9600); // Initialize serial communications with PC
SPI.begin(); // MFRC522 Hardware uses SPI protocol
mfrc522.PCD_Init(); // Initialize MFRC522 Hardware
}
void loop() {
byte bufferATQA[10];
byte bufferSize[10];
// put your main code here, to run repeatedly:
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent()) {
Serial.println("There is no PICC");
return;
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) {
Serial.println("Cannot get UID");
return;
}
Serial.println("Just got UID");
mfrc522.PICC_HaltA();
Serial.println("PICC Halted");
delay(100);
Serial.println("Im trying to Wake Up Halted PICC");
mfrc522.PICC_WakeupA(bufferATQA, bufferSize); //wake up PICC which was previously Halted
delay(100);
mfrc522.PICC_RequestA(bufferATQA, bufferSize);
delay(100);
Serial.println("PICC Should Wake Up");
delay(100);
if ( ! mfrc522.PICC_ReadCardSerial()) {
Serial.println("Tried get UID but no luck");
}
delay(1000);
}
byte MFRC522::PICC_HaltA() {
byte result;
byte buffer[4];
// Build command buffer
buffer[0] = PICC_CMD_HLTA;
buffer[1] = 0;
// Calculate CRC_A
result = PCD_CalculateCRC(buffer, 2, &buffer[2]);
if (result != STATUS_OK) {
return result;
}
// Send the command.
// The standard says:
// If the PICC responds with any modulation during a period of 1 ms after the end of the frame containing the
// HLTA command, this response shall be interpreted as 'not acknowledge'.
// We interpret that this way: Only STATUS_TIMEOUT is an success.
result = PCD_TransceiveData(buffer, sizeof(buffer), NULL, 0);
if (result == STATUS_TIMEOUT) {
return STATUS_OK;
}
if (result == STATUS_OK) { // That is ironically NOT ok in this case ;-)
return STATUS_ERROR;
}
return result;
} // End PICC_HaltA()
/**
* Transmits a Wake-UP command, Type A. Invites PICCs in state IDLE and HALT to go to READY(*) and prepare for anticollision or selection. 7 bit frame.
* Beware: When two PICCs are in the field at the same time I often get STATUS_TIMEOUT - probably due do bad antenna design.
*
* @return STATUS_OK on success, STATUS_??? otherwise.
*/
byte MFRC522::PICC_WakeupA( byte *bufferATQA, ///< The buffer to store the ATQA (Answer to request) in
byte *bufferSize ///< Buffer size, at least two bytes. Also number of bytes returned if STATUS_OK.
) {
return PICC_REQA_or_WUPA(PICC_CMD_WUPA, bufferATQA, bufferSize);
} // End PICC_WakeupA()
/**
* Transmits REQA or WUPA commands.
* Beware: When two PICCs are in the field at the same time I often get STATUS_TIMEOUT - probably due do bad antenna design.
*
* @return STATUS_OK on success, STATUS_??? otherwise.
*/
byte MFRC522::PICC_REQA_or_WUPA( byte command, ///< The command to send - PICC_CMD_REQA or PICC_CMD_WUPA
byte *bufferATQA, ///< The buffer to store the ATQA (Answer to request) in
byte *bufferSize ///< Buffer size, at least two bytes. Also number of bytes returned if STATUS_OK.
) {
byte validBits;
byte status;
if (bufferATQA == NULL || *bufferSize < 2) { // The ATQA response is 2 bytes long.
return STATUS_NO_ROOM;
}
PCD_ClearRegisterBitMask(CollReg, 0x80); // ValuesAfterColl=1 => Bits received after collision are cleared.
validBits = 7; // For REQA and WUPA we need the short frame format - transmit only 7 bits of the last (and only) byte. TxLastBits = BitFramingReg[2..0]
status = PCD_TransceiveData(&command, 1, bufferATQA, bufferSize, &validBits);
if (status != STATUS_OK) {
return status;
}
if (*bufferSize != 2 || validBits != 0) { // ATQA must be exactly 16 bits.
return STATUS_ERROR;
}
return STATUS_OK;
} // End PICC_REQA_or_WUPA()
have you got the right answer to this yet, im mnew to arduino and im trying to find the same code, can you help me out please, or tell me if you coul do it, if you coul doit i can so please et back on this message, appreciate it
mfrc522.MIFARE_UnbrickUidSector(false); // Not sure if this is needed, but it works so I will leave it
byte bufferATQA[2];
byte bufferSize = sizeof(bufferATQA);
mfrc522.PICC_WakeupA(bufferATQA, &bufferSize);
I use this instead of PICC_IsNewCard() and it solved my problem.