非接触ICカード(RFID)のデータ読み書き方法(Arduinoコマンド使用)

非接触ICカードの使い方アイキャッチ

RFID(NFC)技術を使用した非接触ICカードやタグのデータの読み書き方法について、カードのデータ構成も含めて使用方法を詳しく紹介します。

実際にデータの読み書きを行うためには「M5Stack」の「RFID2ユニット」を使用して「Arduinoコマンド」で行います。

デバイスを準備すれば「サンプルプログラム」をコピペして書き込むだけで動作確認できるので、自分オリジナルの非接触ICカード/タグを作ってみましょう。


「M5Stack」を使用した「Arduino」の開発環境の準備方法は、以下のリンクで詳しく紹介しています。

M5StackシリーズのためのArduino IDEのインストール方法と初期設定、使い方紹介
ArduinoIDEバージョン2のインストール方法から初期設定、スケッチ例の書き込み、コピペでの使い方まで詳しく紹介します。インストールはArduinoでも同じです。

スポンサーリンク

1.今回できるようになること

今回は個人でも安価(1つ100円前後)で入手可能な非接触ICカード/タグ(MIFARE 1K)を使用して、データの読み書き、アクセス条件の設定方法等を詳しく紹介します。

「Arduino」の開発環境を使用して、最終的にはシリアルモニタから、好きなデータ領域のデータの読み書き、書き換え、アクセス条件の設定ができるようになります。

カード/タグ内のデータ構成についても紹介しますので、各データの保存領域(セクター・ブロック)や、複雑なアクセス条件の設定方法(Access Bits)についても理解できると思います。
RFID技術について理解して、自分オリジナルの非接触ICカード/タグを作って、使いこなしていきましょう♪
スポンサーリンク

2.RFIDとは

RFIDは「Radio Frequency Identification(ラジオ周波数識別)」の略で、無線通信を利用してデータを自動的に識別する技術です。

RFIDシステムは、タグ(トランスポンダ)とリーダーから構成されます。
タグは特定の情報(識別番号など)を保持しており、リーダーからの電波を受信すると、応答信号を送信します。

小型のタグには、個々のアイテムや製品に取り付けられる小型のチップとアンテナが内蔵されており、リーダーからの電波によって電源が供給されて起動し、データの送受信を行います。

RFIDは、物流や在庫管理、入退室管理などのさまざまな分野で利用されています。
例えば、製造業では材料の追跡や生産プロセスの管理に使用され、小売業では在庫管理や商品の追跡に利用されます。

RFIDの利点は、非接触で情報を取得することができたり、高速かつ正確なデータ収集が可能な点です。ただし、専用のシステムが必要でその種類も多いため、導入コストやセキュリティを考慮して、どれを採用するかの検討が必要です。
スポンサーリンク

3.関連用語の解説

非接触ICカードやタグに利用されている「RFID」技術を使用する時に登場する、主な用語を以下表にまとめました。

用語解説
NFCNFCは「Near Field Communication(近距離無線通信)」の略で、非接触型の近距離無線通信技術です。
NFCは、2つのデバイスがタッチまたは非常に近い距離で接触することで、データを交換することができ、セキュリティのための情報の暗号化や認証などの保護機能もあるため、タグやスマートフォン、決済カードなどのデバイスに組み込まれています。
NFCは、主にモバイル決済やデジタルチケット、スマートロック、デバイス間のファイル転送など、さまざまな応用分野で利用されています。
RFIDタグRFIDタグは、小さなチップとアンテナから構成されており、無線通信の範囲内であれば、特定のリーダーから情報を読み取ることができます。
パッシブRFIDタグとアクティブRFIDがあり、パッシブRFIDタグは、外部の電力源を必要とせず、リーダーからの電波エネルギーを受信して動作します。
アクティブRFIDタグは、内蔵された電池や電源を利用して動作するタイプです。パッシブRFIDとは異なり、送信側と受信側の両方で電波を送受信することができます。

アクティブRFIDは通信範囲が広く、移動物体の追跡や長距離識別などに使用されます。
PICCPICC(Proximity Integrated Circuit Card)は、非接触型ICカード(NFCカード)のことを指します。
PICCは、近距離(数センチ)での通信に使用される技術で、カードリーダーやスマートフォンなどのデバイスとの間で情報をやり取りすることができます。
RFIDタグの中でもキーホルダー型のような小型なものはPICCと同じ機能を持ちます。
主な用途として、交通カードやクレジットカード、スマートキーなどがあります。
トランスポンダトランスポンダ(Transponder)とは、Transmitter(送信機)とresponder(応答機)の両方の機能を備えたデバイスで、情報の保存や処理を行うマイクロチップとアンテナを接合した電気回路です。
RFIDシステムでは、RFIDリーダーがトランスポンダ(タグ)に電波を送信し、その信号を受け取ったタグはリーダーに固有の情報(UID, SAK等)を送り返します。
RFIDリーダーRFIDリーダー(リーダーライター)はアンテナを備えたデバイスで、以下の手順でタグから情報を読み取ったり、タグに情報を書き込んだりする装置です。
RFIDリーダーは、一定の周波数で電波を発信します。
②周囲のRFIDタグやICカードは、受けた電波エネルギーを使って内部の回路を動作させます。
③タグやカードは、リーダーからの電磁波エネルギーを利用して自身の識別情報やデータを応答データとして返します。
④RFIDリーダーは、アンテナを介してタグやカードからの応答データを受信します。
⑤受信したデータは、リーダーが内蔵している回路や処理装置によって解析され、必要な情報(タグの識別情報やデータ)が抽出されます。
UIDUID (Unique Identifier)は、RFIDタグを一意に識別するための識別番号です。
通常、UIDは64ビットまたは96ビットの長さの番号として表されます。
UIDは、タグを特定するために使用され、異なるタグが同じUIDを持つことはありません。
UIDは製造時に割り当てられ、一度割り当てられたら変更されません。
SAKSAK (Select Acknowledge)は、RFIDタグの機能や特性を示すバイト値です。
SAKは、リーダーがタグとの通信時に受信する応答メッセージの一部として提供されます。
SAKによって、タグがISO/IEC 14443規格(13.56MHzの周波数で動作する非接触型ICカードやRFIDタグのための規格)に準拠しているかどうか、または他の特性(例:デュアルインターフェースタグ)を持っているかどうかの判断ができます。
SAKはタグの機能や通信プロトコルに基づいて決まる値であり、リーダーが適切に対応できるかどうかを判断するために使用されます。

4.RFIDタグ・非接触ICカードの種類

・MIFARE(マイフェア)

NXPセミコンダクターズ(旧フィリップス社)によって開発された非接触型ICカードの規格です。
MIFAREカードにはいくつかの種類があり、メモリ容量が大きく安価なため、広く普及しています。

交通機関チケット、入退出管理、キャッシュレス決済などさまざまな用途で利用されています。

・Felica(フェリカ)

Felicaは、ソニーによって開発された非接触型ICカードの規格です。
Felicaは、主に日本で使用されており、SuicaやPASMOなどの交通系ICカードや、電子マネー(例:Edy、nanaco)、電子マネーモードのクレジットカードなど、さまざまなサービスで利用されています。※MIFAREとの互換性はありません。

・ISO/IEC

ISO(国際標準化機構)/IEC(国際電気標準会議)によって制定され、13.56MHz周波数帯域で通信する非接触型ICカードの国際規格です。

  • ISO/IEC 14443
    非接触型ICカードやRFIDタグが互換性を持つための規格です。
    この規格は、近距離(通常は1〜10 cm程度)で動作する非接触技術に適用され、2つのタイプ(タイプAとタイプB)が定義されています。
    タイプAは、データ転送速度は106 kbit/sです。
    タイプBは、データ転送速度は106 kbit/sまたは212 kbit/sで、タイプAよりセキュリティレベルが高いです。
    MIFAREカードもこの規格(タイプA)に準じており、公共交通機関での乗車券や電子マネーなど、さまざまなアプリケーションで使用されます。
  • ISO/IEC 18092
    日本では交通系IC等で使用されている「Felica」がこの規格です。
    セキュリティ面で優れており、処理速度は最大で424 kbpsと ISO/IEC14443より高速です。
  • ISO/IEC 15693
    読み取り距離が比較的長い(5 cm以上)ため「Vicinity(近傍)」カードと呼ばれる規格です。
    データ転送速度は遅く 26 kbit/sです。
    通信距離が長いため、物品の追跡や在庫管理などに使用されます。

5.MIFARE規格の種類

今回、実際にデータの読み書きには「MIFARE Classic」のカード/タグを使用します。
MIFARE規格には以下のような種類があります。

・MIFARE Classic

「MIFARE Classic」は最も広く使用されるMIFAREカードです。
1KBまたは4KBのメモリ容量を持ち、それぞれ16または64セクター(データ保存領域)に分割されています。

暗号化やセキュリティ機能が限られており、比較的安価なため、主にアクセス制御や公共交通機関のチケットなどの決済に使用されます。

・MIFARE Plus

「MIFARE Plus」は「MIFARE Classic」の代替として開発され、より高いセキュリティ機能を提供します。

「MIFARE Classic」との下位互換性を持っており、徐々にアップグレードできるため、既存のシステムに導入しやすくなっています。

AES暗号化や改善されたセキュリティ機能を備えており、データ保護やセキュアなアプリケーション実装に適しています。

・MIFARE Ultralight

「MIFARE Ultralight」は、小型で低コストなRFIDカードです。
メモリ容量は144バイトまたは512バイトで、読み取り専用であり、書き込み機能はありません。
※書込み可能な「Ultralight C」という規格もあります。

公共交通機関の乗車券、イベントチケットなど、一回性の利用のために設計されています。

・MIFARE DESFire(TNP3XXX)

「MIFARE DESFire」は、通信速度が速く(848kbps)、高度なセキュリティ機能を持つRFIDカードです。
2KB、4KB、8KBのメモリ容量があり、暗号化、相互認証、データ保護などの強力なセキュリティ機能が組み込まれています。

多くのセキュリティアプリケーションに使用され、ロンドン地下鉄の交通系ICカードであるOyster Cardをはじめとした、世界各国の交通券にも「MIFARE DESfire」が採用されています。

6.準備するもの:カード/タグの読み書き準備

今回は安価(1つ100円前後)で、入手しやすい非接触ICカード/タグの「MIFARE Classic(1KB)」を使用して、実際にデータの読み書きを行います。

全体の構成は下写真のようになります。


動作確認に必要なものは以下になります。

・M5Stack Basic

「M5Stack Basic V2.6」とは「M5Stackテクノロジー社」のマイコンボードです。

大きさは 54mm x 54mm x 18mmで2.0インチ(320*240)液晶表示器を搭載しており、入出力端子、3個のボタン、3軸ジャイロ+3軸加速度センサ、スピーカ搭載でSDカードやバッテリーも内蔵され、シリアル通信はもちろんWiFiやBluetoothにも対応しています。

「M5Stack Basic V2.6」については以下のリンクで詳しく紹介しています。

M5Stack Basicの使い方、端子配列、サンプルプログラムで詳しく紹介
基本仕様、端子配列、サンプルプログラムで「Lチカ」やアナログ入力(ADC)、アナログ出力(DAC)、シリアル通信(UART)、液晶表示、バッテリー残量表示等の基本的な動作まで詳しく紹介します。

・RFIDリーダーライター[RFID2ユニット]

今回使用した非接触ICカード/タグのリーダーライターは下画像の「M5Stak」社製の「RFID2ユニット」です。

非接触ICカードの使い方 RFID2ユニット
非接触ICカードの使い方 RFID2ユニット
非接触ICカードの使い方 RFID2ユニット
非接触ICカードの使い方 RFID2ユニット

RFIDリーダーライターは色々なものがありますが、電波を使用するデバイスのため、日本の電波法により、電波強度が基準値以下である確認が取れているものを使用する必要があります。

私は最初Amazonで適当に購入しましたが、この確認をする術がなかったので・・・使わずに放置してました。
以下のスイッチサイエンスさんで取り扱っている「M5Stack」社の「RFID2ユニット」は電波強度の確認がされており、安心して使用できるため、以下リンクから購入されることをお勧めします。

SwitchScience
スイッチサイエンス
通信仕様は「I2C」で配線は付属の「Groveコネクタ配線」で「M5Stack Basic」と接続するだけです。
価格はこれを書いている時点で¥748-と比較的安価です。

・RFIDカード/タグ

「RFIDカード/タグ」については下画像のようにいろいろな種類があります。
下画像の中央にある青いカードは「M5Stack」社の公式オンラインショップで¥5000-程購入した時に、おまけで付属していたものです。
特に何も書かれていなかったので空のカードとして使用できます。

非接触ICカードの使い方、MIFARE 1KBカード/タグ色々

「Amazon」でも以下のように色々な種類が販売されています。
「MIFARE Classic 1KB」なら何でも良いので、カードタイプでも、キーホルダタイプでも、シールでも、お好みのもので準備してください。

・使用ライブラリ「MFRC522_I2C」

今回使用したライブラリは「MFRC522_I2C」です。

「Arduino IDE」の「ライブラリマネージャ」で検索すると、下画像の「kkloesener」さん作のライブラリです。

非接触ICカードの使い方、使用ライブラリMFRC522_I2C
類似ライブラリで「MFRC522」もあり、プログラム例も多くみられますが、今回使用したリーダーライターは「I2C通信」専用のものなので「MFRC522_I2C」をインストールしてください。

7.サンプルプログラム(コピペ)

カード内のデータを読み込んでシリアルモニタに表示したり、シリアルモニタから入力した文字を書き込むためのサンプルプログラムを準備しました。


サンプルプログラムは以下になります。コピペで貼り付けて書き込んで実行してください。
※下コード(黒枠)内の右上角にある小さなアイコンのクリックでもコピーできます。

#include <M5Stack.h>
#include <MFRC522_I2C.h>

MFRC522_I2C mfrc522(0x28, 2, &Wire); // デバイスアドレスとリセット端子番号、TwoWireインスタンスを指定してインスタンス化(&Wire省略可)

// 変数宣言
byte read_data[16] = {};  // 読込みデータ格納用配列
byte write_data[16] = {}; // 書込みデータ格納用配列
int sector_num = 0;       // セクター番号格納用
int block_num = 0;        // ブロック番号格納用

// 関数 --------------------------------------------------------
// 全データ読み込みシリアルモニタ表示 ------------------------------------------
void readAllData() {
  byte piccType = mfrc522.PICC_GetType(mfrc522.uid.sak); // SAK(NFCタグの識別子)を取得し、変数に格納
  // カードタイプ確認
  if (piccType == MFRC522_I2C::PICC_TYPE_MIFARE_MINI ||
      piccType == MFRC522_I2C::PICC_TYPE_MIFARE_1K ||
      piccType == MFRC522_I2C::PICC_TYPE_MIFARE_4K) {
    mfrc522.PICC_DumpToSerial(&(mfrc522.uid));          // Mifare Classicのデータを出力
  } else if (piccType == MFRC522_I2C::PICC_TYPE_MIFARE_UL) {
    mfrc522.PICC_DumpMifareUltralightToSerial();        // Mifare Ultralightのデータを出力
  } else {
    M5.Lcd.setTextColor(RED, BLACK);
    M5.Lcd.fillRect(0, 57, 320, 200, BLACK);            // 液晶のデータ表示部を黒塗りリセット
    M5.Lcd.setCursor(0, 57);                            // 座標表示
    M5.Lcd.println("This card is not supported.");      // サポートされていないカードである旨を表示
    delay(5000);
  }
  mfrc522.PICC_HaltA(); // 現在読み込んでいるカードをハルトする
  mfrc522.PCD_Init();   // RFIDリーダーを初期化する
}
// ブロックデータ読み込み ------------------------------------------
void readData(int sector, int block) {  // (セクター番号, ブロック番号)
  MFRC522_I2C::MIFARE_Key key = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // MIFARE_Key構造体でセクター認証キーを準備(ポインタで指定するため)
  Serial.println("カードデータ読み取り");

  uint8_t address = sector * 4 + block;         // ブロックアドレスを算出
  // 読込み対象のセクターを認証する(認証キータイプ, ブロックアドレス, 認証キーポインタ, カードのUIDプロパティへのポインタ)
  if (mfrc522.PCD_Authenticate(MFRC522_I2C::PICC_CMD_MF_AUTH_KEY_A, address, &key, &(mfrc522.uid)) == MFRC522_I2C::STATUS_OK) {
    Serial.println("認証に成功しました");
    byte buffer[18];                            // 読込みデータ16byte + エラーチェック用CRC用2byte分の配列を準備
    byte bufferSize = sizeof(buffer);           // バッファサイズをポインタで指定できるように準備
    // 認証成功で読込み実行(ブロックアドレス, データ格納バッファ配列ポインタ, 読込みデータバッファサイズポインタ)
    if (mfrc522.MIFARE_Read(address, buffer, &bufferSize) == MFRC522_I2C::STATUS_OK) { // 通信成功なら
      for (int i = 0; i < bufferSize-2; i++) {  // 読込んだデータのCRCを除いた16byte分繰り返す
        read_data[i] = buffer[i];               // バッファを読み込みデータ配列に格納
        Serial.printf("%02X ", read_data[i]);   // 16byteの読み込みデータをシリアルモニタに出力
      }
      Serial.printf("\n%s\n", read_data);
    }
  } else {
    Serial.println("認証に失敗しました");
  }
  mfrc522.PCD_StopCrypto1();  // 認証済み解除
}
// ブロックデータ書込み -------------------------------------------
void writeData(int sector, int block) { // (セクター番号, ブロック番号)
  MFRC522_I2C::MIFARE_Key key = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // MIFARE_Key構造体でセクターキーを準備(ポインタで指定するため)
  Serial.println("カードデータ書込み");

  uint8_t address = sector * 4 + block;         // ブロックアドレスを算出
  // 書込み対象のセクターを認証する(認証キータイプ, ブロックアドレス, 認証キーポインタ, カードのUIDプロパティへのポインタ)
  if (mfrc522.PCD_Authenticate(MFRC522_I2C::PICC_CMD_MF_AUTH_KEY_A, address, &key, &(mfrc522.uid)) == MFRC522_I2C::STATUS_OK) {  // 通信成功なら
    Serial.println("認証に成功しました");
    if (address == 0 || block == 3) {                 // ブロックアドレスが0またはブロック3なら書込まず終了
        Serial.print("データブロックではないので書き込めません");
    } else {                                          // ブロック0〜2ならデータ書込み
      mfrc522.MIFARE_Write(address, write_data, 16);  // (ブロックアドレス, 書込みデータ, 書込みbyte数)
      // 書き込みデータをシリアルモニタに出力
      for (int i = 0; i < 16; i++) {            // 16byte分繰り返す
        Serial.printf("%02X ", write_data[i]);  // 16進数で出力
      }
    }
    Serial.printf("\n%s\n", write_data);
  } else {
    Serial.println("認証に失敗しました");
  }
  // カードから切断する
  mfrc522.PCD_StopCrypto1();  // 認証済み解除
}

// 初期設定 ------------------------------------------------------
void setup() {
  M5.begin();           // 本体初期化
  M5.Power.begin();     // 電源初期化
  Serial.begin(9600);   // シリアル通信初期化(USBと共用、初期値は RX=G3, TX=G1)
  Wire.begin();         // I2C通信初期化
  mfrc522.PCD_Init();   // RFID2(MFRC522)初期化

  // 初期画面表示
  M5.Lcd.setTextFont(4);                          // フォント
  M5.Lcd.println("RFID2  Card  Reader / Writer"); // タイトル表示
  M5.Lcd.println("Please put the card");
  M5.Lcd.fillRect(0, 51, 320, 2, WHITE);          // 横線
}
// メイン ------------------------------------------------------
void loop() {
  // 新しいカードが読み込まれない、または、カードのシリアル番号が読み取れないならループ
  while (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) {
    delay(100); // 待機時間
  }
  // カードが読み取られたら以下を実行

  M5.update();  // 本体ボタン初期化
  // AボタンONでセクター番号+1(0〜15)
  if (M5.BtnA.wasPressed()) {
    sector_num = (sector_num + 1) % 16; // 16なら0リセット
  }
  // BボタンONでブロック番号+1(0〜2)
  if (M5.BtnB.wasPressed()) {
    block_num = (block_num + 1) % 3;    // 3なら0リセット
  }
  // CボタンONでブロックデータ読込み
  if (M5.BtnC.wasPressed()) {
    readData(sector_num, block_num);    // データ読込み関数(セクター番号, ブロック番号)
  }
  // Cボタン長押しで全データ読込みシリアルモニタ表示関数呼び出し
  if (M5.BtnC.pressedFor(1000)) {
    readAllData();                      // シリアルモニタ表示関数
  }

  // シリアルモニタから書込みデータを設定
  if (Serial.available()) {             // 受信データがあれば
    int bytesRead = Serial.available(); // 受信データバイト数を取得
    if (bytesRead <= 16) {              // 16byte以下なら
      for (int i = 0; i < 16; i++) {    // 書込みデータ配列を0で初期化
        write_data[i] = 0x00;
      }
      // 受信データを書込みデータ配列に格納
      for (int i = 0; i < bytesRead; i++) {
        write_data[i] = Serial.read();
      }
      Serial.printf("%s\n", write_data);
      writeData(sector_num, block_num); // データ書込み関数(セクター番号, ブロック番号)
    } else {
      Serial.println("文字数が16文字を超えています");
      while (Serial.available()) {      // 16byte以上のデータは破棄
        Serial.read();
      }
    }
  }

  // 液晶表示
  // カードデータ表示
  M5.Lcd.fillRect(0, 57, 320, 200, BLACK);  // 液晶のデータ表示部を黒塗りリセット
  M5.Lcd.setCursor(0, 57);                  // 座標表示
  // UID表示
  String uidString = "";                                  // UIDシリアル
  char byte_string[3];                                    // 1byteの16進数表示を格納する文字配列を準備
  for (byte i = 0; i < mfrc522.uid.size; i++) {           // 取得したbyte数分繰り返す
    sprintf(byte_string, "%02X", mfrc522.uid.uidByte[i]); // 2桁で大文字の16進数として文字配列に格納
    uidString += String(byte_string) + " ";               // String型でスペース区切りで連結
  }
  M5.Lcd.setTextColor(CYAN, BLACK);
  M5.Lcd.printf("UID : %s\n", uidString.c_str());         // Cスタイルの文字列に変換して表示
  // Mifareカード(タグ)タイプ表示
  byte piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);  // SAK(Select Acknowledge:NFCタグの識別子)を取得し、変数に格納
  M5.Lcd.setTextColor(WHITE, BLACK);                      // 文字色
  M5.Lcd.print("TYPE No. ");
  M5.Lcd.println(piccType);                               // SAKを表示
  M5.Lcd.print("TYPE Name : ");
  M5.Lcd.println(mfrc522.PICC_GetTypeName(piccType));     // SAKを基にタイプ名を表示
  // 書込みデータ、読み込みデータ確認表示
  M5.Lcd.setTextColor(GREEN, BLACK);
  M5.Lcd.printf("Sector : %d/Block : %d/Add : %d\n", sector_num, block_num, sector_num * 4 + block_num);  // ブロック情報
  M5.Lcd.printf("Write : %s\n", write_data);  // 書込みデータ
  M5.Lcd.setTextColor(ORANGE, BLACK);
  M5.Lcd.printf("Read : %s\n", read_data);    // 読み込みデータ
  
  delay(100); // 遅延時間
}

8.動作確認

サンプルプログラムの動作は以下のようになります。

動作確認で非接触ICカード/タグ内のデータ確認には「シリアルモニタ」を使用します。
「Arduino IDE」を使用する場合はした画像のように[ツール]→[シリアルモニタ]をクリックします。

「M5Stack」と非接触ICカード/タグのリーダーライター「RFID2ユニット」は付属のGROVEコネクタ配線で接続するだけです。

非接触ICカードの使い方、動作確認

「M5Stack」電源を入れると上画像のような表示になります。

非接触ICカードの使い方、動作確認

「RFID2ユニット」に非接触ICカードまたはタグを近づけると、上画像のように「UID」とカード/タグの「TYPE」が表示されます。

緑文字の「Sector」「Block」「Add」で読み書きするカード/タグ内のデータ領域を指定します。
画像の「Sector:0/Block:0/Add:0」には「UID」が保存されています。

※データ領域の詳細はこの後の「10.MIFARE 1KB のデータ構成について」で詳しく紹介しています。
非接触ICカードの使い方、動作確認

上画像のように「ボタンC」を押すと、指定したデータ領域のデータを読み出すことができますが、1秒以上長押しすると下画像のように、全データ領域に保存されているデータが一覧で表示されます。

非接触ICカードの使い方、シリアルモニタ表示
非接触ICカードの使い方、シリアルモニタ表示

次にデータの書き込みを行います。
まずは書込みたいデータ領域を下画像のように指定します。

非接触ICカードの使い方、動作確認

「ボタンA」を押すとデータ領域の「Sector(セクター)」が選択できます。

非接触ICカードの使い方、動作確認

「ボタンB」を押すとデータ領域の「Block(ブロック)」が選択できます。
「Add(ブロックアドレス)」は「Sector」と「Block」から自動で算出されます。

読み書きしたいデータ領域を設定したら、下画像のように「シリアルモニタ」に保存したい内容を入力(今回は「logikara.blog」と入力)します。

各ブロックには「16byte」のデータ(ASCII文字で16文字)が保存できます。
改行文字の「LF」や「CR」もデータ領域を使用してしまうため「改行なし」にすると「16byte」全てを有効に使用することができます。
非接触ICカードの使い方、シリアルモニタ表示

保存したいデータを入力したら[送信]ボタンか[ENTER]キーを押すと書き込みが実行されます。

非接触ICカードの使い方、動作確認

書き込みが完了すると上画像のように「Write:」に書き込まれたデータが表示されます。

非接触ICカードの使い方、動作確認

書き込みされたデータを読み込むには「ボタンC」を押す(1秒以下)と「Read:」に表示されます。

データの読み書きを行うと「シリアルモニタ」には下画像のように表示されます。
書き込まれるデータは「16進数」で「16byte」分です。
シリアルモニタでは「16進数」を「ASCII文字」に変換したものも表示させています。

非接触ICカードの使い方、シリアルモニタ表示

「ボタンC」を長押し(1秒以上)すると、下画像のように指定したデータ領域に書き込みが行われたことが確認できます。

非接触ICカードの使い方、シリアルモニタ表示
セクター0のブロック0には「UID」保存されているため書き込みできません。
各セクターのブロック3は「セクタートレーラー」と呼ばれ、セクターごとの「認証キーA,B」や各ブロックのアクセス条件を決定する「アクセスコンディション」が保存されています。
不用意に書き換えると、セクターごとアクセスできなる可能性もあるため、サンプルプログラムで書き込みできないようにしてあります。
これについては下の「・セクタートレーラー」で詳しく紹介しています。
よく理解してから、必要に応じて書き換えを行なってください。

9.サンプルプログラムの詳細

サンプルプログラムの各動作について、以下で詳しく紹介します。

・初期設定

まずは「RFID2ユニット」を使用するためのライブラリ「MFRC522_I2C」をインクルードします。

#include <M5Stack.h>
#include <MFRC522_I2C.h>

// デバイスアドレスとリセット端子番号、TwoWireインスタンスを指定してインスタンス化(&Wire省略可)
MFRC522_I2C mfrc522(0x28, 2, &Wire);

次に「MFRC 522_I2C」のインスタンスを「I2Cデバイスアドレス:0x28」と「リセット端子番号」を指定して作成します。

リセット端子番号は「Arduino」の6ピン(アクティブLOW)を設定することになってますが、今回使用した「M5Stack」では「6」はエラーになります。
リセット機能は特に使用しないので適当な入出力端子として、今回は「2」を設定しました。
第3引数に設定する「TwoWireインスタンス」は省略可能です。
この場合は初期値の「&Wire」が使用されます。
複数のI2Cを使用するときは「&Wire2」のように指定します。

初期設定は以下のように指定します。

// 初期設定 ------------------------------------------------------
void setup() {
  M5.begin();           // 本体初期化
  M5.Power.begin();     // 電源初期化
  Serial.begin(9600);   // シリアル通信初期化(USBと共用、初期値は RX=G3, TX=G1)
  Wire.begin();         // I2C通信初期化
  mfrc522.PCD_Init();   // RFID2(MFRC522)初期化
}

7行目」の「mfrc522.PCD_Init()」で「RFID2ユニット」を初期化することで、カードの読み込み待機状態となります。

・カードの認識(読み込み待機状態)

メインループで以下を実行することでカード読み込み待機状態にしています。

// メイン ------------------------------------------------------
void loop() {
  // 新しいカードが読み込まれない、または、カードのシリアル番号が読み取れないならループ
  while (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) {
    delay(100); // 待機時間
  }
  // カードが読み取られたら以下を実行

以下の関数を使用して、カードが読み込まれてカードのシリアル番号が読み取られたことを確認します。

mfrc522.PICC_IsNewCardPresent(); // カードが読み込まれたらtrueを返す
mfrc522.PICC_ReadCardSerial();     // カードのシリアル番号が読み取れたらtrueを返す

カードが認識されたらループを抜け、以降のプログラムが実行されます。

カードデータを読み書きするには必ず「カードの認識」をする必要があります。
さらに、データを読み書きするにはデータ保存領域の「データブロックの認証」を行う必要がありますが読み書き後、認証状態解除してから再度読み書きする場合にも「カードの認識」をする必要があります。

・カード内全データ確認表示

以下の「readAllData()」関数を実行することで、カードの全データを読み込んでシリアルモニタに表示することができます。

// 全データ読み込みシリアルモニタ表示 ------------------------------------------
void readAllData() {
  byte piccType = mfrc522.PICC_GetType(mfrc522.uid.sak); // SAK(NFCタグの識別子)を取得し、変数に格納
  // カードタイプ確認
  if (piccType == MFRC522_I2C::PICC_TYPE_MIFARE_MINI ||
      piccType == MFRC522_I2C::PICC_TYPE_MIFARE_1K ||
      piccType == MFRC522_I2C::PICC_TYPE_MIFARE_4K) {
    mfrc522.PICC_DumpToSerial(&(mfrc522.uid));          // Mifare Classicのデータを出力
  } else if (piccType == MFRC522_I2C::PICC_TYPE_MIFARE_UL) {
    mfrc522.PICC_DumpMifareUltralightToSerial();        // Mifare Ultralightのデータを出力
  } else {
    M5.Lcd.setTextColor(RED, BLACK);
    M5.Lcd.fillRect(0, 57, 320, 200, BLACK);            // 液晶のデータ表示部を黒塗りリセット
    M5.Lcd.setCursor(0, 57);                            // 座標表示
    M5.Lcd.println("This card is not supported.");      // サポートされていないカードである旨を表示
    delay(5000);
  }
  mfrc522.PICC_HaltA(); // 現在読み込んでいるカードをハルトする
  mfrc522.PCD_Init();   // RFIDリーダーを初期化する
}

カードのデータを確認するためには、まずは以下(上コード「3行目」)のようにカードの「SAK(NFCタグの識別子)」を取得します。

byte piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);

取得した「SAK」から「カードタイプ」が「MIFARE」の「MINI、1KB、4KB」であることが確認されたら、以下(上コード「8行目」)を実行することでシリアルモニタにカードの全データが表示されます。

mfrc522.PICC_DumpToSerial(&(mfrc522.uid));

「カードタイプ」が「MIFARE」の「Ultralight または Ultralight C」の場合は以下(上コード「10行目」)を実行することでシリアルモニタにカードの全データが表示されます。

mfrc522.PICC_DumpMifareUltralightToSerial();
「MIFARE」以外のカードの場合は今回対応していないため、その旨をシリアルモニタに表示します。
最後に上コード18,19行目」のように「RFID2ユニット」を初期化しています。
これを書かないと、その後の読み書きがうまく動作しなかったため書いていますが、もっと良い方法があるかもしれませんので参考としてください。

・データの読込み方法

データを読み込むには、カード内のデータ保存領域の「セクター番号, ブロック番号」を指定して以下のように「readData()」関数を実行します。

// ブロックデータ読み込み ------------------------------------------
void readData(int sector, int block) {  // (セクター番号, ブロック番号)
  MFRC522_I2C::MIFARE_Key key = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // MIFARE_Key構造体でセクター認証キーを準備(ポインタで指定するため)
  Serial.println("カードデータ読み取り");

  uint8_t address = sector * 4 + block;         // ブロックアドレスを算出
  // 読込み対象のセクターを認証する(認証キータイプ, ブロックアドレス, 認証キーポインタ, カードのUIDプロパティへのポインタ)
  if (mfrc522.PCD_Authenticate(MFRC522_I2C::PICC_CMD_MF_AUTH_KEY_A, address, &key, &(mfrc522.uid)) == MFRC522_I2C::STATUS_OK) {
    Serial.println("認証に成功しました");
    byte buffer[18];                            // 読込みデータ16byte + エラーチェック用CRC用2byte分の配列を準備
    byte bufferSize = sizeof(buffer);           // バッファサイズをポインタで指定できるように準備
    // 認証成功で読込み実行(ブロックアドレス, データ格納バッファ配列ポインタ, 読込みデータバッファサイズポインタ)
    if (mfrc522.MIFARE_Read(address, buffer, &bufferSize) == MFRC522_I2C::STATUS_OK) { // 通信成功なら
      for (int i = 0; i < bufferSize-2; i++) {  // 読込んだデータのCRCを除いた16byte分繰り返す
        read_data[i] = buffer[i];               // バッファを読み込みデータ配列に格納
        Serial.printf("%02X ", read_data[i]);   // 16byteの読み込みデータをシリアルモニタに出力
      }
      Serial.printf("\n%s\n", read_data);
    }
  } else {
    Serial.println("認証に失敗しました");
  }
  mfrc522.PCD_StopCrypto1();  // 認証済み解除
}

データを読み込むためには、まず読み込み対象の「ブロック」を含む「セクター」に対して認証を行う必要があります。
認証を行うには「セクター認証キー」が必要なため、以下(上コード「3行目」)のように「MIFARE_Key構造体」でセクター認証キーを準備し、ポインタで指定します。

MFRC522_I2C::MIFARE_Key key = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
認証キーはA、Bの2つあります。初期値はいずれも「FF FF FF FF FF FF」で、必要に応じて「セクター」ごとに変更することができます。

読み込み対象の「ブロック」は以下(上コード「6行目」)の式で「ブロックアドレス」を算出して指定します。

uint8_t address = sector * 4 + block;

次に以下(上コード「8行目」)を「認証キータイプ(AまたはB), ブロックアドレス, 認証キーのポインタ, カードのUIDプロパティへのポインタ」を指定して実行することで、読込み対象の「セクター」認証が行われます。

mfrc522.PCD_Authenticate(MFRC522_I2C::PICC_CMD_MF_AUTH_KEY_A, address, &key, &(mfrc522.uid));

認証に成功したら以下(上コード「13行目」)のように「ブロックアドレス, データ格納バッファ配列のポインタ, 読込みデータバッファサイズのポインタ」を指定して「mfrc522.MIFARE_Read()」を実行することでデータを読み込むことができます。

if (mfrc522.MIFARE_Read(address, buffer, &bufferSize) == MFRC522_I2C::STATUS_OK) { 
  for (int i = 0; i < bufferSize2; i++) { 
    read_data[i] = buffer[i];
    Serial.printf(“%02X “, read_data[i]);
  }
  Serial.printf(“\n%s\n”, read_data);
}
受信したデータは「データ格納バッファ配列(buffer)」に「18byte」で受信されます。
「buffer」配列の末尾にはエラーチェック用のデータ(CRC)が「2byte」含まれるため、必要なデータ(16byte)分を「read_data」配列に格納してシリアルモニタに表示しています。

読み込みが完了したら、最後に以下(上コード「23行目」)を実行し、認証済み状態を解除して完了です。

mfrc522.PCD_StopCrypto1();
続けて別のブロックの読み書きを行う場合は、全ての読み書きが終了してから認証済み状態を解除します。

・データの書込み方法

データを書き込むには、カード内のデータ保存領域の「セクター番号, ブロック番号」を指定して以下のように「writeData()」関数を実行します。

サンプルプログラムではシリアルモニタに入力したデータを受信したら「write_data」配列に格納してから、以下の関数を実行して書き込みを行うようにしています。
// ブロックデータ書込み -------------------------------------------
void writeData(int sector, int block) { // (セクター番号, ブロック番号)
  MFRC522_I2C::MIFARE_Key key = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // MIFARE_Key構造体でセクターキーを準備(ポインタで指定するため)
  Serial.println("カードデータ書込み");

  uint8_t address = sector * 4 + block;         // ブロックアドレスを算出
  // 書込み対象のセクターを認証する(認証キータイプ, ブロックアドレス, 認証キーポインタ, カードのUIDプロパティへのポインタ)
  if (mfrc522.PCD_Authenticate(MFRC522_I2C::PICC_CMD_MF_AUTH_KEY_A, address, &key, &(mfrc522.uid)) == MFRC522_I2C::STATUS_OK) {  // 通信成功なら
    Serial.println("認証に成功しました");
    if (address == 0 || block == 3) {                 // ブロックアドレスが0またはブロック3なら書込まず終了
        Serial.print("データブロックではないので書き込めません");
    } else {                                          // ブロック0〜2ならデータ書込み
      mfrc522.MIFARE_Write(address, write_data, 16);  // (ブロックアドレス, 書込みデータ, 書込みbyte数)
      // 書き込みデータをシリアルモニタに出力
      for (int i = 0; i < 16; i++) {            // 16byte分繰り返す
        Serial.printf("%02X ", write_data[i]);  // 16進数で出力
      }
    }
    Serial.printf("\n%s\n", write_data);
  } else {
    Serial.println("認証に失敗しました");
  }
  // カードから切断する
  mfrc522.PCD_StopCrypto1();  // 認証済み解除
}

データを書き込む場合も上コード「1〜8行目」までは読み込みと同様で、書込み対象のブロックの認証を行う必要があります。

認証に成功したら書き込みを実行しますが「ブロックアドレス0」は「UID」が格納されているため書き込みができません。

また、「各セクター」の「ブロック3」には認証キー(AとB)や各ブロックへのアクセス条件の設定(アクセスコンディション)が含まれており、不用意に書き込みを行うとアクセスできなくなる可能性があるため、以下(上コード「10〜18行目」)のように書込み対象のブロックを制限しています。

書き込みは以下(上コード「13行目」)のように「ブロックアドレス, 書込みデータ配列, 書込みバイト数(16固定)」を指定して「mfrc522.MIFARE_Write()」を実行することでデータを書き込むことができます。

if (address == 0 || block == 3) { 
  Serial.print(“データブロックではないので書き込めません”);
} else
  mfrc522.MIFARE_Write(address, write_data, 16);
// 書き込みデータをシリアルモニタに出力
  for (int i = 0; i < 16; i++) {
    Serial.printf(“%02X “, write_data[i]);// 16進数で出力
  }
}
書き込みは、ブロック内データの16byte全てを一括で書き込む必要があります。
一部を書き換える場合は、先に対象のブロック内のデータを16byte分全て「write_data」配列に読み込んで、書き換えたい要素だけ書き換えてから、書き込みを行います。

書込みが完了したら、読み込みの時と同様に、最後に以下(上コード「24行目」)を実行し、認証済み状態を解除して完了です。

mfrc522.PCD_StopCrypto1();
続けて別のブロックの読み書きを行う場合は、全ての読み書きが終了してから認証済み状態を解除します。

10.MIFARE 1KB のデータ構成について

今回使用した「非接触ICカード」の「MIFARE 1KB」を使いこなすには、内部のデータ構造を理解する必要があります。

内部のデータ構造は「データの保存領域」だけでなく「認証キー(A、B)」や「アクセス条件」を決めるデータも格納されていて少々複雑なため、以下から図を交えて詳しく紹介していきます。

・全体構成の確認

全体のデータは以下表のような構造になっています。

データ領域は「0〜15」の合計16個の「セクター」に分かれており、各セクターには4つの「ブロック」があります。

各ブロックには「ブロックアドレス」が割り当てられており「16バイト」のデータ保存領域があります。

さらに各ブロックのアクセス条件(読み書きの可否等)を設定する「アクセスビット(Access Bits)」がブロックごとに「3ビット」で設定されています。

非接触ICカードの使い方 データブロック構成

「セクター0」の「ブロック0(ブロックアドレス0)」には0〜3バイト目に「UID(固有の識別番号)」が4バイトで格納されており、このブロックは読み込み専用です。

「UID」以降のデータは工場出荷時に書き込まれ、特に意味を持ちません。

各セクターの「ブロック0〜2(セクター0は1〜2)」が自由にデータが保存できる領域です。
「ブロック3」は「セクタートレーラー」と呼ばれ認証キー等が格納されている特別なブロックです。

セクタートレーラーを不用意に書き換えてしまうと「セクター」内の「ブロック」全ての読み書きができなくなることもあるので、誤って書き換えてしまわないようにしましょう。

・セクタートレーラー

「各セクター」の「ブロック3」にある「セクタートレーラー」のデータ構造は以下表のようになっています。

非接触ICカードの使い方 セクタートレーラー
  • 0〜5バイト目:6バイトの「認証キーA
  • 6〜8バイト目:3バイトのアクセスコンディション(アクセス条件
  • 9バイト目  :1バイトのデータ領域として使用可
  • 10〜15バイト目:6バイトの「認証キーB

「各セクター」ごとに「認証キーA,B」を設定することができ、各ブロックの「アクセス条件(読み書き可否等)」はここでブロックごとに設定できます。

9バイト目のデータ領域は実際に書き換えてみてもデータの読み書きに何の影響もありませんでしたが、間違いの元になるので余程の理由がない限り、使用はしない方が良いと思います。

・認証キーA、B

「セクタートレーラー」には「各セクター」の4つの「ブロック」にアクセスするための「認証キーA,B」が設定されており、データの読み書きを行うには、毎回「認証キーAまたはB」を使用して認証を行う必要があります。

工場出荷時は「認証キーA,B」の両方とも「FF FF FF FF FF FF」が設定されています。
必要に応じて書き換えて使用することができます。

「認証キーA」は読み込むことができません。
このため、読み込むと「00  00  00  00  00  00」となります。
初期設定では書き換えられるようになっていますが、読み込んで確認することはできないため、忘れないようにしましょう。
初期設定では「認証キーA,B」どちらでも読み書きができるようになっていますが「セクタートレーラー」の「6〜8バイト目」の「アクセスコンディション(アクセス条件)」を変更することで使用する認証キーを制限することができます。

・アクセスコンディション(アクセス条件)

「各ブロック」の読み書きに使用する「認証キー」や「読み書きの可否」については「各セクター」の「ブロック3(セクタートレーラー)」の「6〜8バイト目」でブロックごとに設定することができます。

設定方法は少々複雑なので、以下表を使用して詳しく紹介していきます。


以下表の緑文字の部分が「アクセス条件」に関連する部分です。
「セクタートレーラー」の「6〜8バイト」の「各ビット」の状態から「ブロック」ごとの「アクセス条件」が決定され「Access Bits」に「3ビット」で設定されます。

非接触ICカードの使い方 アクセスコンディション

上の表では一見わかりにくいので、実際の工場出荷時の設定「FF 07 80」を「ビット」から以下表のように求めてみました。

非接触ICカードの使い方 アクセスコンディション

「Access Bits」の内容はこの後詳しく紹介しますが、まずは希望の「Access Bits」を上表の「3ビット」に設定するとわかりやすいです。

今回は工場出荷時の設定を各ブロックの「Access Bits」の「黄塗り部」に書きます。
この値を上の「各bit」表に当てはめていきます。
まずは「8byte目」の「bit」を全て埋め、次に「7byte目」の「4〜7bit」を埋めます。
残りの「青塗り部」に論理反転した値を記入して「16進数」に変換すると「セクタートレーラー」の「6〜8byte目」を求めることができます。

あとは求めた「アクセスコンディション(アクセス条件)」で「ブロック3」を書き換えれば設定完了です。

ライブラリの関数でアクセスコンディションを算出

今回使用したライブラリ「MFRC522_I2C」には設定したいアクセスビット(Access bits)から、セクタートレーラーのアクセスコンディションを算出する関数があるので以下で紹介します。

// セクタートレーラーの初期値を設定
byte sector_traler[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  // 認証キーA(初期値)
                          0xFF, 0x07, 0x80, 0x69,              // アクセスコンディション(初期値)
                          0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // 認証キーB(初期値)
byte access_bits[4];       // 各ブロックの設定したいアクセスビットを格納(下位3bit)
byte access_condision[3];  // アクセスコンディション算出結果格納用

// 各ブロック(0〜3)のアクセスビット(Access bits)を設定
access_bits[3] = 0x01;     // ブロック3(セクタートレーラー)のアクセスビットを設定([C1 C2 C3] = [0 0 1]の時「b00000001」)
access_bits[2] = 0x00;     // ブロック2のアクセスビットを設定([C1 C2 C3] = [0 0 0]の時「b00000000」)
access_bits[1] = 0x02;     // ブロック1のアクセスビットを設定([C1 C2 C3] = [0 1 0]の時「b00000010」)
access_bits[0] = 0x03;     // ブロック0のアクセスビットを設定([C1 C2 C3] = [0 1 1]の時「b00000011」)
// 各ブロック(0〜3)のアクセスビットの設定からアクセス条件(ブロック3の6〜8byte目の値)を算出
mfrc522.MIFARE_SetAccessBits(access_condision, access_bits[0], access_bits[1], access_bits[2], access_bits[3]);

// 算出したアクセスコンディションをセクタートレーラーの6〜8byteに設定
for (int i = 0; i < 3; i++) {
  sector_traler[i + 6] = access_condision[i];
}
// 液晶、シリアルモニタ表示
M5.Lcd.setTextColor(GREEN, BLACK);
M5.Lcd.printf("AccessBits : [");
Serial.print("Access_condision: [");
for (int i = 0; i < 3; i++) {
  M5.Lcd.printf("%02X ", sector_traler[i + 6]);
  Serial.printf("%02X ", access_condision[i]);
}
M5.Lcd.println("]");
Serial.println("]");

上コードの「9〜12行目」で各ブロックのアクセスビットを「access_bits」配列の下位3bitで設定します。
次に以下(上コードの「14行目」)を実行すると「access_condision」配列に3byteでアクセスコンディションが生成されます。

mfrc522.MIFARE_SetAccessBits(access_condision, access_bits[0], access_bits[1], access_bits[2], access_bits[3]);

上コードでは液晶画面とシリアルモニタに「アクセスコンディション」が「3byte」で表示されるようにしています。

生成された「アクセスコンディション」を「セクタートレーラー(ブロック3)」の「6〜8byte目」と置き換えて書き込むと設定が完了します。

「アクセスコンディション(アクセス条件)」に間違った値を書き込むと、セクターごと読み書きができなくなることもあるので、よく確認して慎重に行ないましょう。

・設定可能な「Access Bits」

設定可能な「アクセスコンディション」は「セクタートレーラー」と「データブロック」で異なり、それぞれ以下表のようになります。

表の見方について
・Read:読み込み/Write:書き込み
・key A:認証キーAで可/key B:認証キーBで可/key A|B:どちらでも可
・×:不可

セクタートレーラーの「Access Bits」

「セクタートレーラー」の「アクセスビット(Access Bits)」では以下表のような設定ができます。

「認証キーA,B」と「Access Bits」の読み書き(Read/Write)の可否と、読み書きに使用する「認証キー」を設定できます。

非接触ICカードの使い方 アクセスビット
初期設定の[0 0 1]では「KEY A」の読み込み以外は全て「KEY A」で読み込みできます。
[1 1 1]では「Access bits」の読み込みのみでそれ以外の読み書きができなくなります。
「Access bits」の書き込みを不可に設定すると、他の設定に変更することができなくなるので、慎重に行いましょう。

データブロックの「Access Bits」

「データブロック」の「アクセスビット(Access Bits)」では以下表のような設定ができます。

各ブロックのデータの読み書き(Read/Write)の可否と、読み書きに使用する「認証キー」を設定できます。

非接触ICカードの使い方 アクセスビット
初期設定の[0 0 0]では「認証キーA,B」どちらでも全ての操作が可能です。
[0 1 0]では「認証キーA,B」はどちらでも良いですが読み込みしかできません。
[1 1 1]では何の操作もできません。
他にも値の加算、減算等の設定ができるようですが今回は未確認のため、確認できたらまた紹介したいと思います。

11.まとめ

「非接触ICカード」について、RFID(NFC)技術の用語や仕組み、データの読み書き方法について、カードのデータ構成も含めて使い方を詳しく紹介しました。

データの読み書き方法だけ確認する予定でしたが「認証キー」や「アクセス条件」等、思った以上に複雑で長文となり、結構時間がかかりましたw

おかげで自分でも「非接触ICカード」の仕組みや使い方をよく理解することができたので良い経験になりました。
自分では、あえて何かを作るというわけではないのですが・・・目的を持って読んでくださった方の参考になればと思います。

今回は「MIFARE 1KB」だけしか動作確認できませんでしたが、今回使用した「MFRC522_I2C」ライブラリでは他の規格のものも使用できそうです。

手持ちでは「xyzプリンティング」社製の3Dプリンター「ダヴィンチmini w+」のフィラメントに内蔵されているタグが「Ultralight C」でした。
純正以外のフィラメントを使って壊れるのも困るので他社品を使うつもりはなかったのですが、これを書いている段階で「xyzプリンティング社」が3Dプリンター事業から撤退するとのことで・・・今後どうなるかわかりませんが、フィラメントが買えなくなると困るので、今のうちに解析して書き換えられるようにしておきたいと思います♪

ダヴィンチmini w+ 3Dプリンタの使い方①開梱・設置編
ダヴィンチmini w+の使い方としてまずは開梱から設置方法について、特徴や選定理由(メリット・デメリット)注意点等、評価・レビューを交えて詳しく紹介していきます。

コメント

タイトルとURLをコピーしました