Back to Parent

#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!

0