#include "M5Dial.h"
void setup() {
auto cfg = M5.config();
M5Dial.begin(cfg, false, true);
}
void loop() {
if (M5Dial.Rfid.PICC_IsNewCardPresent() &&
M5Dial.Rfid.PICC_ReadCardSerial()) {
M5Dial.Display.clear();
Serial.print(F("PICC type: "));
uint8_t piccType = M5Dial.Rfid.PICC_GetType(M5Dial.Rfid.uid.sak);
Serial.println(M5Dial.Rfid.PICC_GetTypeName(piccType));
// Check is the PICC of Classic MIFARE type
if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&
piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
Serial.println(F("Your tag is not of type MIFARE Classic."));
return;
}
for (byte i = 0; i < M5Dial.Rfid.uid.size;
i++) { // Output the stored UID data.
Serial.printf("%02X ", M5Dial.Rfid.uid.uidByte[i]);
}
Serial.println();
}
}
#include "M5Dial.h"
MFRC522::MIFARE_Key key;
void setup() {
auto cfg = M5.config();
M5Dial.begin(cfg, false, true);
// Prepare the key (used both as key A and as key B)
// using FFFFFFFFFFFFh which is the default at chip delivery from the factory
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
}
/**
* Helper routine to dump a byte array as hex values to Serial.
*/
void dump_byte_array(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], HEX);
}
}
void loop() {
M5Dial.update();
if (M5Dial.Rfid.PICC_IsNewCardPresent() && M5Dial.Rfid.PICC_ReadCardSerial()) {
Serial.print(F("PICC type: "));
uint8_t piccType = M5Dial.Rfid.PICC_GetType(M5Dial.Rfid.uid.sak);
Serial.println(M5Dial.Rfid.PICC_GetTypeName(piccType));
// Check is the PICC of Classic MIFARE type
if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI && piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
Serial.println(F("Your tag is not of type MIFARE Classic."));
return;
}
String uid = "";
for (byte i = 0; i < M5Dial.Rfid.uid.size; i++) { // Output the stored UID data. 将存储的UID数据输出
Serial.printf("%02X ", M5Dial.Rfid.uid.uidByte[i]);
uid += String(M5Dial.Rfid.uid.uidByte[i], HEX);
}
Serial.println();
// M5Dial.Rfid.PICC_DumpToSerial(&(M5Dial.Rfid.uid));
// In this sample we use the second sector,
// that is: sector #1, covering block #4 up to and including block #7
byte sector = 1;
byte blockAddr = 4;
byte dataBlock[] = {
0x01, 0x02, 0x03, 0x04, // 1, 2, 3, 4,
0x05, 0x06, 0x07, 0x08, // 5, 6, 7, 8,
0x09, 0x0a, 0xff, 0x0b, // 9, 10, 255, 11,
0x0c, 0x0d, 0x0e, 0x0f // 12, 13, 14, 15
};
byte trailerBlock = 7;
MFRC522::StatusCode status;
byte buffer[18];
byte size = sizeof(buffer);
// Authenticate using key A
Serial.println(F("Authenticating using key A..."));
status = (MFRC522::StatusCode)M5Dial.Rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key,
&(M5Dial.Rfid.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(M5Dial.Rfid.GetStatusCodeName(status));
return;
}
// Show the whole sector as it currently is
Serial.println(F("Current data in sector:"));
M5Dial.Rfid.PICC_DumpMifareClassicSectorToSerial(&(M5Dial.Rfid.uid), &key, sector);
Serial.println();
// Read data from the block
Serial.print(F("Reading data from block "));
Serial.print(blockAddr);
Serial.println(F(" ..."));
status = (MFRC522::StatusCode)M5Dial.Rfid.MIFARE_Read(blockAddr, buffer, &size);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Read() failed: "));
Serial.println(M5Dial.Rfid.GetStatusCodeName(status));
}
Serial.print(F("Data in block "));
Serial.print(blockAddr);
Serial.println(F(":"));
dump_byte_array(buffer, 16);
Serial.println();
Serial.println();
// Authenticate using key B
Serial.println(F("Authenticating again using key B..."));
status = (MFRC522::StatusCode)M5Dial.Rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, trailerBlock, &key,
&(M5Dial.Rfid.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(M5Dial.Rfid.GetStatusCodeName(status));
return;
}
// Write data to the block
Serial.print(F("Writing data into block "));
Serial.print(blockAddr);
Serial.println(F(" ..."));
dump_byte_array(dataBlock, 16);
Serial.println();
status = (MFRC522::StatusCode)M5Dial.Rfid.MIFARE_Write(blockAddr, dataBlock, 16);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Write() failed: "));
Serial.println(M5Dial.Rfid.GetStatusCodeName(status));
}
Serial.println();
// Read data from the block (again, should now be what we have written)
Serial.print(F("Reading data from block "));
Serial.print(blockAddr);
Serial.println(F(" ..."));
status = (MFRC522::StatusCode)M5Dial.Rfid.MIFARE_Read(blockAddr, buffer, &size);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Read() failed: "));
Serial.println(M5Dial.Rfid.GetStatusCodeName(status));
}
Serial.print(F("Data in block "));
Serial.print(blockAddr);
Serial.println(F(":"));
dump_byte_array(buffer, 16);
Serial.println();
// Check that data in block is what we have written
// by counting the number of bytes that are equal
Serial.println(F("Checking result..."));
byte count = 0;
for (byte i = 0; i < 16; i++) {
// Compare buffer (= what we've read) with dataBlock (= what we've written)
if (buffer[i] == dataBlock[i]) count++;
}
Serial.print(F("Number of bytes that match = "));
Serial.println(count);
if (count == 16) {
Serial.println(F("Success :-)"));
} else {
Serial.println(F("Failure, no match :-("));
Serial.println(F(" perhaps the write didn't work properly..."));
}
Serial.println();
// Dump the sector data
Serial.println(F("Current data in sector:"));
M5Dial.Rfid.PICC_DumpMifareClassicSectorToSerial(&(M5Dial.Rfid.uid), &key, sector);
Serial.println();
// Halt PICC
M5Dial.Rfid.PICC_HaltA();
// Stop encryption on PCD
M5Dial.Rfid.PCD_StopCrypto1();
}
}
« PICC type: MIFARE 1KB
C2 34 D4 44
Authenticating using key A...
Current data in sector:
1 7 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
Reading data from block 4 ...
Data in block 4:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Authenticating again using key B...
Writing data into block 4 ...
01 02 03 04 05 06 07 08 09 0A FF 0B 0C 0D 0E 0F
Reading data from block 4 ...
Data in block 4:
01 02 03 04 05 06 07 08 09 0A FF 0B 0C 0D 0E 0F
Checking result...
Number of bytes that match = 16
Success :-)
Current data in sector:
1 7 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
4 01 02 03 04 05 06 07 08 09 0A FF 0B 0C 0D 0E 0F [ 0 0 0 ]
The following is the use of common API instructions, general read and write MIFARE card using the process as follows.
Operation return value status code
enum StatusCode {
STATUS_OK = 1, // Success
STATUS_ERROR = 2, // Error in communication
STATUS_COLLISION = 3, // Collission detected
STATUS_TIMEOUT = 4, // Timeout in communication.
STATUS_NO_ROOM = 5, // A buffer is not big enough.
STATUS_INTERNAL_ERROR = 6, // Internal error in the code. Should not happen ;-)
STATUS_INVALID = 7, // Invalid argument.
STATUS_CRC_WRONG = 8, // The CRC_A does not match
STATUS_MIFARE_NACK = 9 // A MIFARE PICC responded with NAK.
};
Syntax:
void begin();
Description:
It can be initialized by setting the parameter enableRFID
to true when calling M5Dial.begin.
M5Dial.begin(m5::M5Unified::config_t cfg, bool enableEncoder,bool enableRFID)
Parameters:
Return:
Syntax:
bool PICC_IsNewCardPresent();
Description:
IDLE
state, cards in the HALT state are ignored.Parameters:
Return:
Syntax:
bool PICC_ReadCardSerial();
Description:
Uid uid;
. Before read operation, PICC_IsNewCardPresent()
, PICC_RequestA()
or PICC_WakeupA()
should be executed to make sure the card is read.for (byte i = 0; i < M5Dial.Rfid.uid.size;
i++) { // Output the stored UID data.
Serial.printf("%02X ", M5Dial.Rfid.uid.uidByte[i]);
}
Parameters:
Return:
Syntax:
uint8_t PICC_RequestA(uint8_t *bufferATQA, uint8_t *bufferSize);
Description:
Parameters:
Return:
Syntax:
uint8_t PICC_WakeupA(uint8_t *bufferATQA, uint8_t *bufferSize);
Description:
Parameters:
Return:
Syntax:
uint8_t PICC_Select(Uid *uid, uint8_t validBits = 0);
Description:
Parameters:
Return:
Syntax:
uint8_t PICC_HaltA();
Description:
Parameters:
Return:
Syntax:
uint8_t PCD_Authenticate(uint8_t command, uint8_t blockAddr, MIFARE_Key *key, Uid *uid);
Description:
Parameters:
FFFFFFFFFFFFFFF
.Return:
Syntax:
void PCD_StopCrypto1();
Description:
Parameters:
Return:
Syntax:
uint8_t MIFARE_Read(uint8_t blockAddr, uint8_t *buffer, uint8_t *bufferSize);
Description:
Parameters:
Return:
Syntax:
uint8_t MIFARE_Write(uint8_t blockAddr, uint8_t *buffer, uint8_t bufferSize);
Description:
Parameters:
Return: