
スーパーマーケットのセルフレジを利用したことがあるなら、商品をトレイに置くと画面に自動的に表示される様子を見たことがあるはずです。これは魔法でもなければ、超能力によるテレパシーでもありません。無線周波数を利用したシステムで、直接触れることなく物体を識別できるのです。ArduinoとRC522のような安価なリーダーを使えば、自宅でも簡単に再現できます。
このガイドでは、ArduinoとRC522 RFIDリーダーを使ってタグの読み書きを行う方法、RFIDとは何か、どのようなシステムが存在するのか、パッシブカードへの電源供給方法、MIFARE Classic 1Kカードのメモリ構成、そしてアクセス制御システムや充電式交通カードといった実用的なプロジェクトの構築方法を、ステップバイステップで解説します。これからこのテーマを徹底的に掘り下げていきますが、分かりやすく丁寧に説明していきますので、どうぞリラックスしてお読みください。
RFID技術とは何ですか?また、どのように機能するのですか?
無線周波数識別(RFID)とは、無線で送信される固有の識別子を用いて物体を識別するシステムです。この識別子は通常UID(Unique ID)と呼ばれ、タグのIDと考えることができます。システム全体は、RFIDタグ(またはトランスポンダ)とRFIDリーダー(トランシーバ)という2つの主要な要素で構成されています。
RFIDタグには、クレジットカードのようなプラスチックカード、キーホルダー、盗難防止のために製品に貼り付ける粘着ステッカー、さらには動物の皮膚の下に埋め込んで識別するチップなど、さまざまな形態があります。内部構造はすべて共通しており、アンテナと、情報を保存してリーダーと通信する小型チップで構成されています。
タグには、UIDが工場出荷時にプログラムされており変更できない読み取り専用タグと、RC522モジュールなどの適切なリーダーでデータの読み書きが可能な読み書きタグがあります。これにより、チャージ式交通カード、プリペイド残高付き入退室管理システム、勤怠管理システムなど、さまざまなアプリケーションが可能になります。
一方、RFIDリーダーまたはトランシーバーという装置があります。この装置はデータを受信するだけでなく、無線周波数電磁界を発信します。この電磁界は、パッシブタグがどのように電源供給され、カードとリーダー間でどのように情報が交換されるかを理解する上で重要な要素となります。
RFIDタグの電源供給と動作原理
よくある質問の一つに、スーパーマーケットの商品やアクセスカードに貼られているRFIDタグには電池が入っていないのに、一体どこからエネルギーを得ているのか、というものがあります。重要なのは、これらのタグの多くは受動型であり、リーダーが生成する電磁場からの電磁誘導によって電力を供給されているということです。
パッシブタグをリーダーに近づけると、タグのアンテナがモジュールによって生成される電磁場(例えば、RC522の場合は13,56MHz)に入ります。この電磁場によってタグのアンテナに電流が誘導され、その電流が内部チップに一時的に電力を供給します。チップが起動すると、リーダーに送り返す信号を変調し(これをバックキャッタリングと呼びます)、UIDと、該当する場合はメモリに保存されているその他のデータをエンコードします。
赤外線などの技術とは異なり、タグとリーダーの間に直接的な視線は必要ありません。無線周波数は特定の物質を透過できますが、その挙動は周波数、金属や水などの存在によって異なります。リーダーは後方散乱信号を捕捉し、それを解釈して、マイクロコントローラー(Arduino、ESP8266、ESP32など)またはコンピューターにデータを送信します。
周波数によるRFIDシステムのタイプ
無線周波数スペクトルは非常に広く、電波はすべての周波数で同じように振る舞うわけではありません。そのため、RFIDでは用途に応じて異なる周波数帯が使用されます。ラジオが正しい放送局にチューニングする必要があるのと同様に、リーダーとタグは同じ周波数で動作するように設計する必要があります。
一般的に、RFIDシステムは使用する周波数帯域に応じて、大きく3つのカテゴリーに分類できます。
- 低周波(LF): 約125~134kHz。
- 高周波(HF): 約13,56MHzで、MIFAREやNFCなどの技術が含まれます。
- 超高周波(UHF):約433MHzから860~960MHzの間。
低周波(LF)RFIDシステム
低周波RFIDシステムは波長が比較的長いため、薄い素材や、果物や飲料など水分含有量の多い物体をより効果的に透過できます。また、薄い金属の近くでも比較的良好な性能を発揮します。
しかし、この利点には重大な制約が伴います。通信範囲は通常わずか数センチメートルで、データ伝送速度も低いため、メモリ容量が制限され、タグのコストが高くなります。これらのシステムは、シンプルなアクセス制御、旧式の近接キー、動物のタグ付けなどに一般的に使用されています。
高周波(HF)RFIDおよびNFCシステム
13,56MHzの高周波帯域は、おそらく「メーカー」やDIYプロジェクトのレベルで最も人気があるでしょう。なぜなら、この帯域にはMIFAREカードやNFC(近距離無線通信)技術が搭載されており、多くの携帯電話が非接触決済に利用しているからです。
HFシステムは金属の近くや中程度から多量の水が存在する環境でも良好に動作し、理想的な条件下では通常数センチメートルから約1メートルの通信範囲を提供します。データ転送速度は控えめですが、識別、アクセス、および小規模なデータ転送アプリケーションには十分です。多くの国際標準がHFをベースとしているため、機器やカードの相互運用性が向上します。
超高周波(UHF)RFIDシステム
その対極にあるのがUHFシステムで、数センチメートルから20メートル以上の距離まで通信可能です。倉庫での在庫管理、イベントでの人数カウント、レースでのアスリートのタイム計測など、多数のタグを遠距離から迅速に読み取る必要がある場合に最適です。
欠点としては、波長が短いため信号の減衰が大きく、金属や水を透過しにくい点が挙げられる。それでもなお、料金徴収システム、駐車場の入退場管理、大規模な物流追跡などに広く利用されている。
RC522 RFIDモジュール:機能とピン配置
Arduinoプロジェクトで最も人気のあるリーダーの一つは、NXP社のMFRC522チップをベースにしたRC522です。これは非常に手頃な価格で広く使われているモジュールで、MIFAREカードと連携して高周波(13,56MHz)で動作し、互換性のあるタグへの読み書きの両方が可能です。
通常は、リーダー本体、クレジットカード、RFIDキーフォブがセットになったキットとして販売されます。これらのカードは一般的に1Kまたは4KのMIFARE Classicカードで、輸送、アクセス制御、低コストソリューションで非常に普及している規格です。RC522は高周波電磁界を発生させ、実際には有効範囲は約3~5cmですが、理論的にはもう少し遠くまで届く可能性があります。
マイクロコントローラとの通信に関して、RC522は主にSPI(シリアルペリフェラルインターフェース)を介して統合されており、最大10Mbpsの速度をサポートしています。I2CとUARTもサポートしていますが、ほとんどのArduinoプロジェクトでは、速度とシンプルさの点でSPIが使用されます。
電気的には、このモジュールは2,5V~3,3Vの電源電圧で動作します。通常、基板には3,3Vに接続するためのVCCピンが明確に表示されています。5Vを直接供給すると、モジュールが破損する恐れがありますのでご注意ください。利点としては、ロジックレベルは一般的に5Vまで許容されるため、基本的なテストであればレベルコンバータなしでArduino UNOのデジタルピンに接続できますが、本格的な設計ではレベル調整を行うことをお勧めします。
RC522モジュールのピン留め
一般的なRC522には、マイクロコントローラへの接続ピンが8本あります。
- VCC電源電圧は2,5V~3,3Vです。
- RST: リセットピン。レベルをLOW/HIGHに設定することで、モジュールの電源をオフにしたり再起動したりできます。
- GND:地球の質量または基準。
- IRQ: タグが読み取りフィールドに入ったときにマイクロコントローラに警告を発する割り込みピン。
- MISO / SCL / TX: 多機能ピン。例えば、SPI の MISO、I2C の SCL、UART の TX など。
- MOSI: SPIにおけるマスターからスレーブへの出力データライン。
- SCK: SPIインターフェースクロック。
- SS / SDA / RX: SPI のスレーブ選択ピン、I2C の SDA、または UART の RX。
Arduino UNOやその他のATmega328Pベースのボードでは、SPIピンはハードウェアによって既に定義されているため、SPIを使用する際の一般的な接続図は次のようになります。
- VCC → Arduinoからの3,3V。
- GND → ArduinoのGND。
- SCK → UNO/Nanoの13番ピン。
- MOSI → UNO/Nanoの11番ピン。
- 味噌 → UNO/Nanoの12番ピン。
- SS(SDA) → ピン10(またはSSとして選択したピン。ただし、コード内で指定する必要があります)。
- RST → 例えば、Arduinoのピン9。
- IRQ → オプション。割り込みを使用しない場合は接続しなくても構いません。
Arduino Mega、Leonardo、Microなどのボードでは、SPIラインが異なるピンやICSPコネクタに接続されている場合があるため、配線を行う前に公式ドキュメントの対応表を確認することが重要です。
MFRC522ライブラリのインストールと基本的なタグ読み取り
MFRC522はゼロからプログラムすることも可能ですが、内部通信が非常に複雑なため、 GitHubおよびArduino IDEのライブラリマネージャで入手可能な、 Miguel Balboa氏が開発したライブラリを使用するのが一般的です。このライブラリには、リーダーの初期化、カードの検出、セクターの認証、ブロックの読み書きに必要なすべての操作がカプセル化されています。
Arduino IDEからインストールするには、ライブラリマネージャを開き、「MFRC522」を検索して、コミュニティがメンテナンスしているバージョン(GitHub Community)を選択するだけです。また、IDEに既に含まれているSPIライブラリも追加する必要があります。
インストール後、ラベルのUIDを読み取るためのシンプルなスケッチにおける一般的な流れは次のとおりです。
- 書店を含める SPI.hy MFRC522.h.
- リーダーが使用するRSTピンとSSピンを定義します。
- 指定されたピンを渡して、MFRC522オブジェクトを作成します。
- setup() では、シリアル、SPI、およびリーダーを初期化します。 PCD_Init().
- loop() では、 PICC_IsNewCardPresent() 近くにカードがあるかどうか調べて、 PICC_ReadCardSerial() 基本データを読み取ります。
- UIDにアクセスするには、 mfrc522.uid.uidByte そして、mfrc522.uid.size でサイズを指定します。
- ラベルとの連絡を終了するには、 PICC_HaltA().
このタイプのスケッチは、複数のカードやキーフォブのUIDを取得し、簡単なテストを実行するのに最適です。例えば、読み取ったUIDを承認済みUIDのリストと比較するだけのシンプルなアクセス制御などに適しています。
MIFARE Classic 1Kカードのメモリ構造
RC522に付属するカードは通常、MIFARE Classic 1Kです。これらのカードは、セクターとブロックに階層的に構成された1KBのメモリを提供し、書き込みを行う前に理解しておくべき、やや特殊なキーとアクセス権限システムを備えています。
メモリ全体は0から15までの番号が付けられた16個のセクターに分割されています。各セクターには、セクター内で0から3までの番号が付けられた4つのブロックが含まれています。各ブロックには16バイトのデータが格納されます。つまり、0から15までの番号が付けられた16個の位置が格納されるため、各セクターは64バイトのデータを提供します。
各セクターに4つのブロックがありますが、そのうちユーザーデータの保存に使用されるのは、各セクターのブロック0、1、2の3つのみです(ただし、セクター0は特別な特性を持っています)。各セクターの最後のブロックであるブロック3は、トレーラーブロックと呼ばれています。このブロックには、暗号化キーと、そのセクターで許可される操作を制御するアクセスビットが格納されます。
予告編では、16バイトは以下のように分割されています。
- キーA: 6 バイト。
- アクセス条件: 読み取り/書き込み権限、認証、およびキーの可視性を定義する3バイト。
- 未使用バイト (U): 使用されていない1バイト。
- キーB: 6 バイト。
工場出荷時にモジュールと共に出荷されるカードは、通常、キーAとキーBがFF FF FF FF FF FFに初期化されていますが、これは非常に安全性が低く、規格を知っている人であれば誰でもカードの内容を認証および変更できてしまいます。DIYプロジェクトでは、すべてのセクターで同じキーを使用することが比較的よく行われますが、真のセキュリティを確保するには、キーを分散させる方が良いでしょう。
さらに、セクター0のブロック0は特殊で、カードのUID(通常、これらのMIFARE Classicカードでは4バイト)と製造元データが格納されています。このブロックは実際には読み取り専用とみなされており、変更しようとするとカードが取り返しのつかないほど破損する可能性があります。
セクター内のキーAとキーBを変更する
ArduinoとRC522を使ったプロジェクトでMIFAREカードを効果的に使用したい場合は、まずデフォルトのキーを変更する必要があります。これにより、リーダーと標準ライブラリを持っている人が許可なくカードを改ざんすることを防ぐことができます。
特定のセクター(例えばセクター15)のキーを更新するための基本的な考え方は次のとおりです。
- コード内で現在のキーを定義します(変更されていない場合は、工場出荷時のデフォルト値を使用します)。
- その分野で使用したい新しいキーワードAとキーワードBを定義してください。
- そのセクターのトレーラーブロック番号を計算します。 セクター * 4 + 3 (セクター15、ブロック63の場合)
- 現在のキーAを使用して最初に認証します PCD_Authenticate() トレーラーブロックについて。
- 予告編ブロックを読んでください MIFARE_Read() あなたのコンテンツを取得します。
- バッファ内の新しいキーに対応するバイト列を変更します。
- 必要に応じて再度認証を行ってください(例えば、キーBを使用して)。
- 更新されたトレーラーブロックを次のように記述します。 MIFARE_Write().
この処理中は、操作が完了するまでカードをリーダーから動かさないことが非常に重要です。トレーラーブロックへの書き込みが中断されると、セクターにアクセスできなくなる可能性があるためです。キーを変更したら、そのセクターに対する今後の操作でこれらの新しいキーを使用するように、Arduinoコードも更新する必要があります。
読み書きブロック:交通カードのシミュレーション
MIFARE Classicを使った読み書きの非常に分かりやすい応用例として、チャージ式の公共交通機関カードの動作をシミュレートすることが挙げられます。その仕組みはシンプルです。カードには特定のブロックに一定回数の乗車回数が保存され、システムによって乗車回数をチャージ(再チャージ)したり、乗車時に認証(バスや路面電車への乗車時に認証)したりすることができます。
この目的のために、例えばセクター15をユーザーデータ用に予約し、そのデータブロックの1つ(例えばブロック60)をトリップカウンターの格納に使用することができます。利用可能なトリップ数は、ブロックの0バイト目に格納されます。ブロックの残りのバイトは、他のデータに使用することも、単にゼロのままにしておくこともできます。
リロード部分の典型的なコードの流れは次のようになります。
- 定義する キーAとキーB 当該分野を保護する現行の規制(例えば、前のステップで変更した規制など)。
- セクター番号、データブロック(60)、およびトレーラーブロック(63)を定義します。
- 最初のバイトが旅行回数を表す16バイトの配列(blockData)を宣言します。
- カードがリーダーに近づけられるたびに、 ブロック60を読み込む MIFARE_Read() を使用して現在の旅行情報を取得します。
- 読み取った値に、充電のために往復した回数(例えば10回)を加算します。
- データを更新します。新しい旅行回数でブロックを作成します。
- キーAを使用して、対応するトレーラーブロックに対して認証を行います。
- ブロック60を書き込む MIFARE_Write().
- 値が正しく更新されていることを確認するために、もう一度読み取ってください。
乗車回数計測部分(バス車内での検証)のコードはほぼ同じですが、加算ではなく減算が行われます。減算を行う前に、読み取った値がゼロかどうかを確認します。乗車回数が残っていない場合はアクセスが拒否され、ユーザーに再読み込みを促します。カウンターがゼロより大きい場合は、デクリメントされ、ブロックが書き換えられ、残りの乗車回数が画面に表示されます。
どちらの場合も、MFRC522ライブラリ関数の戻りコード(認証エラーや書き込みエラーなど)を正しく処理し、各サイクルの最後に必ずPCD_StopCrypto1()とPICC_HaltA()を使用してカード自体の暗号化通信を停止することが重要です。
UIDに基づいたシンプルなアクセス制御
RC522とArduinoを使ったもう一つの定番プロジェクトは、提示されたボードのUIDに基づいて入退室を許可または拒否する基本的なアクセス制御システムです。この方式ではボードの内部メモリは使用せず、固有識別子のみを使用するため、セキュリティ面ではかなり制限がありますが、手軽な例として役立ちます。
一般的なアプローチは次のとおりです。
- 基本ライブラリ関数(PICC_IsNewCardPresent、PICC_ReadCardSerialなど)を使用してカードのUIDを読み取ります。
- 読み取ったUIDのバイト列を一時配列(例:ActualUID)にコピーします。
- コード内で、認証済みカードのUID(例:User1、User2)を含む複数の配列を定義します。
- バイト配列比較関数を作成し、 両方が同一の場合は真.
- ActualUIDを各認証済みUIDと比較し、一致するものがあれば、デジタル出力をアクティブにするか、「アクセス許可」メッセージを表示するか、電気錠を作動させる。
- いずれにも一致しない場合は、「アクセス拒否」と表示してシステムを閉じたままにします。
実際の環境では、このようなシステムはタグのクローン作成に対して脆弱です。なぜなら、多くの安価なリーダーではUIDのコピーやエミュレーションが可能だからです。セキュリティを強化するには、カードの内部メモリ、カスタムキー、そしておそらくはMIFARE Classicよりも堅牢な暗号化メカニズムを使用する必要があるでしょう。MIFARE Classicのセキュリティは現在広く疑問視されています。それでもなお、このシステムはカード読み取りワークフローと物理アクチュエータとの統合を学ぶための優れた教育例として役立ちます。
上記すべてを通して、あなたはRFIDの基本概念をしっかりと理解し、異なる周波数帯の挙動を把握し、MIFARE Classic 1Kカードの内部構造を理解し、RC522モジュールとArduinoの基本的な接続と使用方法を習得し、アクセス制御や交通系ICカードなどの実世界のシステムを構築するためのブロックの読み書き方法を詳細に理解しました。ここから、次の自然なステップは、RFIDを他のモジュール(LCDスクリーン、リレー、Wi-Fi、クラウドデータベース)と組み合わせ、スマート電球を制御する方法を学び、店舗、公共交通機関、非接触決済端末などで日常的に目にするプロフェッショナルなシステムにさらに近い、より包括的なソリューションを構築することです。
