Reputation: 356
We need to detect both the presence and absence of an RFID chip. We intend to do this by continually checking for a card. If one is there, we read it and confirm which it is. If there isn't one there after there previously was, then that is noted. It doesn't have to be super fast.
Arduino UNO + RC522 FRID reader, with MIFARE 1k cards. Using the library at: https://github.com/miguelbalboa/rfid
Contrary to what seems to be stated in example code found elsewhere, I am never able to read more than one card without resetting the RC522. As soon as it reads a card, and it's HALTed, no more cards can be read until the processor is reset. Other examples suggest this shouldn't be the case and a new card should immediately be readable on the next loop. Using:
void loop() {
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return;
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) {
return;
}
// Dump debug info about the card; PICC_HaltA() is automatically called
mfrc522.PICC_DumpDetailsToSerial(&(mfrc522.uid));
mfrc522.PICC_HaltA();
}
Successfully gives:
Card UID: B6 35 9F 46
Card SAK: 08
PICC type: MIFARE 1KB
But I cannot read any more cards until I reset the RF522 (either using software or just restarting the device).
void loop() {
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return;
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) {
return;
}
// Dump debug info about the card; PICC_HaltA() is automatically called
mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
}
Gives the following output
Card UID: B6 35 9F 46
Card SAK: 08
PICC type: MIFARE 1KB
Sector Block 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 AccessBits
15 63 PCD_Authenticate() failed: Timeout in communication.
14 59 PCD_Authenticate() failed: Timeout in communication.
13 55 PCD_Authenticate() failed: Timeout in communication.
...
I cannot read a card if it's present when starting the RC522, the communication times out. It does, however, take longer when a card is present. Using the following code:
// this is triggered by a serial command input
void resetAndRead() {
Serial.println("Init and check for any card");
mfrc522[0].PCD_Reset();
Serial.print("Reset complete (antenna off): ");
Serial.println(millis() - time_last_action);
delay(2000);
time_last_action = millis();
initialise();
Serial.print("Init complete: ");
Serial.println(millis() - time_last_action);
delay(10);
time_last_action = millis();
PICC_IsAnyCardPresent();
Serial.print("Check for card complete: ");
Serial.println(millis() - time_last_action);
}
void initialise() {
mfrc522[0].PCD_Init(ssPins[0], RST_PIN); // Init each MFRC522 card
mfrc522[0].PCD_DumpVersionToSerial();
}
bool PICC_IsAnyCardPresent() {
byte bufferATQA[2];
byte bufferSize = sizeof(bufferATQA);
MFRC522::StatusCode result = mfrc522[0].PICC_WakeupA(bufferATQA, &bufferSize);
Serial.print("Status Code: ");
Serial.print(mfrc522[0].GetStatusCodeName(result));
Serial.println();
return (result == MFRC522::STATUS_OK || result == MFRC522::STATUS_COLLISION);
}
I get the following output with no card present
Init and check for any card
Reset complete (antenna off): 50
Firmware Version: 0x92 = v2.0
Init complete: 51
Status Code: Timeout in communication.
Check for card complete: 41
And with a card present
Init and check for any card
Reset complete (antenna off): 52
Firmware Version: 0x92 = v2.0
Init complete: 53
Status Code: Timeout in communication.
Check for card complete: 294
Particularly given the first issue - does this sound like a hardware issue? No one else seems to have problems reading multiple cards without requiring a reset.
Should it be possible to solve the third issue? i.e. should an RFID reader be able to communicate with an RFID chip when the antenna is first switched on.
Upvotes: 2
Views: 4081
Reputation: 46
Bit late, but perhaps someone will find these usefull..
https://github.com/miguelbalboa/rfid/issues/269#issuecomment-292783655 https://github.com/miguelbalboa/rfid/issues/269#issuecomment-472342583
// Function requires an integer assigned to specific reader
// If not multi-reader, just drop the [...]
void mfrc522_fast_Reset(int reader) {
digitalWrite(RST_PIN, HIGH);
mfrc522[reader].PCD_Reset();
mfrc522[reader].PCD_WriteRegister(mfrc522[reader].TModeReg, 0x80); // TAuto=1;
// Timer starts automatically at the end of the transmission
// in all communication modes at all speeds
mfrc522[reader].PCD_WriteRegister(mfrc522[reader].TPrescalerReg, 0x43); // 10μs.
// mfrc522.PCD_WriteRegister(mfrc522.TPrescalerReg, 0x20); // test
mfrc522[reader].PCD_WriteRegister(mfrc522[reader].TReloadRegH, 0x00);
// Reload timer with 0x064 = 30, ie 0.3ms before timeout.
mfrc522[reader].PCD_WriteRegister(mfrc522[reader].TReloadRegL, 0x1E);
//mfrc522.PCD_WriteRegister(mfrc522.TReloadRegL, 0x1E);
mfrc522[reader].PCD_WriteRegister(mfrc522[reader].TxASKReg, 0x40);
// Default 0x00. Force a 100 % ASK modulation independent
//of the ModGsPReg register setting
mfrc522[reader].PCD_WriteRegister(mfrc522[reader].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)
mfrc522[reader].PCD_AntennaOn(); // Enable the antenna driver pins TX1 and TX2
// (they were disabled by the reset)
}
Upvotes: 2
Reputation: 11389
You forgot exit an authentificated PICC. Try to use the MFRC522::PCD_StopCrypto1()
function.
Used to exit the PCD from its authenticated state. Remember to call this function after communicating with an authenticated PICC - otherwise no new communications can start.
You can use the method after dumping the information:
mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
or directly before checking a new card (multiple calls are no problem):
mfrc522.PICC_IsNewCardPresent()
Upvotes: 2