ArduinoでRFIDドアロックを作る - マスターRFID技術をステップバイステップで習得
このチュートリアルでは、RFIDとは何か、どう動作するか、そしてArduinoベースのRFIDドアロックの作り方を学びます。詳細については、以下のビデオまたは文章チュートリアルをご覧ください。 RFIDシステムは主に2つのコンポーネントで構成されます。識別対象のオブジェクトに取り付けるトランスポンダ(タグ)と、トランシーバ(リーダー)です。 RFIDリーダーは無線周波数モジュール、制御ユニット、高周波電磁界を生成するアンテナコイルで構成されます。一方、タグは通常パッシブコンポーネントで、アンテナと電子マイクロチップのみで構成されます。タグがトランシーバの電磁界に近づくと、誘導によってタグのアンテナコイルに電圧が発生し、これがマイクロチップの電源となります。 タグが電力を得ると、リーダーから送信されたメッセージを抽出できます。タグからリーダーへデータを送り返すには負荷変調という技術を使います。タグのアンテナで負荷をオン/オフ切り替えると、リーダー側のアンテナ消費電力に影響し、電圧降下として検出されます。この電圧変化を0と1としてデータ転送を行います。 もう一つのデータ転送方式にバック散乱結合があります。これはタグが受信電力の一部を使って別の電磁界を生成し、それをリーダーのアンテナで受信する方式です。 基本原理を理解したところで、ArduinoでRFIDを使い、独自のRFIDドアロックを作ってみましょう。MIFAREプロトコルベースのタグとMFRC522 RFIDリーダーを使用します。これらはわずか数ドルで入手可能です。 これらのタグは1KBのメモリを持ち、演算機能を備えたマイクロチップを搭載。動作周波数は13.56MHz、通信距離はアンテナ形状により最大10cmです。タグを光にかざすと、内部のアンテナとマイクロチップが見えます。 RFIDリーダーモジュールはSPIプロトコルでArduinoと通信します。接続方法は以下の通りです。重要: モジュールのVCCは必ず3.3Vに接続してください。他のピンは5Vトレラントなのでそのまま接続可能です。 接続後、GitHubからMFRC522ライブラリをダウンロードします。ライブラリにはいくつかの優れたサンプルが含まれています。まず「DumpInfo」例をアップロードしてシステムが正常に動作するかテストします。シリアルモニタを開き、タグをモジュールにかざすと、タグの全情報が表示されます。 ここではタグのUID番号と、1KBメモリが16セクタ×4ブロック×2バイトの構造になっていることがわかります。このチュートリアルではタグのメモリは使用せず、UID番号のみを利用します。 コードを見る前に、コンポーネントと回路図を確認しましょう。 RFIDモジュールに加え、ドアの開閉検知用の近接センサ、ロック機構用のサーボモータ、ステータス表示用のキャラクタLCDを使用します。 コードを順を追って解説します。まず必要なライブラリをインクルードし、変数定義とライブラリインスタンスの作成を行います。 メインループではまず近接センサでドアの開閉状態を確認します。 ドアが閉まっている場合(近接センサ値 > 200)、タグをスキャンしてUIDを取得。`getID()`関数内の`return`文により、タグがスキャンされるまで処理はブロックされます。 取得したタグがマスタータグ(`myTags[0]`)と一致する場合、プログラムモードに入ります。このモードでは、既に登録済みのタグをスキャンすると削除、未登録タグなら許可タグとして追加されます。 プログラムモード以外では、スキャンされたタグが登録済みタグ(`myTags`配列)と一致するかチェックし、一致すれば「Access Granted!」表示と共にサーボでドアを解錠。一致しなければ「Access Denied!」を表示します。ドアが開いている場合(近接センサ値 ≤ 200)は「Door Opened!」表示し、ドアが閉まるのを待ってから自動施錠し、通常モードメッセージに戻ります。 このチュートリアルがお役に立てば幸いです。ご質問はコメント欄でお気軽にどうぞ。概要
RFIDの仕組み


RFIDとArduino




Arduino RFIDドアロック アクセス制御プロジェクト

必要なコンポーネント
プロジェクトのワークフロー

ソースコード
#include <SPI.h>
#include <MFRC522.h>
#include <LiquidCrystal.h>
#include <Servo.h>
#define RST_PIN 9
#define SS_PIN 10
byte readCard[4];
char* myTags[100] = {};
int tagsCount = 0;
String tagID = "";
boolean successRead = false;
boolean correctTag = false;
int proximitySensor;
boolean doorOpened = false;
// インスタンス作成
MFRC522 mfrc522(SS_PIN, RST_PIN);
LiquidCrystal lcd(2, 3, 4, 5, 6, 7); // (rs, enable, d4, d5, d6, d7)
Servo myServo; // サーボモータsetup() - 初期化とマスタータグ登録
void setup() {
SPI.begin();
mfrc522.PCD_Init();
lcd.begin(16, 2);
myServo.attach(8);
myServo.write(10); // 初期施錠位置
// 初期メッセージ表示
lcd.print("-No Master Tag!-");
lcd.setCursor(0, 1);
lcd.print(" SCAN NOW");
// マスタータグがスキャンされるまで待機
while (!successRead) {
successRead = getID();
if (successRead) {
myTags[tagsCount] = strdup(tagID.c_str()); // マスタータグを配列先頭に格納
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Master Tag Set!");
tagsCount++;
}
}
successRead = false;
printNormalModeMessage();
}getID() - タグUID取得関数
uint8_t getID() {
if (!mfrc522.PICC_IsNewCardPresent()) return 0;
if (!mfrc522.PICC_ReadCardSerial()) return 0;
tagID = "";
for (uint8_t i = 0; i < 4; i++) { // MIFAREタグは4バイトUID
readCard[i] = mfrc522.uid.uidByte[i];
tagID.concat(String(mfrc522.uid.uidByte[i], HEX));
}
tagID.toUpperCase();
mfrc522.PICC_HaltA(); // 読み取り停止
return 1;
}printNormalModeMessage() - 通常モードメッセージ表示
void printNormalModeMessage() {
delay(1500);
lcd.clear();
lcd.print("-Access Control-");
lcd.setCursor(0, 1);
lcd.print(" Scan Your Tag!");
}loop() - メインループ
int proximitySensor = analogRead(A0);// マスタータグかどうかチェック
if (tagID == myTags[0]) {
lcd.clear();
lcd.print("Program mode:");
lcd.setCursor(0, 1);
lcd.print("Add/Remove Tag");
while (!successRead) {
successRead = getID();
if (successRead) {
for (int i = 0; i < 100; i++) {
if (tagID == myTags[i]) { // 既存タグなら削除
myTags[i] = "";
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Tag Removed!");
printNormalModeMessage();
return;
}
}
// 新規タグとして追加
myTags[tagsCount] = strdup(tagID.c_str());
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Tag Added!");
printNormalModeMessage();
tagsCount++;
return;
}
}
}// 登録済みタグかチェック
for (int i = 0; i < 100; i++) {
if (tagID == myTags[i]) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Access Granted!");
myServo.write(170); // 解錠
printNormalModeMessage();
correctTag = true;
}
}
if (!correctTag) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Access Denied!");
printNormalModeMessage();
}
// ドアが開いている場合
else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Door Opened!");
while (!doorOpened) {
proximitySensor = analogRead(A0);
if (proximitySensor > 200) doorOpened = true;
}
doorOpened = false;
delay(500);
myServo.write(10); // 施錠
printNormalModeMessage();
}完全なソースコード
/*
* Arduino Door Lock Access Control Project
* by Dejan Nedelkovski, www.HowToMechatronics.com
* Library: MFRC522, https://github.com/miguelbalboa/rfid
*/
#include <SPI.h>
#include <MFRC522.h>
#include <LiquidCrystal.h>
#include <Servo.h>
#define RST_PIN 9
#define SS_PIN 10
byte readCard[4];
char* myTags[100] = {};
int tagsCount = 0;
String tagID = "";
boolean successRead = false;
boolean correctTag = false;
int proximitySensor;
boolean doorOpened = false;
MFRC522 mfrc522(SS_PIN, RST_PIN);
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
Servo myServo;
void setup() {
SPI.begin();
mfrc522.PCD_Init();
lcd.begin(16, 2);
myServo.attach(8);
myServo.write(10);
lcd.print("-No Master Tag!-");
lcd.setCursor(0, 1);
lcd.print(" SCAN NOW");
while (!successRead) {
successRead = getID();
if (successRead) {
myTags[tagsCount] = strdup(tagID.c_str());
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Master Tag Set!");
tagsCount++;
}
}
successRead = false;
printNormalModeMessage();
}
void loop() {
int proximitySensor = analogRead(A0);
if (proximitySensor > 200) { // ドア閉
if (!mfrc522.PICC_IsNewCardPresent()) return;
if (!mfrc522.PICC_ReadCardSerial()) return;
tagID = "";
for (uint8_t i = 0; i < 4; i++) {
tagID.concat(String(mfrc522.uid.uidByte[i], HEX));
}
tagID.toUpperCase();
mfrc522.PICC_HaltA();
correctTag = false;
// マスタータグチェック
if (tagID == myTags[0]) {
lcd.clear();
lcd.print("Program mode:");
lcd.setCursor(0, 1);
lcd.print("Add/Remove Tag");
while (!successRead) {
successRead = getID();
if (successRead) {
for (int i = 0; i < 100; i++) {
if (tagID == myTags[i]) {
myTags[i] = "";
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Tag Removed!");
printNormalModeMessage();
return;
}
}
myTags[tagsCount] = strdup(tagID.c_str());
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Tag Added!");
printNormalModeMessage();
tagsCount++;
return;
}
}
}
successRead = false;
// 許可タグチェック
for (int i = 0; i < 100; i++) {
if (tagID == myTags[i]) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Access Granted!");
myServo.write(170);
printNormalModeMessage();
correctTag = true;
}
}
if (!correctTag) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Access Denied!");
printNormalModeMessage();
}
}
// ドア開
else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Door Opened!");
while (!doorOpened) {
proximitySensor = analogRead(A0);
if (proximitySensor > 200) doorOpened = true;
}
doorOpened = false;
delay(500);
myServo.write(10);
printNormalModeMessage();
}
}
uint8_t getID() {
if (!mfrc522.PICC_IsNewCardPresent()) return 0;
if (!mfrc522.PICC_ReadCardSerial()) return 0;
tagID = "";
for (uint8_t i = 0; i < 4; i++) {
readCard[i] = mfrc522.uid.uidByte[i];
tagID.concat(String(mfrc522.uid.uidByte[i], HEX));
}
tagID.toUpperCase();
mfrc522.PICC_HaltA();
return 1;
}
void printNormalModeMessage() {
delay(1500);
lcd.clear();
lcd.print("-Access Control-");
lcd.setCursor(0, 1);
lcd.print(" Scan Your Tag!");
}
製造プロセス
- ArduinoとRC522で作るセキュアなRFIDドアロック(MIFARE 13.56MHz)
- Arduinoで作るセキュアなRFIDロック – ステップバイステップガイド
- Arduinoで作るパンチングキーボードボタン:ストレス解消カスタムキー
- Arduino、キーパッド、リニアアクチュエーターで作るパスワード式ドアロック
- Arduino Nanoと128x64 OLEDで実行するセルラーオートマトン「ライフゲーム」
- eDOT:高精度Arduino時計・気象ステーション(IRリモコン・自動輝度調整内蔵)
- ArduinoとGoogleスプレッドシート連携 リアルタイムRFID勤怠管理システム
- Arduinoで楽器演奏:音階生成のステップバイステップガイド
- Arduinoと超音波センサーで自動ドアを制御:LCD・ブザー付き完全ガイド
- スマートキーレスドアロック:ArduinoとAndroid Bluetoothでパスワード制御
- ArduinoとProcessingで作るリアルタイムデジタルコンパス