arrow-right hamburger logo-mark social-facebook social-github social-twitter
2018.05.09

非接触ICタグで遊ぼう!ArduinoでRFIDリーダRC522を使う方法

ちゃんとく

電子工作レシピ

こんにちは、ちゃんとくです。

みなさんは「認証機能」というとどんなイメージを持つでしょうか?

auth

Webページを開いて、IDとパスワードを入力して、ログインして……。「めんどくさい!もっと簡単に認証したい!」ということもありますよね。

そんなときは非接触ICタグを使って、ピッとして認証できる装置を作ってみましょう!

touch
今回はArduinoとRFIDリーダを使って、非接触ICタグをかざすと登録されたユーザかどうか判定するデバイスを作ってみます!

※ただし今回の実装はセキュリティ対策を施していないので、ご家庭内や趣味の範囲でお試しください。

RFID?NFC?非接触IC?

RFID」とは、電磁界や電波を用いて情報を埋め込んだRFタグとやりとりする無線通信技術です。「NFC」はRFタグの規格の一つで、正式名称はNear Field Communication(近距離無線通信)と言います。

非接触ICは、読み取り端末にかざすことで通信ができる電池レスのICです(電池内臓の場合もあります)。

世界で利用されているMifare(マイフェア)カードやTaspoでは「ISO/IEC 14443 Type A」というNFCの規格、日本で利用されている交通系ICカードでは「FeliCa」という規格が主に利用されています。

今回利用するRFIDリーダライタのRFID-RC522では、FeliCa規格のICは読み取ることができません。FeliCaを利用したい場合はSony製のPaSoRiやFeliCaリーダライタRC-S620Sなどを使ってみてください。

今回使うもの

use
今回はArduinoまたは互換ボード(写真はGenuino 101)、RFIDリーダライタRC522、その他に判定用のLEDやブレッドボード、ジャンパワイヤを利用します。

Arduino/互換ボード

genuino
Arduinoや互換ボードを利用すると、RC522ライブラリをそのまま使えて簡単です。写真ではGenuino 101(※)を使っていますが、今回使うピンの配置はArduino Unoと全く同じです。

Arduino Mega、Nano v3、Microなども利用できますが、ピンの接続箇所が変わるので今回利用するMFRC522ライブラリPin Layoutを参考に配線してください。

※Genuino 101はBluetooth搭載のIntel製ボードで、色が好きなので多用しています。ディスコンになってしまったけど……。

RFID-RC522

rc522set
安価で入手しやすいRFIDリーダライタです。ライブラリ側でドキュメントとサンプルコードが用意されていて、Arduinoで扱いやすいです。過出力や電波の不要輻射を防ぐため、3.3Vで利用します。

※RFID-RC522では、FeliCa規格のICは読み取ることができません。FeliCaを利用したい場合はSony製のPaSoRiやFeliCaリーダライタRC-S620Sなどを使ってみてください。

rc522
例えばAmazonで「RC522」を検索すると、価格帯の違うものがたくさんでてきますお届け時期発送元(Amazon.co.jpからだと安心かも)、送料レビュー などに注意して購入しましょう!

ちゃんとくは急いでいたので、Amazon.co.jpが発送する翌日受け取りできるものを購入しました。

solder

ピンヘッダは未実装の状態で届くので、好きな角度の方をはんだづけしておきます(かっこいい!と思ってくの字型のピンヘッダを使いましたが、タグによってはジャンパが邪魔してタッチしづらいです……)。

RFID/NFCタグ

nfc
こちらもAmazonで「NFCタグ」などと検索してみると、かなり安価で手に入ることがわかります。ステッカーを使えば、手持ちのキーホルダーなどを簡単にキーにすることができますね!

RC522のセットを購入した場合はカードとキーホルダーがついてきますし、「とりあえず試したいだけ」「認識させたいICタグが既にある」という場合は購入しなくて大丈夫です。

shiokara
ちゃんとくは、シオカラーズの2人(Splatoon)に協力してもらおうと思います!!

これは任天堂のamiiboというフィギュアなんですが、ゲーム用のNFCを搭載していてRFIDリーダで情報を読み取ることができます。

識別子を取得する

配線

MFRC522ライブラリPin Layoutを参考に、ArduinoとRC522を接続していきます。Arduino Mega、Nano v3、Microなども利用できますが、ピンの接続箇所が変わるのでライブラリのREADMEを参照してください。

Signal MFRC522 Reader/PCD Pin Arduino Uno Pin
RST/Reset RST 9
SPI SS SDA(SS) 10
SPI MOSI MOSI 11 / ICSP-4
SPI MISO MISO 12 / ICSP-1
SPI SCK SCK 13/ICSP-3

上記の表の通り、RC522のSignalの名前の部分を見て、対応するArduino Unoのピンに接続します。

その他、RC522の「GND」はArduinoの「GND」へ、RC522の「3.3V」はArduinoの「3.3V」へ接続します。

circuit1

map
慣習的に3.3Vを赤、GNDを黒、その他はそれぞれ違う色のジャンパで繋ぐと見やすいです。書いてある通りに繋ぐだけなので、落ち着いて接続しましょう!(IRQというピンは今回は使用しません)

ブレッドボードの使い方がよくわからない、という方は、ドキュメントの「ブレッドボード」を参照してください。

プログラム

Arduino IDEというソフトを使い、Arduinoにプログラムを書き込みます。インストール方法は、ドキュメントの「Arduino IDEをPCにインストール」を参照してください。

まずArduino IDEに、今回利用するMFRC522ライブラリをインストールします。

step1 ─ ライブラリマネージャを開く
[スケッチ] > [ライブラリをインクルード] > [ライブラリを管理]を選択します。

step2 ─ MFRC522ライブラリをインストール
「MFRC」と検索し、MFRC522ライブラリをインストールします。

エディタには下記のプログラムを貼り付けます。ライブラリのDumpInfoのサンプルコードをそのまま利用しています。

#include <SPI.h>
#include <MFRC522.h>

constexpr uint8_t RST_PIN = 9;          // Configurable, see typical pin layout above
constexpr uint8_t SS_PIN = 10;         // Configurable, see typical pin layout above

MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance

void setup() {
		Serial.begin(9600);		// Initialize serial communications with the PC
		while (!Serial);		// Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
		SPI.begin();			// Init SPI bus
		mfrc522.PCD_Init();		// Init MFRC522
		mfrc522.PCD_DumpVersionToSerial();	// Show details of PCD - MFRC522 Card Reader details
		Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
}

void loop() {
	// Look for new cards
	if ( ! mfrc522.PICC_IsNewCardPresent()) {
			return;
	}

	// Select one of the cards
	if ( ! mfrc522.PICC_ReadCardSerial()) {
			return;
	}

	// Dump debug info about the card; PICC_HaltA() is automatically called
	mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
}

step3
[ツール] > [ボード]は「Arduino/Genuino 101」、[シリアルポート]はArduinoを接続したUSBポートを選択します(Windowsの方はCOMポート番号)。

step4
左上の「➡︎」をクリックしてプログラムを書き込みます。

確認

プログラムを書き込めたら、タグの情報を確認します。

monitor
[ツール] > [シリアルモニタ]を開きます。

step5
シリアルモニタを開いた状態でRFIDリーダにタグをかざすと、タグの情報が表示されます。

登録したいタグをかざし、「Card UID:」以降の部分(画像では消してある部分)をコピーしておきましょう。

識別子を元に動作を変える

識別子を取得したNFCタグを「認証するユーザ」、それ以外のタグを「認証しないユーザ」として、Arduino側の動作を変えてみます。

goal
認証するユーザの場合はLEDを青に、認証しないユーザの場合はLEDを赤に光らせるプログラムを作ってみます。

配線

回路に、青と赤のLEDを追加します。配線するときは、一旦Arduinoを電源から外します。

circuit2

青いLEDのアノード(+側・脚が長い方)を8番ピンに、赤いLEDのアノードをアナログの3番ピンに繋ぎ、カソード(ー側)をそれぞれGNDに接続します。

map2 ─ 配線した状態(上の図とLEDの向きが逆になっています)

プログラム

先ほど取得したタグの識別子とマッチしたら青いLED、それ以外は赤いLEDを光らせるプログラムを作成します。

#defin UIDの部分は、ご自身が取得したタグの識別子に置き換えてください。また、今回赤いLEDはアナログ出力に接続しているので、AnalogWrite()を利用して光量を0〜255で指定します。

#include <SPI.h>
#include <MFRC522.h>

constexpr uint8_t RST_PIN = 9;
constexpr uint8_t SS_PIN = 10;

#define UID "xx xx xx xx xx xx xx" // 取得した識別子を記述

int led_blue = 8;
int led_red = 3;

MFRC522 mfrc522(SS_PIN, RST_PIN);
MFRC522::MIFARE_Key key;

void setup() {
	  Serial.begin(9600);
	  pinMode(led_blue, OUTPUT);
	  pinMode(led_red, OUTPUT);
	  while (!Serial);
	  SPI.begin();
	  mfrc522.PCD_Init();
	  mfrc522.PCD_DumpVersionToSerial();
	  Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));

	  dump_byte_array(key.keyByte, MFRC522::MF_KEY_SIZE);
}

void loop() {
    if ( ! mfrc522.PICC_IsNewCardPresent()) {
      	return;
    }
    if ( ! mfrc522.PICC_ReadCardSerial()) {
      	return;
    }

    String strBuf[mfrc522.uid.size];
    for (byte i = 0; i < mfrc522.uid.size; i++) {
      	strBuf[i] =  String(mfrc522.uid.uidByte[i], HEX);
      	if(strBuf[i].length() == 1){
        	strBuf[i] = "0" + strBuf[i];
      	}
    }

    String strUID = strBuf[0] + " " + strBuf[1] + " " + strBuf[2] + " " + strBuf[3] + " " + strBuf[4] + " " + strBuf[5] + " " + strBuf[6];
    if ( strUID.equalsIgnoreCase(UID) ){
	      Serial.println("chantoku");
	      digitalWrite(led_blue, HIGH); // 青いLEDを光らせる
	      delay(1000); // 1秒待つ
	      digitalWrite(led_blue, LOW); // 青いLEDを消す
    } else {
	      Serial.println("error!");
	      analogWrite(led_red, 180); // 赤いLEDを光らせる
	      delay(1000); // 1秒待つ
	      analogWrite(led_red, 0); // 赤いLEDを消す
    }
}

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);
    }
}

先ほどと同様の手順でArduinoにプログラムを書き込みます。これで完成です!

試してみる

さっそく登録したタグを識別できるか試してみましょう。

アオリちゃん(ピンクの子)が登録したタグ、ホタルちゃん(緑の子)は登録していないタグです。 https://gyazo.com/2a2e957605e230f3d539f331c718f9b4

登録したアオリちゃんをタッチした時は青、登録していないホタルちゃんをタッチした時は赤を光らせることができました!

まとめ

非接触通信、無線通信というと難しいイメージがありますが、かなり簡単に実装することができました!この機能を使ってタッチした時間を記録したり、タグの識別を利用して電気をつける場所を変えたりと、いろいろなことに活用できそうです。

次回はWi-Fiに接続してタッチした時間を記録するデバイスの実装方法を紹介してみたいと思います。

それではまた!