What rfid readers do you recommend to use with the Photon?

I am looking to do a rfid/nfc project that lets me do rapid programming of nfc tags. I found a board called the Adafruit PN532 NFC/RFID Controller Shield for Arduino but it costs $40 and I would also need the shield shield to use it with my Photon. The Adafruit PN532 NFC/RFID Controller Shield does everything I want I just would like to find a board that can do the same thing for a cheaper price and it would be nice if it was breadboard friendly but it fine if the board isn’t.

@rpiswag, I have had a lot of success with this MFRC522 based one. They are cheap and easy to use. If the PN532 is what you want, there is also this one. :smile:

2 Likes

I like the MFRC-522 based one but I have had some bad experiences with ebay but all the good fead back is a good sign that that seller is reputable. I live in the US and that like you posted if for Canada so is that board on the US version of ebay? Is that board genuine or is it a knock off or a fake copy of a genuine board?

Hi, I am also planning to install 3 MFRC-522 based RFID readers in our office.
I ordered them today.

Did you have success with your project?
Does the arduino library need adaptation for the Photon or is it already included in the web IDE?

Tks!

@FiDel, there are several RFID device libraries in the IDE including one for the MRFC-522. Make sure to pay attention to the wiring for “SPARK” in the example app comments. Also, you should power the device from the Photon 3V3 and GND pins.

1 Like

@peekay123 :sunny: Thanks so much for your quick reply!
Hoping my 3 RFID readers will be delivered soon from China…
Meanwhile I’d like to prepare the sketch for a Photon.
I found the “MFRC522” directory in the web IDE but I’m overwhelmed by the collection of files it contains…

Let me confirm how to use all this:

  • I guess “DumpInfo.ino” is the example sketch to start with, right?
    There, I find following Pin layout instructions:

Signal - SPARK - MFRC522 board
Reset - ANY (D2) - RST
SPI SS - ANY (A2) - SDA
SPI MOSI - A5 - MOSI
SPI MISO - A4 - MISO
SPI SCK - A3 - SCK

I understand this:

  • For the Reset and SPI SS signals, we can use any pin but the library uses D2 and A2.
  • For the other SPI signals, A5, A4 and A3 must be used.
  • In the initial section of “DumpInfo.ino” I see:

'#define SS_PIN SS
#define RST_PIN D2

=> I guess for the Particle devices, we need to change the first line to: #define SS_PIN A2

  • Is it correct that the “Dump” of card data will be sent to the Photon USB serial monitor?
    Interesting…
  • The other files in the directory demonstrate all kind of fancy functions with the cards but I am wondering what I need from all this…

Now, where do we go from here?

The only thing I want to achieve is an authorization if a registered card is used:

  • How can I register multiple card IDs and make the Photon set a pin HIGH when one of the registered cards is presented?

Is there anyone who has made a (simple) working script for a Particle device?

Any tip is welcome!

I built a device using the RC522 for a pre-pad Card System for our Offices coffee vending machine and it works great for that. I’ll post the first draft of the Code below (though it worked so fine for some weeks now that i’ll might just leave it that way). it only reads out the Card ID, the rest is handled via an internal Server.

 #include "HttpClient/HttpClient.h"
 #include "MFRC522/MFRC522.h"

#define SS_PIN SS
#define RST_PIN D2

MFRC522 mfrc522(SS_PIN, RST_PIN);

int relayPin = D4;
int photoPin = A1;
int powerPin = A0;

SYSTEM_MODE(SEMI_AUTOMATIC);
SYSTEM_THREAD(ENABLED);

IPAddress server(192,168,1,114);
HttpClient http;
http_request_t request;
http_response_t response;
http_header_t headers[] = {{ "Accept" , "*/*"},{ NULL, NULL }};

STARTUP(WiFi.selectAntenna(ANT_EXTERNAL))

void setup() {

Serial1.begin(9600);

Particle.function("serverCMD", serverCMDHandler);

Particle.connect();    

nextionExecute();

setText(0, "t0", " ... Initialisierung ...");

delay(500);

mfrc522.setSPIConfig();

setText(0, "t0", " ... SPI Config ...");

delay(500);

mfrc522.PCD_Init();	// Init MFRC522 card

setText(0, "t0", " ... PCD Init ...");

delay(500);

setText(0, "t0", " ... Server Connection ...");

while(!Particle.connected()) {

    Particle.process();
    delay(10);
    
}

pinMode(powerPin, OUTPUT);

digitalWrite(powerPin, HIGH);

pinMode(relayPin, OUTPUT);

digitalWrite(relayPin, HIGH);

pinMode(photoPin, INPUT_PULLDOWN);

Serial1.write("page 1");

nextionExecute();

}

void loop() {

Particle.process();
delay(10);

// New card?
if ( ! mfrc522.PICC_IsNewCardPresent()) {
	return;
	
}

// choose card
if ( ! mfrc522.PICC_ReadCardSerial()) {
	return;
	
}

String cardID = "";

for (byte i = 0; i < mfrc522.uid.size; i++) 

{
    cardID += String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : "");
    
    cardID += String(mfrc522.uid.uidByte[i], HEX);
    
}

executeRequest(cardID);

mfrc522.PICC_HaltA();
}

void executeRequest(String cardID) {

Serial1.write("page 2");
nextionExecute();
setText(2, "t0", cardID);
serverCMDHandler(queryServer(cardID));
}


int serverCMDHandler(String command) {

int cmd = getValue(command, '|', 0).toInt();

    switch (cmd) {
    
    case 0: // No more coffee for you!

        setText(2, "t4", getValue(command, '|', 1));
        setText(2, "t5", getValue(command, '|', 2));
        setText(2, "t6", getValue(command, '|', 3));
        
        Serial1.write("t6.bco=63488");
        
        Serial1.write(0xFF);
        Serial1.write(0xFF);
        Serial1.write(0xFF);
        
        refreshComponent("t6");
        
        delay(3000);
        Serial1.write("page 1");
        nextionExecute();

    break;
    
    case 1: // Enjoy your Coffee
    
        setText(2, "t4", getValue(command, '|', 1));
        setText(2, "t5", getValue(command, '|', 2));
        setText(2, "t6", getValue(command, '|', 3));
        
        
        Serial1.write("t6.bco=1007");
        
        nextionExecute();
        
        refreshComponent("t6");
        
        switchRelay();
        
        delay(5000);
        
        setText(2, "t5", getValue(command, '|', 4));
        
        nextionExecute();
        
        refreshComponent("t5");
        
        setText(2, "t5", getValue(command, '|', 4));
        
        delay(25000);
        
        do {
            
            switchRelay();
            
            delay(300);

            if (analogRead(photoPin)<100) {
                break;
                
            }

            delay(5000);
            
        } while (analogRead(photoPin)>100);

        Serial1.write("page 1");
        
        nextionExecute();

    break;
    
    case 2: // From Android (Tasker Autovoice / IFTT)
    
        executeRequest(getValue(command, '|', 1));
    
    break;
    
    }
}


String queryServer(String cardID) {

request.hostname = server;
request.port = 1234;
request.path = "/webApi/api/kaffee/" + cardID;
http.get(request, response, headers);
return response.body.remove(0, 1);

}

String getValue(String data, char separator, int index) {
int found = 0;
int strIndex[] = {
    0, -1  };
    int maxIndex = data.length()-1;
for(int i=0; i<=maxIndex && found<=index; i++){
if(data.charAt(i)==separator || i==maxIndex){
      found++;
      strIndex[0] = strIndex[1]+1;
strIndex[1] = (i == maxIndex) ? i+1 : i;
  }
  }
 return found>index ? data.substring(strIndex[0], strIndex[1]) : "";

}


void switchRelay() {

digitalWrite(relayPin, LOW);
        
delay(300);
        
digitalWrite(relayPin, HIGH);

}


void nextionExecute() {

Serial1.write(0xFF);
Serial1.write(0xFF);
Serial1.write(0xFF);

}


void setPic(const int page, const char* name, const int pic) {

  char buffer[100];
  sprintf(buffer, "page%d.%s.pic=%d", page, name, pic);
  Serial1.write(buffer);
  nextionExecute();

}

void setText(const int page, const char* name, const char* value) {
char buffer[100];
sprintf(buffer, "page%d.%s.txt=\"%s\"", page, name, value);
Serial1.write(buffer);
nextionExecute();

}


void refreshComponent(const char* name) {

String cmd = "ref ";
cmd += name;
Serial1.write(cmd);
nextionExecute();

}
1 Like

Here’s a Picture of it:

This was my very first microcontroller project at all, so i’m quite proud it worked out so well (-;

5 Likes

@smnnekho : Thanks for sharing your nice coffe-access project.
Congratulations if this is your first microcontroller project!
But you are a very experienced programmer…
I try to follow your sketch but some parts go “over my head”… :wink:

I’d like to keep my sketch as simple as possible.
So, forgive me but I stripped out all that I believe I don’t need.

Could you please have a look if this modified sketch has any chance to do what I want?


*/* MFRC522 card reader: When an RFID card is swiped in front of the reader,*
*a relay should be turned ON for 3s, then OFF again.*

*This sketch is based on a sketch from "smnnekho" (Particle community)*
*It is being modified by FiDel to the "BARE ESSENTIALS"*

*Removed lines are related to:*
*- The internal server*
*- Handling of names and photos*
*- The LCD display used*

*Not yet tested! Any comments and improvements are welcome!*
**/*

*'#include "MFRC522/MFRC522.h"*

*#define SS_PIN SS*
*#define RST_PIN D2*

*MFRC522 mfrc522(SS_PIN, RST_PIN);*

*int relayPin = D4;*

*void setup()*
*{*
  *Serial.begin(9600);*
  *Serial.println(" ... Initializing ...");*

  *delay(500);*

  *mfrc522.setSPIConfig();*
  *Serial.println(" ... SPI Config ...");*
  *delay(500);*

  *mfrc522.PCD_Init();	// Init MFRC522 card*
  *Serial.println(" ... PCD Init ...");*
  *delay(500);*

  *while(!Particle.connected())*
  *{*
   *Particle.process();*
   *delay(10);*
  *}*

  *pinMode(relayPin, OUTPUT);*
  *digitalWrite(relayPin, LOW);*
  *Serial.println("page 1");*
*}*

*void loop()*
*{*
  *Particle.process();*
  *delay(10);*
  *// New card?*
  *if ( ! mfrc522.PICC_IsNewCardPresent())*
  *{*
   *return;*
  *}*

  *// choose card*
  *if ( ! mfrc522.PICC_ReadCardSerial())*
  *{*
   *return;*
  *}*

  *String cardID = "";*

  *for (byte i = 0; i < mfrc522.uid.size; i++)*
  *{*
   *cardID += String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : "");*
   *cardID += String(mfrc522.uid.uidByte[i], HEX);*
  *}*

  *executeRequest(cardID);*
  *mfrc522.PICC_HaltA();*
*}*

*void executeRequest(String cardID)*
*{*
  *Serial.println("page 2");*
  *setText(2, "t0", cardID);*
  *serverCMDHandler(queryServer(cardID));*
*}*

*int serverCMDHandler(String command)*
*{*
  *int cmd = getValue(command, '|', 0).toInt();*

  *switch (cmd)*
  *{*
   *case 0: // No action*
    *break;*

   *case 1: // Activate relay*
    *digitalWrite(relayPin, HIGH);*
    *delay(3000);*
    *digitalWrite(relayPin, LOW);*
    *break;*
  *}*
*}*

I cannot test this sketch yet, as I’m still waiting for my three sets of card readers.

Some more questions about this reader and the cards supplied with it:

Do these all contain the same ID?
If so, do we need to change the ID for security?
How can we change this ID in the easiest possible way?

Thanks for your help!

EDIT: Sorry for all the asterisks around the sketch lines… I don’t know how this happened. Probably as I tried to include preformatted text… :frowning:

not really - it was actually my very first C/C++/Wiring project too (-; But i do have experience in object oriented programming (mainly .net)

If you take a look at the MFRC522 (BUILD IDE or https://github.com/pkourany/MFRC522_RFID_Library) by courtesy of @peekay123 you’ll see a very basic DumpInfo.ino which prints out the cards UID via serial. You can then do with mfrc522.uid whatever you like to do.

https://github.com/pkourany/MFRC522_RFID_Library/blob/master/firmware/examples/DumpInfo/DumpInfo.ino

each card should have it’s own UID by default since it is random and very unlikely to have another one with the same ID.

2 Likes

OK Thanks @smnnekho !
I will come back after I received and tried my card readers…

@peekay123 @smnnekho
Thanks for your help: My RFID controlled doorlocks are working fine!

I have just one simple question:
Can we use digital pin D1 instead of analog pin A2 here?

@FiDel, yes you can change to D1 instead of A2. Make sure to change the constructor call to use D1 instead of SS (A2). :wink:

1 Like

@peekay123 : Thanks for your reply! (Analog pins are more precious for me… :wink: )

1 Like

Wow. This is fantastic! Great project!

I’m looking to make an attendance (check in/out) kiosk and this is a great bar to strive for! Do you have any write ups on this project? Love to see the process you went through!

hi, Peekay. Do you happen to have a code that would work for Parallax RFID reader. The code i am using right now compiles and flashes successfully, but it does not return the tag value. Also, the serial.available() returns a zero value.This is the code i am using:

int  val = 0; 
char code[10]; 
int bytesread = 0; 
int num;




void setup() 
{

Serial1.begin(2400);
Serial.begin(9600);

Particle.publish("insidee setup");
}  


 void loop() { 



Particle.publish("Testiiing");


delay(1000);



num=Serial1.available();
delay(1000);

Particle.publish("Serial.available",String(num));
delay(1000);

  if(Serial1.available()) {     
      // if data available from reader 
    delay(1000);

    if((val = Serial1.read()) == 10) {   // check for header 
      bytesread = 0; 
      while(bytesread<10) {              // read 10 digit code 
        if( Serial1.available() > 0) { 
          val = Serial1.read(); 
          if((val == 10)||(val == 13)) { // if header or stop bytes before the 10 digit reading 
            break;                       // stop reading 
          } 
          code[bytesread] = val;         // add the digit           
          bytesread++;                   // ready to read next digit  
        } 
      } 
      if(bytesread == 10) {              // if 10 digit read is complete 
               // print the TAG code 
        Particle.publish("Tag Code",code);
      } 
      bytesread = 0; 
      digitalWrite(D2, HIGH);                  // deactivate the RFID reader for a moment so it will not flood
           delay(1500);                       // wait for a bit 
           digitalWrite(D2, LOW);               // Activate the RFID reader
    } 
  } 
}

@raginigupta6, I’m not familiar with the Parallax unit. However, your code seems to have a lot of delays that may not be helping. If I get a chance, I’ll have a look and make some suggestions.

Thanks Peekay. Well, the result was the same even after removing the delays. I am thinking is it due to multiple serial interfaces of Particle which is causing the problem?
I hope my connections are right.
My connections are as follows:
RFID Reader Particle
.GND GND
Enable D2
SOUT RX
Vcc 3.3

You could always try a mere “serial pass-through” that only forwards whatever you receive via Serial1 to Serial and see what you get.
Make sure to use Serial.write() to avoid any unwanted “interpretation” via Serial.print().

What exact reader are you using? I couldn’t find one with a pin called 3.3V (and there is no Vcc pin on the Particles either :wink: )
Have you tried to power the reader off Vin rather than 3V3?

This datasheet says the supply power is 5V (min. 4.5V) not 3.3V!
https://www.parallax.com/sites/default/files/downloads/28140-28340-RFID-Reader-Documentation-v2.3.pdf

And /ENABLE stands for active LOW, but in order to initially activate your reader you’d need this in setup() (which you are missing)

  pinMode(D2, OUTPUT);
  digitalWrite(D2, LOW);

So no it’s not …

Thanks for the reply ScruffR. I guess i switched the names in the connections list between Photon and RFID reader. I am using the parallax reader.
I’ll work on the setup part as you mentioned and try powering the reader through 5V. Thank you :slight_smile: