10月4日(土)・5日(日) Maker Faire Tokyo 2025に量子アニーリングでプラレール衝突回避を出展します☆彡
Raspberry Pi / Arduino

New!! RFIDセンサーでいろいろなカードを読み取ってみた

AI要約

RFIDリーダーRC522を用いて、クレジットカードや交通系ICカードの読み取り実験を行いました。センサーは安価に手に入ります。Arduinoへの接続方法やセンサーの検出範囲を紹介します。

やること

RFIDセンサーを使ってみましょう。ユニクロのカゴまるごと会計できるアレですね。

安いものだとセンサーは数百円、タグは数円と非常に安価です。

JR東日本のホームドア無線連携システムにも利用され始めています。2025年現時点で南武線、中央線、湘南新宿ラインに実装されているようです。

RFIDセンサー

RFID(Radio Frequency Identification)は、RFタグとリーダーライタ間で近距離無線通信によって情報をやり取りする技術です。

Amazonで安く売られているRFIDセンサー「RC522」を購入しました。白いカードタグと青いキーホルダータグも付いてきました。タグが電源を必要としないタイプをパッシブ型と呼び、検出距離は短めとのこと。

Arduinoで動作確認してみましょう。次のように接続します。電源は3.3Vです。

MFRC522 ReaderArduino Uno Pin
RST9
SDA(SS)10
MOSI11(ICSP)
MISO12(ICSP)
SCK13(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に変更したのです。

リアクションのお願い

「参考になった!」「刺激された!」と思ったらぜひリアクションをしましょう。エンジニアの世界はGive and Takeによって成り立っています。これからも無料で良質な情報にアクセスできるよう、Giveする人への感謝をリアクションで示しましょう!

この記事をシェアする

自身のブログ等で使用する場合は引用を忘れずに!

また、寄付も受け付けています。コーヒー1杯でとても喜びます(*˘︶˘*)

 Amazonでギフト券(アマギフ)を贈る

こちらのリンク から金額を指定してお贈りください。(デフォルトで10000円になっているのでご変更ください)

配送:Eメール
受取人:staffあっとvigne-cla.com
贈り主:あなたのお名前やニックネーム
メッセージ:◯◯の記事が参考になりました。など

のようにご入力ください。見返りはありませんのでご了承ください。

 Amazonで食事券(すかいらーく優待券)を贈る

500円 1000円 2000円 5000円 からお贈りください。

配送:Eメール
受取人:staffあっとvigne-cla.com
贈り主:あなたのお名前やニックネーム
メッセージ:◯◯の記事が参考になりました。など

のようにご入力ください。見返りはありませんのでご了承ください。

 その他、ギフト券やクーポン券をメールで贈る

デジタルのギフト券/クーポン券はメールアドレス(staffあっとvigne-cla.com)までお送りください。受領の返信をいたします。
紙のギフト券/クーポン券は 「郵便物はこちらへ」の住所 まで送付してください。名刺やメールアドレスを同封していただければ受領の連絡をいたします。
余った株主優待券等の処理におすすめです。
いずれも見返りはありませんのでご了承ください。

不明点はSNSでお気軽にご連絡ください

ビネクラのTwitter・Youtubeでコメントをください!


Slack・Discordの場合はこちらの公開グループに参加してShoya YasudaまでDMをください!


※当ブログに関することは何でもご相談・ご依頼可能です。

この記事を書いた人
Yasuda

博士(理学)。専門は免疫細胞、数理モデル、シミュレーション。米国、中国で研究に携わった。遺伝的アルゴリズム信者。物価上昇のため半額弁当とともに絶滅寸前。

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