工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

ArduinoでRFIDドアロックを作る - マスターRFID技術をステップバイステップで習得

概要

このチュートリアルでは、RFIDとは何か、どう動作するか、そしてArduinoベースのRFIDドアロックの作り方を学びます。詳細については、以下のビデオまたは文章チュートリアルをご覧ください。

RFIDの仕組み


RFIDシステムは主に2つのコンポーネントで構成されます。識別対象のオブジェクトに取り付けるトランスポンダ(タグ)と、トランシーバ(リーダー)です。

ArduinoでRFIDドアロックを作る - マスターRFID技術をステップバイステップで習得

RFIDリーダーは無線周波数モジュール、制御ユニット、高周波電磁界を生成するアンテナコイルで構成されます。一方、タグは通常パッシブコンポーネントで、アンテナと電子マイクロチップのみで構成されます。タグがトランシーバの電磁界に近づくと、誘導によってタグのアンテナコイルに電圧が発生し、これがマイクロチップの電源となります。

ArduinoでRFIDドアロックを作る - マスターRFID技術をステップバイステップで習得

タグが電力を得ると、リーダーから送信されたメッセージを抽出できます。タグからリーダーへデータを送り返すには負荷変調という技術を使います。タグのアンテナで負荷をオン/オフ切り替えると、リーダー側のアンテナ消費電力に影響し、電圧降下として検出されます。この電圧変化を0と1としてデータ転送を行います。

もう一つのデータ転送方式にバック散乱結合があります。これはタグが受信電力の一部を使って別の電磁界を生成し、それをリーダーのアンテナで受信する方式です。

RFIDとArduino

基本原理を理解したところで、ArduinoでRFIDを使い、独自のRFIDドアロックを作ってみましょう。MIFAREプロトコルベースのタグとMFRC522 RFIDリーダーを使用します。これらはわずか数ドルで入手可能です。

ArduinoでRFIDドアロックを作る - マスターRFID技術をステップバイステップで習得

これらのタグは1KBのメモリを持ち、演算機能を備えたマイクロチップを搭載。動作周波数は13.56MHz、通信距離はアンテナ形状により最大10cmです。タグを光にかざすと、内部のアンテナとマイクロチップが見えます。

ArduinoでRFIDドアロックを作る - マスターRFID技術をステップバイステップで習得

RFIDリーダーモジュールはSPIプロトコルでArduinoと通信します。接続方法は以下の通りです。重要: モジュールのVCCは必ず3.3Vに接続してください。他のピンは5Vトレラントなのでそのまま接続可能です。

ArduinoでRFIDドアロックを作る - マスターRFID技術をステップバイステップで習得

接続後、GitHubからMFRC522ライブラリをダウンロードします。ライブラリにはいくつかの優れたサンプルが含まれています。まず「DumpInfo」例をアップロードしてシステムが正常に動作するかテストします。シリアルモニタを開き、タグをモジュールにかざすと、タグの全情報が表示されます。

ArduinoでRFIDドアロックを作る - マスターRFID技術をステップバイステップで習得

ここではタグのUID番号と、1KBメモリが16セクタ×4ブロック×2バイトの構造になっていることがわかります。このチュートリアルではタグのメモリは使用せず、UID番号のみを利用します。

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

コードを見る前に、コンポーネントと回路図を確認しましょう。

ArduinoでRFIDドアロックを作る - マスターRFID技術をステップバイステップで習得

RFIDモジュールに加え、ドアの開閉検知用の近接センサ、ロック機構用のサーボモータ、ステータス表示用のキャラクタLCDを使用します。

必要なコンポーネント

  • MFRC522 RFIDモジュール
  • サーボモータ
  • LCDディスプレイ
  • Arduinoボード
  • ブレッドボードとジャンパワイヤ
  • 近接センサ CNY70

プロジェクトのワークフロー

  1. まずマスタータグを登録
  2. システムがノーマルモードで起動
  3. 未登録タグをスキャン → アクセス拒否
  4. マスタータグをスキャン → プログラムモードに入る
  5. プログラムモードで未登録タグをスキャン → 許可タグとして追加
  6. 再度同じタグをスキャン → アクセス許可、ドア解錠
  7. ドアが閉まると自動的に施錠
  8. プログラムモードで既知タグをスキャン → システムから削除
ArduinoでRFIDドアロックを作る - マスター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);

ドアが閉まっている場合(近接センサ値 > 200)、タグをスキャンしてUIDを取得。`getID()`関数内の`return`文により、タグがスキャンされるまで処理はブロックされます。

取得したタグがマスタータグ(`myTags[0]`)と一致する場合、プログラムモードに入ります。このモードでは、既に登録済みのタグをスキャンすると削除、未登録タグなら許可タグとして追加されます。

// マスタータグかどうかチェック
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;
    }
  }
}

プログラムモード以外では、スキャンされたタグが登録済みタグ(`myTags`配列)と一致するかチェックし、一致すれば「Access Granted!」表示と共にサーボでドアを解錠。一致しなければ「Access Denied!」を表示します。ドアが開いている場合(近接センサ値 ≤ 200)は「Door Opened!」表示し、ドアが閉まるのを待ってから自動施錠し、通常モードメッセージに戻ります。

// 登録済みタグかチェック
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!");
}

このチュートリアルがお役に立てば幸いです。ご質問はコメント欄でお気軽にどうぞ。

製造プロセス

  1. ArduinoとRC522で作るセキュアなRFIDドアロック(MIFARE 13.56MHz)
  2. Arduinoで作るセキュアなRFIDロック – ステップバイステップガイド
  3. Arduinoで作るパンチングキーボードボタン:ストレス解消カスタムキー
  4. Arduino、キーパッド、リニアアクチュエーターで作るパスワード式ドアロック
  5. Arduino Nanoと128x64 OLEDで実行するセルラーオートマトン「ライフゲーム」
  6. eDOT:高精度Arduino時計・気象ステーション(IRリモコン・自動輝度調整内蔵)
  7. ArduinoとGoogleスプレッドシート連携 リアルタイムRFID勤怠管理システム
  8. Arduinoで楽器演奏:音階生成のステップバイステップガイド
  9. Arduinoと超音波センサーで自動ドアを制御:LCD・ブザー付き完全ガイド
  10. スマートキーレスドアロック:ArduinoとAndroid Bluetoothでパスワード制御
  11. ArduinoとProcessingで作るリアルタイムデジタルコンパス