#include "application.h"
#include "MFRC522.h"
#include "MifareUltralight.h"
#include <math.h>
// MORE AT: https://github.com/aroller/NDEF-MFRC522
// MFRC522 Wiring
//
// Pin on MRFC522 Pin on Argon
// MOSI MO
// MISO MI
// SCK SCK
// SS A5
// RST A2 (configurable)
// GND GND
// 3v3 3v3
// IMPORTANT NOTE
// The MRFC522 Library (default) has an issue
// Described here: https://community.particle.io/t/mfrc522-rfid-library-stopped-working/61516/2
// It requires (since Nov 2021) adding the library manually and repairing a function
using namespace ndef_mfrc522;
#define SS_PIN SS //
#define RST_PIN D2
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
long lastDetection = -1;
String lastDetected = "";
long redetectAfter = 10000;
bool writeNextTag = false;
bool overwriteOK = false;
String ndef_text = "";
bool isURL = false;
void setup() {
Serial.begin(9600);
mfrc522.setSPIConfig(); // sets up SPI config
mfrc522.PCD_Init(); // Initialize RC522 card
// Use this to add a HTTP URL to the tag
// ARG: any string beginning 'http'
Particle.function( "addNFCURL", handleWriteNDefURL );
// Use this to add a piece of text or a message
// ARG: any string (limit will be 65 characters based on particles limits)
Particle.function( "addNFCTxt", handleWriteNDefText );
// By default this won't overwrite data on a tag
// If you want it to overwrite content, use the Particle console
// and call this function with 'allowed' as the arg.
Particle.function( "overwrite", handleOverwrite );
}
void loop() {
// Look for new cards
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return;
}
// Serial.println("New card Detected");
// Read tapped card data
if ( ! mfrc522.PICC_ReadCardSerial()) {
return;
}
Serial.println("Discovered Card");
String rfid_card_id = readTagID();
String payloads = readTagAndNDefInfo();
if( writeNextTag ){
if( payloads.length() > 0 and !overwriteOK ){
Serial.println( "Card not empty and cannot overwrite. Contains the following payload:" );
Serial.println( payloads );
}else{
Serial.println(F("Attempting to write to the card."));
if( isURL ){
writeURITag( ndef_text );
}else{
writeTextTag( ndef_text);
}
}
writeNextTag = false;
}
publishEvent( rfid_card_id );
delay( 1000);
}
int handleOverwrite( String cmd ){
if( cmd.indexOf( "allowed" ) < 0 ){
return -1;
}
overwriteOK = true;
return 1;
}
int handleWriteNDefURL( String cmd ){
if( cmd.indexOf( "http" ) < 0 ){
return -1;
}
ndef_text = cmd;
writeNextTag = true;
isURL = true;
return 1;
}
int handleWriteNDefText( String cmd ){
ndef_text = cmd;
writeNextTag = true;
isURL = false;
return 1;
}
void publishEvent( String data ){
long timeNow = millis();
if( lastDetection + redetectAfter < timeNow ){
lastDetection = timeNow;
Particle.publish("com/daraghbyrne/nfc-writer", data );
}
}
void writeURITag( String uri ){
//String url = String("http://daraghbyrne.me");
//String url = String(ndef_text);
ndef_mfrc522::NdefMessage message = ndef_mfrc522::NdefMessage();
message.addUriRecord(uri);
MifareUltralight writer = MifareUltralight(mfrc522);
bool success = writer.write(message);
if (success)
Serial.println(F("Success. Now read the tag with your phone."));
else
Serial.println(F("Failure. See output above?"));
delay(5000); // avoids duplicate scans
}
void writeTextTag( String txt ){
ndef_mfrc522::NdefMessage message = ndef_mfrc522::NdefMessage();
message.addTextRecord(txt);
MifareUltralight writer = MifareUltralight(mfrc522);
bool success = writer.write(message);
if (success)
Serial.println(F("Success. Now read the tag with your phone."));
else
Serial.println(F("Failure. See output above?"));
delay(5000); // avoids duplicate scans
}
String readTagID(){
// discover the id of the last item;
String uuid = "";
for (byte i = 0; i < mfrc522.uid.size; i++) {
// Create a RFID Hexdecimal String
uuid += String(mfrc522.uid.uidByte[i], HEX);
}
// Convert to Uppercase
uuid.toUpperCase();
Serial.println(uuid);
return uuid;
}
String readTagAndNDefInfo(){
MifareUltralight reader = MifareUltralight(mfrc522);
NfcTag tag = reader.read();
String payloads = "";
if( tag.hasNdefMessage() )
{
ndef_mfrc522::NdefMessage message = tag.getNdefMessage();
Serial.print("\nThis NFC Tag contains an NDEF Message with ");
Serial.print(message.getRecordCount());
Serial.print(" NDEF Record");
if (message.getRecordCount() != 1) {
Serial.print("s");
}
Serial.println(".");
// cycle through the records, printing some info from each
int recordCount = message.getRecordCount();
for (int i = 0; i < recordCount; i++)
{
Serial.print("\nNDEF Record ");Serial.println(i+1);
NdefRecord record = message.getRecord(i);
// NdefRecord record = message[i]; // alternate syntax
Serial.print(" TNF: ");Serial.println(record.getTnf());
Serial.print(" Type: ");Serial.println(record.getType()); // will be "" for TNF_EMPTY
// The TNF and Type should be used to determine how your application processes the payload
// There's no generic processing for the payload, it's returned as a byte[]
int payloadLength = record.getPayloadLength();
byte payload[payloadLength];
record.getPayload(payload);
// Force the data into a String (might work depending on the content)
// Real code should use smarter processing
String payloadAsString = "";
Serial.print( "Payload has lenght:" ) ;
Serial.println( payloadLength );
for (int c = 0; c < payloadLength; c++) {
Serial.print( payload[c], HEX );
char cc = (char)payload[c];
Serial.print( cc );
payloadAsString += String( cc ) ;
}
Serial.print("\n Payload (as String): ");
Serial.println(payloadAsString);
payloads += payloadAsString + ";";
// id is probably blank and will return ""
String uid = record.getId();
if (uid != "") {
Serial.print(" ID: ");Serial.println(uid);
}
}
if( payloads.length() > 0 )
payloads = payloads.remove( payloads.length() -1 );
return payloads;
}else{
return "";
}
}
Click to Expand
Content Rating
Is this a good/useful/informative piece of content to include in the project? Have your say!
You must login before you can post a comment. .