「鍵を持ち歩くのが面倒…でもセキュリティは下げたくない」そんな気持ち、ありますよね。

実はArduinoとNFCモジュールを使えば、Suicaや社員証のようなICカード・スマートフォンをかざすだけで開くスマートロックを自作できるんです。市販品を買えば手軽ですが、DIYで作ることで「どのカードが使えるか」「何回アクセスしたか」のログまで自分でコントロールできます。

この記事では、電子工作の基本(Lチカ・センサー読み取りなど)を一度は経験したことがある中級者向けに、NFCスマートロックの仕組みから配線・スケッチ・実運用のポイントまで一気に解説します。難しそうに見えますが、ざっくりとした流れをつかめばきっと「できそう!」と思えるはずです。

📌 この記事でわかること

NFC smart lock electronics
NFC smart lock electronics / Photo by Jakub Zerdzicki via Pexels
  • NFCとRFIDの違いと、スマートロックに使うモジュールの選び方
  • PN532 NFCモジュール+Arduino Unoの配線方法
  • ICカードのUID読み取りと認証スケッチの書き方
  • サーボモーター・電磁ロックでドアを制御する回路
  • 登録カードの管理とセキュリティ強化のポイント

NFCとRFIDの違い、スマートロックに使うのはどっち?

まず混乱しやすい言葉の整理から。

RFID(Radio Frequency IDentification)は「電波を使った無線認識」全般を指す広い概念で、倉庫管理タグや高速道路ETCもRFIDの一種です。NFC(Near Field Communication)はRFIDの中でも13.56MHz帯・10cm以内の近距離通信規格を指します。

スマートロックに使うならNFCが断然おすすめです。理由は3つ。

  • ✅ Suica・PASMOなど手持ちのICカードがそのまま使える(FeliCa対応モジュールなら)
  • ✅ AndroidスマホはNFCエミュレーション機能があるので鍵アプリ化できる
  • ✅ 通信距離が短いため「意図せず認証」が起きにくい

おすすめモジュール:PN532

Arduinoで使えるNFCモジュールとして最もメジャーなのがPN532です。秋月電子やAmazonで1,000〜2,000円前後で購入できます。

通信方式はI2C・SPI・HSUARTの3種類から選べます。今回は配線がシンプルなI2C接続で進めます。

必要な部品リスト

部品 数量 備考
Arduino Uno(またはNano) 1 互換機でもOK
PN532 NFCモジュール 1 I2Cモード使用
SG90サーボモーター 1 軽量錠前向け
赤色・緑色LED 各1 認証結果の表示用
抵抗(220Ω) 2 LED用
ブレッドボード+ジャンパワイヤ 適量
Mifare 1KカードまたはNFCシール 2〜3枚 登録カード用

💡 手持ちのSuicaやPASMOでも動作確認できますが、EEPROMに保存するUID情報が本物の交通系カードのものになるため、本番運用では専用のMifareカードを使うほうが管理しやすいです。

配線図と接続方法

PN532(I2Cモード)とArduino Unoの接続

PN532をI2Cモードで使うには、モジュール上のディップスイッチを「I2C設定」に切り替えます(多くの場合、SW1=ON, SW2=OFF)。メーカーによって異なるのでデータシートを確認してください。

PN532モジュール  →  Arduino Uno
─────────────────────────────
VCC            →  3.3V(または5V:モジュール仕様による)
GND            →  GND
SDA            →  A4(SDAピン)
SCL            →  A5(SCLピン)

サーボとLEDの接続

SG90サーボ     →  Arduino Uno
─────────────────────────────
赤線(VCC)    →  5V
茶線(GND)    →  GND
オレンジ(信号)→  D9

緑LED(認証OK) →  D7 → 220Ω抵抗 → GND
赤LED(認証NG) →  D6 → 220Ω抵抗 → GND

ポイントをまとめるとこんな感じです。

  • サーボの電源はArduinoの5Vピンから直接供給(電流に余裕がない場合は外部電源を使うこと)
  • PN532の電源電圧はモジュールによって3.3V専用と5V対応があるため必ず確認する
  • I2Cラインにはプルアップ抵抗(4.7kΩ程度)が必要な場合があるが、多くのPN532モジュールには基板上に実装済み

ライブラリの準備

Arduino IDEのライブラリマネージャーから以下をインストールしてください。

  • Adafruit PN532:PN532の公式サポートライブラリ
  • Adafruit BusIO:上記の依存ライブラリ(自動インストールされることも)
  • Servo:標準ライブラリなので追加不要

STEP1:NFCカードのUIDを読み取る

まず最初にやること。認証に使うカードのUID(固有ID)を読み取って確認します。このUIDをスケッチに登録することで「このカードだけ開く」という仕組みを作ります。

// UID読み取りスケッチ(確認用)
#include <Wire.h>
#include <Adafruit_PN532.h>

// I2C接続の場合、ピン指定は不要(SDA/SCLは自動)
Adafruit_PN532 nfc(-1, -1);  // IRQ, RST ピン未使用

void setup() {
  Serial.begin(115200);
  Serial.println("NFCスマートロック - UID読み取りモード");

  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (!versiondata) {
    Serial.println("PN532モジュールが見つかりません");
    while (1);  // 見つからなければ停止
  }

  Serial.print("PN532ファームウェアバージョン: ");
  Serial.println((versiondata >> 16) & 0xFF, DEC);

  // RFIDカードのポーリングを開始
  nfc.SAMConfig();
  Serial.println("カードをかざしてください...");
}

void loop() {
  uint8_t uid[7];   // 最大7バイトUID
  uint8_t uidLength;

  // カードを検出(タイムアウト1秒)
  boolean success = nfc.readPassiveTargetID(
    PN532_MIFARE_ISO14443A, uid, &uidLength, 1000
  );

  if (success) {
    Serial.print("UIDを検出! バイト数: ");
    Serial.println(uidLength, DEC);
    Serial.print("UID: ");
    for (uint8_t i = 0; i < uidLength; i++) {
      Serial.print(" 0x"); Serial.print(uid[i], HEX);
    }
    Serial.println("");
    delay(1000);  // 連続読み取り防止
  }
}

シリアルモニターを開いてカードをかざすと、こんな感じでUIDが表示されます。

NFCスマートロック - UID読み取りモード
PN532ファームウェアバージョン: 1
カードをかざしてください...
UIDを検出! バイト数: 4
UID:  0xAB 0xCD 0x12 0x34

このUIDの値(0xAB, 0xCD, 0x12, 0x34の部分)をメモしておきましょう。次のステップで使います。

STEP2:認証+サーボ制御のメインスケッチ


いよいよ本体です。読み取ったUIDと登録済みUIDを比較して、一致したらサーボで錠を開くスケッチです。

// NFCスマートロック メインスケッチ
#include <Wire.h>
#include <Adafruit_PN532.h>
#include <Servo.h>

Adafruit_PN532 nfc(-1, -1);
Servo lockServo;

// ピン定義
const int SERVO_PIN  = 9;
const int LED_GREEN  = 7;  // 認証OK
const int LED_RED    = 6;  // 認証NG

// サーボ角度設定
const int LOCK_ANGLE   = 0;    // 施錠位置
const int UNLOCK_ANGLE = 90;   // 開錠位置
const int OPEN_DURATION = 3000; // 開放時間(ミリ秒)

// ✅ 登録済みUIDリスト(STEP1で確認した値を入れる)
const uint8_t REGISTERED_UIDS[][4] = {
  {0xAB, 0xCD, 0x12, 0x34},  // カード1
  {0x11, 0x22, 0x33, 0x44},  // カード2(予備)
};
const int NUM_CARDS = sizeof(REGISTERED_UIDS) / sizeof(REGISTERED_UIDS[0]);

// UID照合関数
bool isAuthorized(uint8_t* uid, uint8_t uidLength) {
  if (uidLength != 4) return false;  // 4バイトUIDのみ対応
  for (int i = 0; i < NUM_CARDS; i++) {
    if (memcmp(uid, REGISTERED_UIDS[i], 4) == 0) {
      return true;  // 一致した
    }
  }
  return false;  // 一致なし
}

void openLock() {
  Serial.println("✅ 認証成功 - 開錠します");
  digitalWrite(LED_GREEN, HIGH);
  lockServo.write(UNLOCK_ANGLE);  // 開く
  delay(OPEN_DURATION);           // 3秒間開放
  lockServo.write(LOCK_ANGLE);    // 閉じる
  digitalWrite(LED_GREEN, LOW);
}

void denyAccess() {
  Serial.println("❌ 認証失敗 - アクセス拒否");
  // 赤LEDを3回点滅
  for (int i = 0; i < 3; i++) {
    digitalWrite(LED_RED, HIGH);
    delay(200);
    digitalWrite(LED_RED, LOW);
    delay(200);
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(LED_GREEN, OUTPUT);
  pinMode(LED_RED, OUTPUT);

  lockServo.attach(SERVO_PIN);
  lockServo.write(LOCK_ANGLE);  // 起動時は施錠状態

  nfc.begin();
  if (!nfc.getFirmwareVersion()) {
    Serial.println("PN532が見つかりません!配線を確認してください");
    while (1);
  }
  nfc.SAMConfig();

  Serial.println("🔒 スマートロック起動完了 - カードをかざしてください");
}

void loop() {
  uint8_t uid[7];
  uint8_t uidLength;

  boolean detected = nfc.readPassiveTargetID(
    PN532_MIFARE_ISO14443A, uid, &uidLength, 500
  );

  if (detected) {
    Serial.print("カード検出 UID: ");
    for (int i = 0; i < uidLength; i++) {
      Serial.print("0x"); Serial.print(uid[i], HEX); Serial.print(" ");
    }
    Serial.println();

    if (isAuthorized(uid, uidLength)) {
      openLock();
    } else {
      denyAccess();
    }
    delay(1500);  // 連続認証防止
  }
}

ここが重要です。このスケッチのポイントをまとめます。

  • REGISTERED_UIDs配列に複数のカードを登録できる(配列を増やすだけ)
  • memcmp関数でバイト列を一括比較しているので高速かつ安全
  • サーボは0度=施錠・90度=開錠として設計。錠前の構造に合わせて角度を調整する
  • 認証成功後、OPEN_DURATIONミリ秒後に自動で施錠に戻る

STEP3:アクセスログをシリアルで記録する

「いつ・誰が開けたか」のログは防犯上とても重要です。ArduinoはRTC(リアルタイムクロック)モジュールを追加すれば時刻も記録できますが、まずはシリアル通信でPCに記録する方法を紹介します。

// openLock()関数内のログ出力部分を拡張する例
void openLock(uint8_t* uid) {
  // UIDをHEX文字列に変換してログ出力
  Serial.print("[ACCESS_LOG] OPEN | UID: ");
  for (int i = 0; i < 4; i++) {
    if (uid[i] < 0x10) Serial.print("0");  // ゼロパディング
    Serial.print(uid[i], HEX);
    if (i < 3) Serial.print(":");
  }
  Serial.println(" | STATUS: GRANTED");

  digitalWrite(LED_GREEN, HIGH);
  lockServo.write(UNLOCK_ANGLE);
  delay(OPEN_DURATION);
  lockServo.write(LOCK_ANGLE);
  digitalWrite(LED_GREEN, LOW);
}

このログ出力をPCで受け取り、Pythonスクリプトでファイルに保存すればアクセス履歴の管理が格段に楽になります。シリアル通信でArduinoとPythonを連携する方法は、当ブログの関連記事が参考になりますよ。

実運用で気をつけたいセキュリティポイント

DIYスマートロックは楽しいプロジェクトですが、セキュリティ面での注意点を知っておくことも大切です。

⚠️ UIDのみの認証は「なりすまし」リスクがある

今回実装したUID照合は「カードのIDが一致するかどうか」だけを見ています。UIDは複製可能な安価なカードも市販されているため、本格的なセキュリティ用途には追加対策が必要です。

強化策としてはこんな方法があります。

  • Mifare Classicのセクタ認証:カードのメモリ領域をパスワード付きで読み書きする
  • UIDホワイトリスト+PINコード:カードをかざした後にボタン入力も要求する二段階認証
  • EEPROMへのUID保存:スケッチにハードコードせず、EEPROMに保存して管理者モードで追加・削除できるようにする

EEPROMを使ったUID管理(発展編)

スケッチを書き換えずにカードを追加・削除したい場合は、ArduinoのEEPROMを活用します。考え方だけ簡単に示すとこんな感じです。

// EEPROMへのUID保存・読み出しのイメージ
#include <EEPROM.h>

// EEPROM構造: [カード数(1byte)] + [UID1(4byte)] + [UID2(4byte)] + ...
const int EEPROM_COUNT_ADDR = 0;      // カード枚数の保存アドレス
const int EEPROM_UID_START  = 1;      // UIDデータの開始アドレス
const int MAX_CARDS = 10;             // 最大登録枚数

// UIDをEEPROMに追加登録する関数
void registerCard(uint8_t* uid) {
  int count = EEPROM.read(EEPROM_COUNT_ADDR);
  if (count >= MAX_CARDS) {
    Serial.println("登録上限に達しています");
    return;
  }
  int addr = EEPROM_UID_START + count * 4;
  for (int i = 0; i < 4; i++) {
    EEPROM.write(addr + i, uid[i]);
  }
  EEPROM.write(EEPROM_COUNT_ADDR, count + 1);
  Serial.println("カードを登録しました");
}

// EEPROMのUIDリストと照合する関数
bool checkEEPROM(uint8_t* uid) {
  int count = EEPROM.read(EEPROM_COUNT_ADDR);
  for (int i = 0; i < count; i++) {
    int addr = EEPROM_UID_START + i * 4;
    bool match = true;
    for (int j = 0; j < 4; j++) {
      if (EEPROM.read(addr + j) != uid[j]) {
        match = false;
        break;
      }
    }
    if (match) return true;
  }
  return false;
}

「管理者カード」を別途用意して、かざした後に新しいカードをかざすと登録できる仕組みにすると、PCなしでカード管理が完結して便利ですよ。

動作確認の手順


接続が済んだら、以下の順番で確認していくとスムーズです。

  1. STEP1のUID読み取りスケッチを書き込み、シリアルモニターでカードのUIDを確認する
  2. UIDをメモしてSTEP2のスケッチのREGISTERED_UIDS配列に追記する
  3. メインスケッチを書き込み、登録カードをかざして緑LED点灯+サーボ回転を確認する
  4. 未登録カードをかざして赤LED点滅(拒否動作)を確認する
  5. サーボの角度(LOCK_ANGLEUNLOCK_ANGLE)を実際の錠前に合わせて微調整する

💡 サーボが動かない・変な動きをする場合は電源を疑ってください。サーボはArduinoの5Vピンから直接給電すると、電流不足でArduinoがリセットされることがあります。その場合は外部の5V電源を使いましょう。

まとめ

今回はPN532 NFCモジュールとArduinoを使ったDIYスマートロックの作り方を解説しました。

  • 🔑 NFCカードのUID読み取り → 登録リストと照合 → サーボで施錠/開錠という基本の流れ
  • 🔑 EEPROMを使えばスケッチを書き換えずにカード管理が可能
  • 🔑 本格運用にはUID認証+PINの二段階認証が有効

「市販のスマートロックって高いな…」と思っていた方も、これなら部品代3,000〜5,000円程度で試せます。ぜひ手を動かして、自分だけのスマートロックを作ってみてください!💪

次のステップとしては、Bluetoothモジュール(HC-05)と組み合わせてスマホアプリから解錠する仕組みや、ArduinoをMQTT対応にしてスマートホームと連携する応用も面白いですよ。引き続き一緒に学んでいきましょう!🚀

📡 Arduinoをもっと深く学ぼう!

Arduino・ラズパイ・ロボットプログラミングを体系的に学びたい方へ。おすすめのUdemyコースや電子部品もまとめています。

Arduinoロボット入門のおすすめコース・部品を見る →

📚 関連商品・おすすめ書籍

スッキリわかるPython入門 第2版 (スッキリわかる入門シリーズ)

もしも

スッキリわかるPython入門 第2版 (スッキリわかる入門シリーズ)

初心者に定番のPython入門書

Amazonで見る

Arduinoをはじめよう 第4版 (Make: PROJECTS)

もしも

Arduinoをはじめよう 第4版 (Make: PROJECTS)

Arduino公式推薦の定番入門書

Amazonで見る

徹底攻略! 電子工作&プログラミング Arduinoで学ぶ電子工作完全ガイド

もしも

徹底攻略! 電子工作&プログラミング Arduinoで学ぶ電子工作完全ガイド

電子工作とプログラミングを同時に学べる

Amazonで見る

※本記事にはアフィリエイトリンクが含まれます。

ABOUT ME
やまちゃん
これまで学生と社会人を合わせて5000人以上にプログラミング学習を指導。 ゼロからイチをわかりやすく解説する専門家として活動しており、本業ではArduinoを用いたIoT開発とロボットプログラミングが専門。 Pythonを用いたアプリ開発、ウェブアプリケーションの開発で業務の効率化をサポートしています。