Dial RFID(NFC)に関する API とサンプルプログラム。
#include "M5Dial.h"
void setup() {
  auto cfg = M5.config();
  M5Dial.begin(cfg, false, true);  // encoder, RFID
  Serial.begin(115200);
}
void loop() {
  // PICC: Proximity Integrated Circuit Card
  if (M5Dial.Rfid.PICC_IsNewCardPresent() && M5Dial.Rfid.PICC_ReadCardSerial()) {
    M5Dial.Display.clear();
    uint8_t piccType = M5Dial.Rfid.PICC_GetType(M5Dial.Rfid.uid.sak);
    Serial.print(F("PICC type: "));
    Serial.println(M5Dial.Rfid.PICC_GetTypeName(piccType));
    // Check if the tag / card is of type MIFARE Classic
    if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI && piccType != MFRC522::PICC_TYPE_MIFARE_1K && piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
      Serial.println(F("This tag / card is not of type MIFARE Classic.\n"));
      delay(500);
      return;
    }
    // Output the stored UID data
    for (byte i = 0; i < M5Dial.Rfid.uid.size; i++) {
      Serial.printf("%02X ", M5Dial.Rfid.uid.uidByte[i]);
    }
    Serial.println("\n");
    delay(500);
  }
} 
 #include "M5Dial.h"
MFRC522::MIFARE_Key key;
void setup() {
  auto cfg = M5.config();
  M5Dial.begin(cfg, false, true);  // encoder, RFID
  Serial.begin(115200);
  // Prepare the key (used both as key A and as key B) with 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();
  // PICC: Proximity Integrated Circuit Card
  if (M5Dial.Rfid.PICC_IsNewCardPresent() && M5Dial.Rfid.PICC_ReadCardSerial()) {
    M5Dial.Display.clear();
    uint8_t piccType = M5Dial.Rfid.PICC_GetType(M5Dial.Rfid.uid.sak);
    Serial.print(F("PICC type: "));
    Serial.println(M5Dial.Rfid.PICC_GetTypeName(piccType));
    // Check if the tag / card is of type MIFARE Classic
    if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI && piccType != MFRC522::PICC_TYPE_MIFARE_1K && piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
      Serial.println(F("This tag / card is not of type MIFARE Classic.\n"));
      delay(500);
      return;
    }
    // Output the stored UID data
    String uid = "";
    for (byte i = 0; i < M5Dial.Rfid.uid.size; i++) {
      Serial.printf("%02X ", M5Dial.Rfid.uid.uidByte[i]);
      uid += String(M5Dial.Rfid.uid.uidByte[i], HEX);
    }
    Serial.println("\n");
    // M5Dial.Rfid.PICC_DumpToSerial(&(M5Dial.Rfid.uid));
    // Serial.println("\n");
    // In this example, we use the second sector (sector #1) including blocks #4, #5, #6, #7
    byte sector = 1;
    byte blockAddr = 4;
    byte trailerBlock = 7;
    byte dataBlock[] = {
      0x01, 0x02, 0x03, 0x04,  //  1,  2,  3,   4,
      0x05, 0x06, 0x07, 0x08,  //  5,  6,  7,   8,
      0x09, 0x0a, 0x0b, 0x0c,  //  9, 10, 11,  12,
      0x0d, 0x0e, 0x0f, 0xff   // 13, 14, 15, 255
    };
    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("\n");
    // 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, now it should 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("\n");
    // Check if the 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();
    Serial.println("====================");
  }
}このプログラムは、Key A 認証完了後に セクタ 1 のブロック 4 のデータを読み取り、その後 Key B 認証完了後に セクタ 1 のブロック 4 のデータを更新します。処理中はタグ / カードを常に Dial に近づけた状態に保ってください。プログラム出力は次のとおりです:
 
 以下は一般的な API の使用説明です。MIFARE カードの読取り/書込みの標準フローは次のとおりです:
操作の戻り値ステータスコード
enum StatusCode {
    STATUS_OK             = 1,  // Success
    STATUS_ERROR          = 2,  // Error in communication
    STATUS_COLLISION      = 3,  // Collision detected
    STATUS_TIMEOUT        = 4,  // Timeout in communication
    STATUS_NO_ROOM        = 5,  // The 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   // The MIFARE PICC responded with NAK
};関数プロトタイプ:
void begin();機能説明:
M5Dial.begin() を呼び出す際に、パラメータ enableRFID を true に設定すると同時に初期化できます。
M5Dial.begin(m5::M5Unified::config_t cfg, bool enableEncoder, bool enableRFID);入力パラメータ:
戻り値:
関数プロトタイプ:
bool PICC_IsNewCardPresent();機能説明:
IDLE 状態のカードが存在するかどうかをスキャンします。HALT 状態のカードは無視されます。入力パラメータ:
戻り値:
関数プロトタイプ:
bool PICC_ReadCardSerial();機能説明:
Uid uid; から取得できます。読み取り操作の前に PICC_IsNewCardPresent()、PICC_RequestA()、または PICC_WakeupA() を実行して、カードが検出されていることを確認する必要があります。for (byte i = 0; i < M5Dial.Rfid.uid.size; i++) {
  Serial.printf("%02X ", M5Dial.Rfid.uid.uidByte[i]);
}入力パラメータ:
戻り値:
関数プロトタイプ:
uint8_t PICC_RequestA(uint8_t *bufferATQA, uint8_t *bufferSize);機能説明:
入力パラメータ:
戻り値:
関数プロトタイプ:
uint8_t PICC_WakeupA(uint8_t *bufferATQA, uint8_t *bufferSize);機能説明:
入力パラメータ:
戻り値:
関数プロトタイプ:
uint8_t PICC_Select(Uid *uid, uint8_t validBits = 0);機能説明:
入力パラメータ:
戻り値:
関数プロトタイプ:
uint8_t PICC_HaltA();機能説明:
入力パラメータ:
戻り値:
関数プロトタイプ:
uint8_t PCD_Authenticate(uint8_t command, uint8_t blockAddr, MIFARE_Key *key, Uid *uid);機能説明:
PCD_StopCrypto1() を呼び出してください。そうしないと、新しい通信を開始できません。入力パラメータ:
FFFFFFFFFFFF に設定されています戻り値:
関数プロトタイプ:
void PCD_StopCrypto1();機能説明:
PCD_StopCrypto1() を呼び出してください。そうしないと、新しい通信を開始できません。入力パラメータ:
戻り値:
関数プロトタイプ:
uint8_t MIFARE_Read(uint8_t blockAddr, uint8_t *buffer, uint8_t *bufferSize);機能説明:
入力パラメータ:
戻り値:
関数プロトタイプ:
uint8_t MIFARE_Write(uint8_t blockAddr, uint8_t *buffer, uint8_t bufferSize);機能説明:
入力パラメータ:
戻り値:
MFRC522 ライブラリをドライバとして使用しています。関連する API の詳細は MFRC522 ソースコード を参照してください。