AI要約
RFIDリーダーRC522を用いて、クレジットカードや交通系ICカードの読み取り実験を行いました。センサーは安価に手に入ります。Arduinoへの接続方法やセンサーの検出範囲を紹介します。
やること
RFIDセンサーを使ってみましょう。ユニクロのカゴまるごと会計できるアレですね。
安いものだとセンサーは数百円、タグは数円と非常に安価です。
JR東日本のホームドア無線連携システムにも利用され始めています。2025年現時点で南武線、中央線、湘南新宿ラインに実装されているようです。
RFIDセンサー
RFID(Radio Frequency Identification)は、RFタグとリーダーライタ間で近距離無線通信によって情報をやり取りする技術です。
Amazonで安く売られているRFIDセンサー「RC522」を購入しました。白いカードタグと青いキーホルダータグも付いてきました。タグが電源を必要としないタイプをパッシブ型と呼び、検出距離は短めとのこと。

Arduinoで動作確認してみましょう。次のように接続します。電源は3.3Vです。
MFRC522 Reader | Arduino Uno Pin |
---|---|
RST | 9 |
SDA(SS) | 10 |
MOSI | 11(ICSP) |
MISO | 12(ICSP) |
SCK | 13(ICSP) |
MOSI、MISO、SCKの3つはICSP規格で、Arduinoの決められたピンに挿す必要があります。複数のリーダーを1つのArduinoに接続する場合、この3つは共有で問題ない。RSTとSDAはリーダーごとに別にする。また、2枚以上のリーダーを繋ぐ場合は3.3Vを外部から取る必要あり。
コード
Arduino IDEで「MFRC522」ライブラリをインストールします。
タグを検出したらATQA、SAK、カードタイプ、固有番号(UID)を表示するコードです。
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 9
#define SS_PIN 10
MFRC522 rfid(SS_PIN, RST_PIN);
void setup() {
Serial.begin(9600);
SPI.begin();
rfid.PCD_Init();
Serial.println("RC522 RFID Reader Ready");
Serial.println("---------------------------");
}
// --- SAK値の説明 ---
String getSAKDescription(uint8_t sak) {
if (sak == 0x04) return "MIFARE Ultralight / NTAG(小容量タグ・交通系やNFC機器などに使用)";
if (sak == 0x08) return "MIFARE Classic 1K(社員証・学生証・交通ICカードなどに広く使用)";
if (sak == 0x18) return "MIFARE Classic 4K(大容量タイプ・ビル入退室管理や電子マネーなど)";
if (sak == 0x00) return "ISO14443-4 Type A(NFC Type 4対応・スマートフォンや多機能カード)";
if (sak == 0x20) return "MIFARE DESFire(高セキュリティタイプ・交通機関・大学IDなど)";
return "不明(登録外または特殊なカード)";
}
// --- ATQA値の説明 ---
String getATQADescription(uint8_t b0, uint8_t b1) {
if (b0 == 0x04 && b1 == 0x00) return "MIFARE Classic 1K / 4K(汎用ICカード・社員証・交通ICなど)";
if (b0 == 0x44 && b1 == 0x00) return "MIFARE Ultralight / NTAG(シール型・チケット・NFCタグなど)";
if (b0 == 0xE6 && b1 == 0x3F) return "複合タイプ(OEM製・複数規格対応タグなど)";
if (b0 == 0x00 && b1 == 0x04) return "ISO14443 Type B(特殊用途・工業機器など)";
return "不明(登録外または非対応のカード)";
}
void loop() {
byte atqa[2];
byte atqaSize = sizeof(atqa);
// ATQAを先に取得
MFRC522::StatusCode status = rfid.PICC_RequestA(atqa, &atqaSize);
if (status != MFRC522::STATUS_OK) {
delay(50);
return;
}
// --- ATQA 表示 ---
Serial.print("ATQA: 0x");
if (atqa[0] < 0x10) Serial.print("0");
Serial.print(atqa[0], HEX);
Serial.print(" 0x");
if (atqa[1] < 0x10) Serial.print("0");
Serial.print(atqa[1], HEX);
Serial.print(" → ");
Serial.println(getATQADescription(atqa[0], atqa[1]));
// UID・SAK取得
if (!rfid.PICC_ReadCardSerial()) {
Serial.println("カード読み取り失敗");
delay(200);
return;
}
// --- SAK 表示 ---
uint8_t sak = rfid.uid.sak;
Serial.print("SAK: 0x");
Serial.print(sak, HEX);
Serial.print(" → ");
Serial.println(getSAKDescription(sak));
// --- カードタイプ ---
MFRC522::PICC_Type piccType = rfid.PICC_GetType(sak);
Serial.print("Card Type: ");
Serial.println(rfid.PICC_GetTypeName(piccType));
// --- UID表示(HEX)---
Serial.print("UID (hex): ");
for (byte i = 0; i < rfid.uid.size; i++) {
if (rfid.uid.uidByte[i] < 0x10) Serial.print("0");
Serial.print(rfid.uid.uidByte[i], HEX);
if (i != rfid.uid.size - 1) Serial.print(":");
}
Serial.println();
// --- 後処理 ---
rfid.PICC_HaltA();
rfid.PCD_StopCrypto1();
Serial.println("---------------------------");
delay(500);
}
白いカードを読み取る↓
ATQA: 0x04 0x00 → MIFARE Classic 1K / 4K(汎用ICカード・社員証・交通ICなど)
SAK: 0x8 → MIFARE Classic 1K(社員証・学生証・交通ICカードなどに広く使用)
Card Type: MIFARE 1KB
UID (hex): 66:42:6F:97
青いタグを読み取る↓
ATQA: 0x04 0x00 → MIFARE Classic 1K / 4K(汎用ICカード・社員証・交通ICなど)
SAK: 0x8 → MIFARE Classic 1K(社員証・学生証・交通ICカードなどに広く使用)
Card Type: MIFARE 1KB
UID (hex): 15:9F:7D:00
クレジットカード1↓
ATQA: 0x04 0x00 → MIFARE Classic 1K / 4K(汎用ICカード・社員証・交通ICなど)
SAK: 0x20 → MIFARE DESFire(高セキュリティタイプ・交通機関・大学IDなど)
Card Type: PICC compliant with ISO/IEC 14443-4
UID (hex): 61:E3:F3:BF
クレジットカード2↓
ATQA: 0x44 0x00 → MIFARE Ultralight / NTAG(シール型・チケット・NFCタグなど)
SAK: 0x20 → MIFARE DESFire(高セキュリティタイプ・交通機関・大学IDなど)
Card Type: PICC compliant with ISO/IEC 14443-4
UID (hex): 04:35:08:12:87:63:80
検出距離・範囲
検出距離はカードが6cm程度、タグが3cm程度でした。リーダーに表裏はないようで、裏側から近づけても同じ検出距離でした。
いい感じの距離と向きにしないと検出しない/読み取りエラーになります。
検出しない↓

検出する↓

いろいろ試した結果、こんな感じの検出範囲でした。

図示してしまえば、小さいタグよりも大きいカードのほうが検出力が強いのも合点がいきます。
検出するカード
手元にあったいろいろなカードをかざしてみました。
検出しない
タッチ決済対応マークのないクレジットカード、大学の学生証(職員証)、キャッシュカード、Tポイントカード、運転免許証、健康保険証、交通系IC(Suica、Kitaca)
検出した
タッチ決済対応マークのあるクレジットカード

安物のRC522ではほぼ検出しないもよう。
ちょっと不思議なのが楽天カードです。2020年に発行された旧カードはタッチ決済対応マークはあるもののタッチ決済はできないものでした(希望すれば機能を付けられたが、希望しなかった)。これはRFIDリーダーで検出しました。2025年に発行された新カードはタッチ決済対応マークはないがタッチ決済はでき、RFIDリーダーでは検出しませんでした。
つまり実際にタッチ決済できるかどうかではなくマークの有無に準ずることになります。旧カードのタッチ決済はRFID(マークはRFIDを意味する)で、新カードは異なる方式でタッチ決済しているのかもしれませんね。しらんけど( ˘ω˘ )
おわりに
「量子アニーリングでプラレールの衝突回避」の第2弾にこのRFIDが使用されています。第1弾はカメラでARマーカーを認識して車両の位置を特定していましたが、第2弾ではカメラを廃止してRFIDに変更したのです。