I'm using this PN532 NFC reader with an Arduino Mega to unlock a door, and it's working well with cards and fobs. But as many people before me have discovered, our phones send a different UID string every time.
From Googling I can see that many other people have encountered this issue, and the common recommendation is to use a banking app like Google Pay, which they think must send the same string every time. But apparently that's not the case, it sends a unique code too (and for very good reason of course).
So I'm wondering: does anyone know of a way to send a specific string from an Android phone via NFC? Some app? I've found lots of Android apps for NFC, but I can't get any to send the same string every time, even when in write mode.
And I know this solution risks being low security, that's fine for this project.
Alas, for better or worse, I always have my phone on me, and I always keep it charged. And I no longer carry anything else with me consistently. Nor do the other people who need access to this lock.
And I know I could use a keypad type thing, but I'm thinking it should be possible to use a phone for this.
Okey. I do have 2 RF pads for a few different places and I find them very convenient, just pull it out of the pocket and hold it to the reader. Fiddling with the phone, opening the proper app etc.... Fun but... just fiddly.
Nevertheless, You want to develop Your idea. Sorry I can't assist You, only recommend You to keep Googling using whatever search word You can think of. Good luck!
Thanks. I've been down a lot of Google rabbit holes on this project. My current best lead is "RFID tag emulation for Android", but so far that's only for NDEF tags, which I haven't been able to successfully read yet. But I have hope. And dumb persistence.
Progress! I found an Android app called NDEF Tag Emulator, which can send NDEF messages. And I think it's doing so, but I still get an error when reading them.
I'm using the Elechouse PN532 library:
And using PN532's I2C mode (setting the jumpers to I2C). I'm connecting to the default SDA and SDL pins on my Mega2560 (pins 20 and 21).
#if 0
#include <SPI.h>
#include <PN532_SPI.h>
#include <PN532.h>
#include <NfcAdapter.h>
PN532_SPI pn532spi(SPI, 10);
NfcAdapter nfc = NfcAdapter(pn532spi);
#else
#include <Wire.h>
#include <PN532_I2C.h>
#include <PN532.h>
#include <NfcAdapter.h>
PN532_I2C pn532_i2c(Wire);
NfcAdapter nfc = NfcAdapter(pn532_i2c);
#endif
void setup(void) {
Serial.begin(115200); // changed from 9600
Serial.println("NDEF Reader");
Serial.println("Turn on PN532 now...");
delay(3000); // a delay to allow turning the PN532 on
nfc.begin();
}
void loop(void) {
Serial.println("\nScan a NFC tag\n");
if (nfc.tagPresent())
{
NfcTag tag = nfc.read();
Serial.println(tag.getTagType());
Serial.print("UID: ");Serial.println(tag.getUidString());
if (tag.hasNdefMessage()) // every tag won't have a message
{
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);
// Print the Hex and Printable Characters
Serial.print(" Payload (HEX): ");
PrintHexChar(payload, payloadLength);
// Force the data into a String (might work depending on the content)
// Real code should use smarter processing
String payloadAsString = "";
for (int c = 0; c < payloadLength; c++) {
payloadAsString += (char)payload[c];
}
Serial.print(" Payload (as String): ");
Serial.println(payloadAsString);
// id is probably blank and will return ""
String uid = record.getId();
if (uid != "") {
Serial.print(" ID: ");Serial.println(uid);
}
}
}
}
delay(1000); // changed from 3000
}
When I scan an RFID hotel room card I get this output:
But when using the Android NDEF Tag Emulator app I get:
I don't imagine anyone has any ideas?
And note that there appears to be a sometime bug in the PN532 when in I2C mode, where you need to power it on a short time after the Arduino, at least when Serial Monitor is open. Hence the delay in my setup().
It looks like the reading of the RFID works fine.'
Then... I'm guessing... Is some kind of transformation, data transformation/change needed?
To limit the line of logic I think You should focus on just sending from the controller to the phone app. Then You can "tilt" the data as You wish. -When You find a message/transmission that work You might find out what transformation You need to do.
Sun is raising here. High time to get horizontal....
On further testing I'm not sure the Android app is doing anything, I get the same message on the Arduino with the app closed. In other words I think it's just reading the standard data sent by my phone. My head hurts.
you have to differntiate: the UID will change, but you can talk with the banking app and you can retrieve the PAN - primary account number - and this PAN is very likely the same every time you read the phone. At least for ApplePay in Europe, and for sure for the Android banking app of my bank.
Well I never did figure out how to get a unique UID from people's phones directly, but I came up with a workaround that works so well I thought I'd post about it in case it's useful for anyone else.
NFC stickers:
They're apparently popular with people playing a game called Amiibo, and I still haven't figured out exactly what that is but a Google search for "amiibo stickers" comes up with a ton of these tags. People often write on them or even inkjet print onto them. They also come in black. They're also used for home automation. They're about the size of an American quarter, extremely thin and extremely sticky.
So I stick them on the phone, ideally under a case, of whoever I want to give access to, then record that sticker's UID. Works really well, and in some ways is better than using the phone's NFC since it doesn't depend on the phone's battery.
To minimize the chances of reading the phone's NFC I try to place them away from the phone's NFC antenna. Here's the Samsung S10 for example:
I think in general the NFC antenna is the wireless charging antenna, so middle of the rear of the phone. Some iPhone forums say this is the location though, not sure if this is correct:
I've been putting the stickers on the bottom rear of hte phone, and if I want to minimize the chance of it reading the phone's chip I hold the phone with my palm over the middle of the phone. Works really well, and finally can use my phone to open the door.