Skip to content

Instantly share code, notes, and snippets.

@scottstamp
Created May 20, 2024 02:59
Show Gist options
  • Save scottstamp/2f3651ead609d5fe01eee0b8e201acd2 to your computer and use it in GitHub Desktop.
Save scottstamp/2f3651ead609d5fe01eee0b8e201acd2 to your computer and use it in GitHub Desktop.
ESP8266 PN532 NDEF reader/writer

Explanation:

  • Setup WiFi and PN532: Connect to the WiFi network and initialize the PN532 NFC reader.
  • Reading NFC Tags: The readNFC function reads NFC tags, decodes the URI and text fields, and sends them to a specified HTTP endpoint.
  • HTTP Server: The ESP8266 hosts an HTTP server with a /writeNDEF endpoint to receive JSON payloads to write to NFC tags.
  • Writing to NFC Tags: The writeNDEFToTag function writes the received URI and description to a new NFC tag.

Notes:

  • Ensure you replace YOUR_SSID, YOUR_PASSWORD, and http://yourserver.com/endpoint with your actual WiFi credentials and server URL.
  • The code uses NdefRecord for creating URI and text records. Adjust as needed based on your NFC library's API.
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266WebServer.h>
#include <ArduinoJson.h>
#include <Wire.h>
#include <Adafruit_PN532.h>
#include <NdefMessage.h>
#include <Ndef.h>
#include <NfcAdapter.h>
// Replace these with your network credentials
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
// Your server endpoint to send the read tag data
const char* serverUrl = "http://yourserver.com/endpoint";
// PN532 configuration
#define SDA_PIN 4 // D2 on NodeMCU
#define SCL_PIN 5 // D1 on NodeMCU
Adafruit_PN532 nfc(SDA_PIN, SCL_PIN);
NfcAdapter nfcAdapter(nfc);
ESP8266WebServer server(80);
void setup() {
Serial.begin(115200);
delay(10);
// Connect to Wi-Fi
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
// Initialize NFC reader
nfc.begin();
uint32_t versiondata = nfc.getFirmwareVersion();
if (!versiondata) {
Serial.print("Didn't find PN53x board");
while (1);
}
nfc.SAMConfig();
nfcAdapter.begin();
// Setup web server endpoints
server.on("/writeNDEF", HTTP_POST, handleWriteNDEF);
server.begin();
Serial.println("HTTP server started");
}
void loop() {
server.handleClient();
readNFC();
}
void readNFC() {
if (nfcAdapter.tagPresent()) {
NfcTag tag = nfcAdapter.read();
Serial.println("Found an NFC tag");
String uri = "";
String description = "";
if (tag.hasNdefMessage()) {
NdefMessage ndefMessage = tag.getNdefMessage();
for (int i = 0; i < ndefMessage.getRecordCount(); i++) {
NdefRecord record = ndefMessage.getRecord(i);
if (record.getType() == "U") {
uri = record.getUri();
} else if (record.getType() == "T") {
description = record.getText();
}
}
if (!uri.isEmpty() && !description.isEmpty()) {
sendToServer(uri, description);
}
}
delay(1000); // Add a delay to prevent reading the same tag multiple times
}
}
void sendToServer(String uri, String description) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(serverUrl);
http.addHeader("Content-Type", "application/json");
StaticJsonDocument<256> doc;
doc["uri"] = uri;
doc["description"] = description;
String requestBody;
serializeJson(doc, requestBody);
int httpResponseCode = http.POST(requestBody);
if (httpResponseCode > 0) {
String response = http.getString();
Serial.println(httpResponseCode);
Serial.println(response);
} else {
Serial.print("Error on sending POST: ");
Serial.println(httpResponseCode);
}
http.end();
}
}
void handleWriteNDEF() {
if (server.hasArg("plain") == false) {
server.send(400, "application/json", "{\"error\":\"Invalid request\"}");
return;
}
String body = server.arg("plain");
StaticJsonDocument<256> doc;
DeserializationError error = deserializeJson(doc, body);
if (error) {
server.send(400, "application/json", "{\"error\":\"Invalid JSON\"}");
return;
}
const char* uri = doc["uri"];
const char* description = doc["description"];
if (writeNDEFToTag(uri, description)) {
server.send(200, "application/json", "{\"status\":\"Tag written successfully\"}");
} else {
server.send(500, "application/json", "{\"error\":\"Failed to write tag\"}");
}
}
bool writeNDEFToTag(const char* uri, const char* description) {
NdefMessage message = NdefMessage();
NdefRecord uriRecord = NdefRecord(NdefRecord::Uri, uri);
NdefRecord textRecord = NdefRecord(NdefRecord::Text, description);
message.addRecord(uriRecord);
message.addRecord(textRecord);
bool success = nfcAdapter.write(message);
return success;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment