%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#2C3E50', 'primaryTextColor': '#fff', 'primaryBorderColor': '#16A085', 'lineColor': '#16A085', 'secondaryColor': '#E67E22', 'tertiaryColor': '#7F8C8D', 'background': '#ffffff', 'mainBkg': '#2C3E50', 'secondBkg': '#16A085', 'tertiaryBkg': '#E67E22'}}}%%
flowchart TD
Tags[NFC Tags on Assets] -->|Tap| Reader[NFC Reader Gateway]
Reader -->|Bluetooth/Wi-Fi| Hub[IoT Hub]
Hub -->|MQTT/HTTP| Cloud[Cloud Platform]
Cloud -->|Analytics| Dashboard[Web Dashboard]
Cloud -->|Alerts| Mobile[Mobile App]
Cloud -->|Track| Inventory[Inventory System]
style Tags fill:#16A085,stroke:#2C3E50,color:#fff
style Reader fill:#2C3E50,stroke:#16A085,color:#fff
style Hub fill:#E67E22,stroke:#2C3E50,color:#fff
style Cloud fill:#7F8C8D,stroke:#333,color:#fff
879 NFC IoT Integration and Labs
879.1 Learning Objectives
By the end of this chapter, you will be able to:
- Build NFC Gateway Systems: Create NFC-to-cloud pipelines for IoT
- Implement Access Control: Develop ESP32-based NFC door lock systems
- Create Smart Home Servers: Build Raspberry Pi NFC automation servers
- Integrate with MQTT: Connect NFC events to IoT message brokers
879.2 Prerequisites
Before diving into this chapter, you should be familiar with:
- NFC Communication Fundamentals: Understanding NFC operating modes, tag types, and NDEF format
- NFC Implementation and Applications: Tag programming and real-world applications
- MQTT Messaging: Message broker concepts for IoT
NFC Deep Dives: - NFC Communication Fundamentals - Operating modes and NDEF - NFC Implementation and Applications - Tag programming - NFC Security and Comparisons - Security analysis
IoT Protocols: - MQTT Fundamentals - Message broker for IoT - CoAP Protocol - Lightweight IoT protocol
879.3 NFC in IoT Ecosystems
879.3.1 IoT Gateway Pattern
Example: Smart Factory Asset Tracking
# Requires paho-mqtt 2.0+
import nfc
import paho.mqtt.client as mqtt
import json
from datetime import datetime
# Connect to NFC reader and MQTT broker
clf = nfc.ContactlessFrontend('usb')
mqtt_client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="nfc-gateway")
mqtt_client.connect("mqtt.factory.local", 1883)
def on_tag_scan(tag):
"""Process scanned asset tag"""
asset_id = tag.identifier.hex()
# Read asset metadata from tag
if tag.ndef:
asset_name = tag.ndef.records[0].text
else:
asset_name = "Unknown"
# Publish to MQTT
data = {
"asset_id": asset_id,
"asset_name": asset_name,
"location": "Assembly Line 3",
"timestamp": datetime.now().isoformat(),
"scanned_by": "Worker-042"
}
mqtt_client.publish("factory/assets/scans", json.dumps(data))
print(f"Asset {asset_name} tracked at Assembly Line 3")
return True
# Listen for tags
print("Factory asset tracking active...")
clf.connect(rdwr={'on-connect': on_tag_scan})879.4 Hands-On Labs
879.4.1 Lab 1: ESP32 NFC Access Control System
Build an NFC-based door lock system using ESP32 and PN532 module.
Hardware Required: - ESP32 Development Board - PN532 NFC Reader Module (I2C) - Servo motor (SG90) for lock mechanism - NFC tags (Type 2 recommended) - LED (Green for granted, Red for denied) - Buzzer (optional) - Jumper wires - Breadboard
Wiring Diagram:
PN532 NFC Module β ESP32
VCC β 3.3V
GND β GND
SDA β GPIO 21 (I2C SDA)
SCL β GPIO 22 (I2C SCL)
Servo Motor β ESP32
Signal β GPIO 13
VCC β 5V (via external power if needed)
GND β GND
Green LED β GPIO 25 (via 220Ξ© resistor)
Red LED β GPIO 26 (via 220Ξ© resistor)
Buzzer β GPIO 27
Complete Code:
#include <Wire.h>
#include <PN532_I2C.h>
#include <PN532.h>
#include <NfcAdapter.h>
#include <ESP32Servo.h>
// Pin definitions
#define SERVO_PIN 13
#define GREEN_LED 25
#define RED_LED 26
#define BUZZER 27
// NFC setup
PN532_I2C pn532i2c(Wire);
NfcAdapter nfc = NfcAdapter(pn532i2c);
// Servo for lock
Servo lockServo;
// Authorized UIDs (add your NFC tag UIDs here)
String authorizedUIDs[] = {
"04 A3 B2 C1 D4 5E 80", // Alice's badge
"08 F7 E2 9A 3B 1C 4D", // Bob's badge
"12 34 56 78 9A BC DE" // Admin card
};
const int numAuthorizedUIDs = 3;
// Lock states
const int LOCKED_ANGLE = 0;
const int UNLOCKED_ANGLE = 90;
bool isLocked = true;
// Access log (circular buffer)
struct AccessLog {
String uid;
String status;
unsigned long timestamp;
};
AccessLog accessHistory[10];
int accessLogIndex = 0;
void setup() {
Serial.begin(115200);
Serial.println("\n=== ESP32 NFC Access Control System ===");
// Initialize pins
pinMode(GREEN_LED, OUTPUT);
pinMode(RED_LED, OUTPUT);
pinMode(BUZZER, OUTPUT);
// Initial state: deny
digitalWrite(GREEN_LED, LOW);
digitalWrite(RED_LED, HIGH);
// Initialize servo
lockServo.attach(SERVO_PIN);
lockServo.write(LOCKED_ANGLE);
// Initialize NFC
nfc.begin();
Serial.println("β NFC Reader initialized");
Serial.println("π± Ready to scan NFC tags...\n");
// Startup beep
beep(100);
}
void loop() {
// Check for NFC tag
if (nfc.tagPresent(1000)) { // 1 second timeout
NfcTag tag = nfc.read();
String uid = tag.getUidString();
Serial.println("\nββββββββββββββββββββββββββββββββ");
Serial.println("π± NFC Tag Detected");
Serial.print(" UID: ");
Serial.println(uid);
// Check authorization
if (isAuthorized(uid)) {
grantAccess(uid);
} else {
denyAccess(uid);
}
Serial.println("ββββββββββββββββββββββββββββββββ\n");
delay(2000); // Prevent multiple reads
}
delay(100);
}
bool isAuthorized(String uid) {
/**
* Check if UID is in authorized list
*/
for (int i = 0; i < numAuthorizedUIDs; i++) {
if (uid == authorizedUIDs[i]) {
return true;
}
}
return false;
}
void grantAccess(String uid) {
/**
* Grant access: unlock door, green LED, success beep
*/
Serial.println("β
ACCESS GRANTED");
// Visual feedback
digitalWrite(RED_LED, LOW);
digitalWrite(GREEN_LED, HIGH);
// Unlock door
lockServo.write(UNLOCKED_ANGLE);
isLocked = false;
// Audio feedback
beep(50);
delay(100);
beep(50);
Serial.println("π Door unlocked");
Serial.println(" Relocking in 5 seconds...");
// Log access
logAccess(uid, "GRANTED");
// Keep door unlocked for 5 seconds
delay(5000);
// Re-lock door
lockServo.write(LOCKED_ANGLE);
isLocked = true;
digitalWrite(GREEN_LED, LOW);
digitalWrite(RED_LED, HIGH);
Serial.println("π Door locked");
}
void denyAccess(String uid) {
/**
* Deny access: red LED, error beep
*/
Serial.println("β ACCESS DENIED");
Serial.println(" Unauthorized NFC tag");
// Visual feedback (red LED already on)
// Blink red LED
for (int i = 0; i < 3; i++) {
digitalWrite(RED_LED, LOW);
delay(100);
digitalWrite(RED_LED, HIGH);
delay(100);
}
// Audio feedback (long error beep)
beep(500);
// Log denied attempt
logAccess(uid, "DENIED");
}
void beep(int duration_ms) {
/**
* Sound buzzer for specified duration
*/
digitalWrite(BUZZER, HIGH);
delay(duration_ms);
digitalWrite(BUZZER, LOW);
}
void logAccess(String uid, String status) {
/**
* Record access attempt in circular buffer
*/
accessHistory[accessLogIndex].uid = uid;
accessHistory[accessLogIndex].status = status;
accessHistory[accessLogIndex].timestamp = millis();
accessLogIndex = (accessLogIndex + 1) % 10; // Circular buffer
// Print log entry
Serial.print("π Logged: ");
Serial.print(status);
Serial.print(" - ");
Serial.println(uid);
}
// Optional: Add command to print access history via Serial
void printAccessHistory() {
Serial.println("\n=== Access History (Last 10 attempts) ===");
for (int i = 0; i < 10; i++) {
if (accessHistory[i].uid != "") {
Serial.print(i + 1);
Serial.print(". ");
Serial.print(accessHistory[i].status);
Serial.print(" - ");
Serial.print(accessHistory[i].uid);
Serial.print(" @ ");
Serial.print(accessHistory[i].timestamp / 1000);
Serial.println("s");
}
}
Serial.println("=====================================\n");
}Expected Serial Monitor Output:
=== ESP32 NFC Access Control System ===
β NFC Reader initialized
π± Ready to scan NFC tags...
ββββββββββββββββββββββββββββββββ
π± NFC Tag Detected
UID: 04 A3 B2 C1 D4 5E 80
β
ACCESS GRANTED
π Door unlocked
Relocking in 5 seconds...
π Logged: GRANTED - 04 A3 B2 C1 D4 5E 80
π Door locked
ββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββ
π± NFC Tag Detected
UID: FF AA BB CC DD EE 11
β ACCESS DENIED
Unauthorized NFC tag
π Logged: DENIED - FF AA BB CC DD EE 11
ββββββββββββββββββββββββββββββββ
How to Add New Authorized Tags:
- Scan an unknown tag to get its UID from Serial Monitor
- Add the UID to the
authorizedUIDsarray:
String authorizedUIDs[] = {
"04 A3 B2 C1 D4 5E 80",
"YOUR NEW UID HERE"
};- Update
numAuthorizedUIDscount - Re-upload the code
879.4.2 Lab 2: Python NFC Smart Home Automation Server
Create a Raspberry Pi-based NFC smart home control system.
Hardware Required: - Raspberry Pi (3B+ or 4) - PN532 NFC Module (I2C or UART) - NFC tags (Type 2) - Optional: Smart home devices (lights, plugs via MQTT)
Installation:
# Install dependencies
pip3 install nfcpy paho-mqtt flask
# Enable I2C on Raspberry Pi
sudo raspi-config
# Interface Options β I2C β EnableComplete Code:
#!/usr/bin/env python3
"""
NFC Smart Home Automation Server
Raspberry Pi + PN532 + MQTT
Tap NFC tags to trigger smart home scenes
"""
import nfc
import paho.mqtt.client as mqtt
import json
from datetime import datetime
from flask import Flask, jsonify
import threading
class NFCSmartHomeServer:
def __init__(self):
# Tag-to-scene mappings
self.tag_scenes = {}
# Registered smart home devices
self.devices = {}
# Scene definitions
self.scenes = {}
# MQTT client
self.mqtt_client = None
# Access log
self.access_log = []
def setup_mqtt(self, broker="localhost", port=1883):
"""Connect to MQTT broker for smart home control"""
self.mqtt_client = mqtt.Client(
mqtt.CallbackAPIVersion.VERSION2,
client_id="nfc-smart-home"
)
self.mqtt_client.connect(broker, port)
self.mqtt_client.loop_start()
print(f"β Connected to MQTT broker: {broker}")
def register_device(self, device_id, name, topic):
"""Register a smart home device"""
self.devices[device_id] = {
"name": name,
"topic": topic,
"state": "OFF"
}
print(f"β Device registered: {name} ({device_id})")
def create_scene(self, scene_name, description, actions):
"""Create a smart home scene"""
self.scenes[scene_name] = {
"description": description,
"actions": actions
}
print(f"β Scene created: {scene_name}")
def map_tag_to_scene(self, tag_uid, scene_name):
"""Map NFC tag UID to scene"""
self.tag_scenes[tag_uid] = scene_name
print(f"β Tag {tag_uid} mapped to scene '{scene_name}'")
def execute_scene(self, scene_name):
"""Execute all actions in a scene"""
if scene_name not in self.scenes:
print(f"β Unknown scene: {scene_name}")
return False
scene = self.scenes[scene_name]
print(f"\n㪠Executing scene: {scene_name}")
print(f" {scene['description']}")
for action in scene['actions']:
self._execute_action(action)
print(f"β
Scene '{scene_name}' completed")
return True
def _execute_action(self, action):
"""Execute a single action"""
device_id = action.get('device')
command = action.get('command')
value = action.get('value')
if device_id in self.devices:
device = self.devices[device_id]
# Send MQTT command
if self.mqtt_client:
payload = json.dumps({
"command": command,
"value": value
})
self.mqtt_client.publish(device['topic'], payload)
# Update local state
device['state'] = value
print(f"β {device['name']} {command} {value}")
else:
print(f" β {action.get('description', 'Custom action')}")
def on_tag_scan(self, tag):
"""Callback when NFC tag is scanned"""
tag_uid = tag.identifier.hex()
print("\n" + "=" * 50)
print("π± NFC Tag Detected")
print(f" UID: {tag_uid}")
print(f" Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
# Log access
self.access_log.append({
"uid": tag_uid,
"timestamp": datetime.now().isoformat()
})
# Find and execute scene
if tag_uid in self.tag_scenes:
scene_name = self.tag_scenes[tag_uid]
self.execute_scene(scene_name)
else:
print(f"β οΈ Unknown tag: {tag_uid}")
print(" Register this tag with a scene")
print("=" * 50)
return True
def start_nfc_listener(self):
"""Start listening for NFC tags"""
try:
clf = nfc.ContactlessFrontend('usb')
print("β NFC reader initialized")
print("\n" + "=" * 50)
print("π NFC Smart Home Server Running")
print("=" * 50)
print("π± Tap NFC tag to trigger scenes...")
while True:
clf.connect(
rdwr={'on-connect': self.on_tag_scan},
terminate=lambda: False
)
except Exception as e:
print(f"β NFC Error: {e}")
print(" Make sure PN532 is connected")
def main():
"""Main entry point"""
server = NFCSmartHomeServer()
# Setup MQTT connection
server.setup_mqtt(broker="localhost", port=1883)
# Register smart home devices
server.register_device("light_001", "Living Room Light", "home/lights/living")
server.register_device("light_002", "Bedroom Light", "home/lights/bedroom")
server.register_device("thermo_001", "Thermostat", "home/climate/thermostat")
# Create scenes
server.create_scene(
"Goodnight",
"Turn off all lights, set thermostat to 68Β°F",
[
{"device": "light_001", "command": "turn", "value": "OFF"},
{"device": "light_002", "command": "turn", "value": "OFF"},
{"device": "thermo_001", "command": "set", "value": "68"}
]
)
server.create_scene(
"Wake Up",
"Turn on bedroom light, set thermostat to 72Β°F",
[
{"device": "light_002", "command": "turn", "value": "ON"},
{"device": "thermo_001", "command": "set", "value": "72"},
{"description": "Start coffee maker"}
]
)
server.create_scene(
"Welcome Home",
"Turn on lights, adjust temperature",
[
{"device": "light_001", "command": "turn", "value": "ON"},
{"device": "thermo_001", "command": "set", "value": "70"},
{"description": "Disarm security system"}
]
)
# Map NFC tags to scenes (replace with your tag UIDs)
server.map_tag_to_scene("04a3b2c1d45e80", "Goodnight")
server.map_tag_to_scene("08f7e29a3b1c4d", "Wake Up")
server.map_tag_to_scene("123456789abcde", "Welcome Home")
# Start web dashboard in background
print("β Web dashboard: http://localhost:5000")
# Start NFC listener (blocking)
server.start_nfc_listener()
if __name__ == "__main__":
main()Testing (Without Hardware):
If you donβt have NFC hardware, you can simulate tag scans:
# Add to NFCSmartHomeServer class:
def simulate_tag_scan(self, tag_uid: str):
"""Simulate NFC tag scan for testing"""
class FakeTag:
def __init__(self, uid):
self.identifier = bytes.fromhex(uid)
self.on_tag_scan(FakeTag(tag_uid))
# Usage:
server.simulate_tag_scan("04a3b2c1d45e80") # Triggers goodnight sceneExpected Output:
β NFC reader initialized
β Connected to MQTT broker: localhost
β Device registered: Living Room Light (light_001)
β Device registered: Bedroom Light (light_002)
β Device registered: Thermostat (thermo_001)
β Scene created: Goodnight
β Scene created: Wake Up
β Scene created: Welcome Home
β Tag 04a3b2c1d45e80 mapped to scene 'Goodnight'
β Tag 08f7e29a3b1c4d mapped to scene 'Wake Up'
β Tag 123456789abcde mapped to scene 'Welcome Home'
β Web dashboard: http://localhost:5000
==================================================
π NFC Smart Home Server Running
==================================================
π± Tap NFC tag to trigger scenes...
==================================================
π± NFC Tag Detected
UID: 04a3b2c1d45e80
Time: 2025-01-15 22:30:45
π¬ Executing scene: Goodnight
Turn off all lights, set thermostat to 68Β°F
β Living Room Light turn OFF
β Bedroom Light turn OFF
β Thermostat set to 68Β°F
β
Scene 'Goodnight' completed
==================================================
879.5 Python Implementations
879.5.1 Implementation 1: NFC Tag and Reader Simulator
Expected Output:
=== NFC Tag & Reader Simulation ===
βοΈ Writing to tag 04:A3:B2:C1:D4:5E:80
β Record written to tag 04:A3:B2:C1:D4:5E:80
βοΈ Writing to tag 04:A3:B2:C1:D4:5E:80
β Record written to tag 04:A3:B2:C1:D4:5E:80
βοΈ Writing to tag 08:F7:E2:9A:3B:1C:4D
β Incorrect password for tag 08:F7:E2:9A:3B:1C:4D
βοΈ Writing to tag 08:F7:E2:9A:3B:1C:4D
β Record written to tag 08:F7:E2:9A:3B:1C:4D
--- Reading Tags ---
π± Reading tag 04:A3:B2:C1:D4:5E:80 at 2.8cm
Record 1: U = https://iotclass.example.com
Record 2: T = Welcome to IoT Class!
β Tag out of range: 15.8cm (max: 10.0cm)
π Tag 04:A3:B2:C1:D4:5E:80 is now permanently read-only
βοΈ Writing to tag 04:A3:B2:C1:D4:5E:80
β Tag 04:A3:B2:C1:D4:5E:80 is locked (read-only)
--- Reader Statistics ---
Total reads: 2
Unique tags: 1
Average distance: 9.3cm
--- Tag Memory ---
Poster tag: 62/48 bytes
Payment tag: 30/4096 bytes
879.5.2 Implementation 2: NFC Payment System
Expected Output:
=== NFC Mobile Payment Simulation ===
β Card ending in 4532 added to iPhone-12-ABC123
β Card ending in 8765 added to iPhone-12-ABC123
--- Transaction 1: Coffee Purchase ---
π³ Terminal ready: $4.75 at Coffee Shop
π± Tap your device to pay...
π€ Biometric verified (fingerprint)
β
Payment successful: $4.75
Card: ****4532
Transaction ID: a3f7c2e1d9b4
--- Transaction 2: Grocery Purchase ---
π³ Terminal ready: $47.82 at Coffee Shop
π± Tap your device to pay...
π€ Biometric verified (fingerprint)
β
Payment successful: $47.82
Card: ****4532
Transaction ID: f8e2a7c3b1d6
--- Transaction 3: Large Purchase (Exceeds Limit) ---
β Amount $150.00 exceeds contactless limit $100.00
--- Transaction 4: Without Biometric ---
π³ Terminal ready: $12.50 at Coffee Shop
π± Tap your device to pay...
β οΈ Biometric not enabled - payment may require PIN
β Biometric authentication required
--- Terminal Summary ---
Total transactions: 3
Successful: 2
Today's total: $52.57
879.6 Summary
This chapter covered NFC IoT integration:
- Gateway Pattern: NFC readers connecting to cloud via MQTT
- Access Control Lab: ESP32-based door lock with PN532 reader
- Smart Home Server: Raspberry Pi automation with scene triggers
- MQTT Integration: Publishing NFC events to message brokers
879.7 Whatβs Next
Continue to NFC Security and Comparisons to explore NFC security analysis, payment security architecture, and detailed comparisons with Bluetooth LE and QR codes.