- 最終更新日
- 記事公開日
NFCチップ(Ntag213)のデータ読み書き【RFID-RC522無線通信ボード&Arduino Pro Mini】
RFID-RC522無線通信ボードとArduino Pro Miniを使って、NFCチップ(Ntag213)のデータ書き込み・読み込みを行う方法について紹介します。
データの書き込み/読み込み方法
RFID-RC522ボードにNFCチップを近づけると、NFCチップに以下のデータが書き込みまれます↓
1ABCDEFG2ABCDEFG3ABCDEFG4ABCDEFG5ABCDEFG6ABCDEFG7ABCDEFG8ABCDEFG9ABCDEFG1ABCDEFG2ABCDEFG3ABCDEFG4ABCDEFG5ABCDEFG6ABCDEFG7ABCDEFG8ABCDEFG9ABCDEFG
その後すぐに、さきほどNFCチップに書き込んだデータを読み込み、シリアルモニタへと表示しています。
使用部品
Arduino Pro Miniにプログラムを書き込む際に必要な部品
Arduino Pro Miniについて
Arduino Pro Miniを初めて使用する方は、ぜひ下記の記事も参考にしてみて下さい↓
配線写真・回路図
プログラム(Arduino言語)
/*
*
* Arduino Pro Mini
*
* RST 9
* SPI SS(SDA) 10
* SPI MOSI 11
* SPI MISO 12
* SPI SCK 13
*
* Arduinoのボード種類によって配線するピンが違います。
* 詳しくは下記を参照して下さい↓
* https://github.com/miguelbalboa/rfid#pin-layout
*
*/
#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN 10
#define RST_PIN 9
// MFRC522インスタンスを作成
MFRC522 mfrc522(SS_PIN, RST_PIN);
// チップのステータスを取得するための変数
MFRC522::StatusCode status;
// データ書き込み用バッファ(最大144バイト)の配列
byte write_buffer[144];
// データ読み込み用バッファ(最大144バイト + CRC用2バイト)の配列
byte read_buffer[146];
// ポインタに使用するために配列サイズを取得
byte read_buffer_size = sizeof(read_buffer);
// ----------------------------------------------
//
// SETUP
//
// ----------------------------------------------
void setup() {
// PCとのシリアル通信を初期化
Serial.begin(9600);
// SPIバスを初期化
SPI.begin();
// MFRC522カードを初期化
mfrc522.PCD_Init();
// チップに書き込むデータ
memcpy(write_buffer, "1ABCDEFG2ABCDEFG3ABCDEFG4ABCDEFG5ABCDEFG6ABCDEFG7ABCDEFG8ABCDEFG9ABCDEFG1ABCDEFG2ABCDEFG3ABCDEFG4ABCDEFG5ABCDEFG6ABCDEFG7ABCDEFG8ABCDEFG9ABCDEFG", 144);
Serial.println();
Serial.println(F("チップかざして下さい。"));
Serial.println();
}
// ----------------------------------------------
//
// LOOP
//
// ----------------------------------------------
void loop() {
// 新しいカードを探す
if (!mfrc522.PICC_IsNewCardPresent())
return;
// 一つのカードを選択
if (!mfrc522.PICC_ReadCardSerial())
return;
// --------------------------------------------
// チップ情報を表示
// --------------------------------------------
mfrc522.PICC_DumpDetailsToSerial(&(mfrc522.uid));
Serial.println();
// --------------------------------------------
// データの書き込み
// --------------------------------------------
for (int i = 4; i < 40; i++) { // block[4] ~ block[39]までがデータを書き込むことができるメモリ領域
// i:書き込む位置
// &write_buffer[(i-4)*4]:書き込むデータをポインタで指定
// 4:書き込むデータサイズ(4バイト)
status = (MFRC522::StatusCode)mfrc522.MIFARE_Ultralight_Write(i, &write_buffer[(i-4)*4], 4);
// エラー
if (status != MFRC522::STATUS_OK) {
Serial.print(F("書き込み失敗:"));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
}
Serial.println(F("書き込み成功!"));
Serial.println();
// --------------------------------------------
// データの読み取り
// --------------------------------------------
Serial.println(F("データ読み取り中 ... "));
Serial.println();
// block[4] ~ block[39]までのデータを読み込む
for (int n = 4; n < 40; n++) {
// n:読み込む位置
// read_buffer:読み取ったデータを格納する配列
// &read_buffer_size:読み取ったデータのサイズを格納するポインタ
status = (MFRC522::StatusCode)mfrc522.MIFARE_Read(n, read_buffer, &read_buffer_size);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("読み込み失敗:"));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
Serial.print(F("Block"));
Serial.print(n);
Serial.print(F(": "));
// 1バイトずつ表示
for (byte m = 0; m < 4; m++) {
Serial.write(read_buffer[m]);
}
Serial.println();
}
Serial.println();
// 通信終了
mfrc522.PICC_HaltA();
}
※MFRC522ライブラリを使用しています。
プログラムを書き込む前に以下の手順に従って、Arduino IDEへMFRC522ライブラリをダウンロードしておいてください↓
MFRC522ライブラリのダウンロード手順
1.Arduino IDEを開き、上部メニューから[スケッチ]-[ライブラリをインクルード]-[ライブラリを管理]を選択します。
2.検索フォームに「MFRC522」と入力して表示された[MFRC522 by GithubCommunity]をインストールしてください。
注意点
MFRC522ライブラリのサンプルスケッチは、MRCRFID-RC522ボードに付属しているカードの規格(MIFARE Classic 1KB)に読み書きするためのコードです。
Ntag213とはメモリ構造が違います。
サンプルスケッチではNtag213にデータを読み書きできないので、ご注意ください。
今回のプログラムは、「Ntag213」の類似品である「MIFARE Ultralight C」へ書き込む関数(MIFARE_Ultralight_Write)を使用しています。
技術解説
NFCチップ(Ntag213)のメモリ構造は以下の通りとなっています↓
[0]~[3]Page・[40]~[44]Pageはチップ情報が格納されているので、データを書き込むことはできません。
無理に書き込むと、データが壊れてチップへの読み書きができなくなってしまいます。
ユーザー側でデータを書き込みできる領域は「144バイト」
文字半角英数文字であれば、144文字分を保存することができます。
実際に上記のプログラムをNtag213に書き込み、実行して、シリアルモニタに表示された結果が以下となります↓
基本編[その2]UID(シリアルナンバー)認証
プログラムの中に書いてある認証UIDと一致するNFCチップをかざすと、LEDランプが点灯します。
認証されないNFCチップをかざしても、LEDは点灯しません。
使用部品
- NFCシール(Ntag213)- AliExpress
- RFID-RC522ボード - AliExpress
- Arduino Pro Mini(3.3V・8M) Arduino用 - Amazon
- LED(抵抗内蔵タイプ)- 秋月電子
配線写真・回路図
プログラム(Arduino言語)
/*
*
* Arduino Pro Mini
*
* RST 9
* SPI SS(SDA) 10
* SPI MOSI 11
* SPI MISO 12
* SPI SCK 13
*
* Arduinoのボード種類によって配線するピンが違います。
* 詳しくは下記を参照して下さい↓
* https://github.com/miguelbalboa/rfid#pin-layout
*
*/
#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN 10
#define RST_PIN 9
// MFRC522インスタンスを作成
MFRC522 mfrc522(SS_PIN, RST_PIN);
// チップのステータスを取得するための変数
MFRC522::StatusCode status;
// LEDに使用するPin
#define LED_PIN 2
// ----------------------------------------------
// 認証UID
// ----------------------------------------------
byte targetUID[] = {0x53, 0x0D, 0x98, 0x52, 0x61, 0x00, 0x01};
// ----------------------------------------------
//
// SETUP
//
// ----------------------------------------------
void setup() {
// LEDピン設定
pinMode(LED_PIN, OUTPUT);
// PCとのシリアル通信を初期化
Serial.begin(9600);
// SPIバスを初期化
SPI.begin();
// MFRC522カードを初期化
mfrc522.PCD_Init();
Serial.println();
Serial.println(F("チップかざして下さい。"));
Serial.println();
}
// ----------------------------------------------
//
// LOOP
//
// ----------------------------------------------
void loop() {
// 新しいカードを探す
if (!mfrc522.PICC_IsNewCardPresent())
return;
// 一つのカードを選択
if (!mfrc522.PICC_ReadCardSerial())
return;
// --------------------------------------------
// チップ情報を表示
// --------------------------------------------
mfrc522.PICC_DumpDetailsToSerial(&(mfrc522.uid));
Serial.println();
// --------------------------------------------
// UIDの一致を検証
// --------------------------------------------
if (memcmp(mfrc522.uid.uidByte, targetUID, mfrc522.uid.size) == 0) {
Serial.println(F("UIDが一致しました。LEDを点灯します。"));
digitalWrite(LED_PIN, HIGH);
delay(1000);
digitalWrite(LED_PIN, LOW);
}
else {
Serial.println(F("UIDが一致しません。"));
}
Serial.println();
// 通信終了
mfrc522.PICC_HaltA();
}
※認証UID(targetUID)は、ご使用のチップNFCに合わせて必ず変更してください。
実際に上記のプログラムをNtag213に書き込み、実行して、シリアルモニタに表示された結果が以下となります↓
応用編(UID認証後、データ値でサーボモーター制御)
NFCチップを張り付けた物体をRFID-RC522ボードに近づけ、UID認証が通ると、NFCチップに書き込んであるデータ量に応じてサーボ-モータが動きます。
使用部品
- NFCシール(Ntag213)- AliExpress
- RFID-RC522ボード - AliExpress
- Arduino Pro Mini(3.3V・8M) Arduino用 - Amazon
- LED(抵抗内蔵タイプ)- 秋月電子
- 三端子レギュレーター(LM317)- 秋月電子
- カーボン抵抗(1W100Ω)※合成50Ω用 - 秋月電子
- カーボン抵抗(1/2W120Ω)
- カーボン抵抗(1/2W200Ω)
- 積層セラミックコンデンサ(0.1μF)
- 積層セラミックコンデンサ(1μF)
- サーボモーター(SG92R)- 秋月電子
- モバイルバッテリー(エレコム DE-M09-5000WH)- Amazon
配線写真・回路図
モバイルバッテリー(5V)と50Ω抵抗について
サーボモーター(SG92R)を動かすには4.8Vが必要なので、モバイルバッテリー(5V)を使用しています。
近くに置いてある50Ωは、モバイルバッテリーから常時電流を供給し続けるためのものです。
これがないと、数秒でモバイルバッテリーは止まってしまいます。
詳しくは下記の記事をご覧ください↓
Arduino Pro Miniへの3.3V電源供給について
Arduino Pro Miniの電源にモバイルバッテリーを使用する場合は、5V→3.3Vへ電圧を落とす必要があります。
そこで、三端子レギュレーター(LM317)を使用しています。
LM317は抵抗値によって出力電圧を調整できるので、付近に置いてある120Ω・200Ω抵抗で5V→3.3Vへ落とす調整を行っています。
0.1μF・1μFは動作を安定させるためのものです。
プログラム(Arduino言語)
/*
*
* Arduino Pro Mini
*
* RST 9
* SPI SS(SDA) 10
* SPI MOSI 11
* SPI MISO 12
* SPI SCK 13
*
* Arduinoのボード種類によって配線するピンが違います。
* 詳しくは下記を参照して下さい↓
* https://github.com/miguelbalboa/rfid#pin-layout
*
*/
#include <SPI.h>
#include <MFRC522.h>
#include <Servo.h>
// サーボモーター制御Pin
#define SERVO_PIN 9
// servoクラスのインスタンス作成
Servo servo1;
// MFRC522インスタンスを作成
#define SS_PIN 7
#define RST_PIN 8
MFRC522 mfrc522(SS_PIN, RST_PIN);
// チップのステータスを取得するための変数
MFRC522::StatusCode status;
// データ書き込み用バッファ(最大144バイト)の配列
byte write_buffer[144];
// データ読み込み用バッファ(最大144バイト + CRC用2バイト)の配列
byte read_buffer[146];
// ポインタに使用するために配列サイズを取得
byte read_buffer_size = sizeof(read_buffer);
// LEDに使用するPin
#define LED_PIN 2
// ----------------------------------------------
// 認証UID
// ----------------------------------------------
byte targetUID[] = {0x53, 0x0D, 0x98, 0x52, 0x61, 0x00, 0x01};
// ----------------------------------------------
//
// SETUP
//
// ----------------------------------------------
void setup() {
// サーボモーターPin設定
servo1.attach(SERVO_PIN);
// サーボモーターの初期位置
servo1.write(0);
// LEDピン設定
pinMode(LED_PIN, OUTPUT);
// PCとのシリアル通信を初期化
Serial.begin(9600);
// SPIバスを初期化
SPI.begin();
// MFRC522カードを初期化
mfrc522.PCD_Init();
// チップに書き込むデータ([4]と[5]という2のデータを書き込む)
memcpy(write_buffer, "45", 144);
Serial.println();
Serial.println(F("チップかざして下さい。"));
Serial.println();
}
// ----------------------------------------------
//
// LOOP
//
// ----------------------------------------------
void loop() {
// 新しいカードを探す
if (!mfrc522.PICC_IsNewCardPresent())
return;
// 一つのカードを選択
if (!mfrc522.PICC_ReadCardSerial())
return;
// --------------------------------------------
// チップ情報を表示
// --------------------------------------------
mfrc522.PICC_DumpDetailsToSerial(&(mfrc522.uid));
Serial.println();
// --------------------------------------------
// データの書き込み
// --------------------------------------------
// block4の位置にwrite_buffer[0]から4バイトのデータを書き込む
status = (MFRC522::StatusCode)mfrc522.MIFARE_Ultralight_Write(4, &write_buffer[0], 4);
// エラー
if (status != MFRC522::STATUS_OK) {
Serial.print(F("書き込み失敗:"));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// --------------------------------------------
// UIDの一致を検証
// --------------------------------------------
if (memcmp(mfrc522.uid.uidByte, targetUID, mfrc522.uid.size) == 0) {
Serial.println(F("UIDが一致しました。LEDを点灯します。"));
// block4を読み込み、read_bufferへデータを格納し、メソッドに渡すためのデータサイズを取得する
status = (MFRC522::StatusCode)mfrc522.MIFARE_Read(4, read_buffer, &read_buffer_size);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("読み込み失敗:"));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// データを2文字の整数に変換
int read_value = 0;
for (int i = 0; i < 2; i++) {
if (isdigit(read_buffer[i])) {
read_value = read_value * 10 + (read_buffer[i] - '0');
}
}
Serial.println(read_value);
// LED点灯
digitalWrite(LED_PIN, HIGH);
// サーバモーターを45度の位置に動かす
servo1.write(read_value);
// 1秒待機
delay(1000);
// LED消灯
digitalWrite(LED_PIN, LOW);
// サーバモーターを0度の位置に戻す
servo1.write(0);
// 1秒待機
delay(1000);
}
else {
Serial.println(F("UIDが一致しません。"));
}
Serial.println();
// 通信終了
mfrc522.PICC_HaltA();
}
※認証UID(targetUID)は、ご使用のチップNFCに合わせて必ず変更してください。
このプログラムでは、NFCチップをかざしたときに「4」と「5」というデータをNFCチップに書き込んでいます。
その後、UIDを認証。
指定したものと一致したら、さきほどデータを書き込んだNFCチップの中から「4」と「5」というデータを取り出します。
「4」と「5」というデータを「45」という数値に変換して、サーボモーターへ「45度」の位置まで動く指示に使用しています。