Internet enabled door access system with RFID

As the topic suggest i am trying to build a door access system that relies on RFID and a online/offline website, with a user database (website is already built btw).

This has previously been done by Arduino users but none exact as my "must have" list. I found a good guide a couple of years back but the link has gone away now.

My plan is to have a user to swipe a RFID-tag which would trigger the Arduino to get the RFID-tag ID and send it to a website of choice. This website will then do a quick check to see if the ID is granted access and it will also save a log of each event, sending some sort of message or http request back to the Arduino that would help me sort if this is a ok entry or not and would allow me to trigger a voltage output via the relay-chip for a few seconds of the electrical lock on the door.

My setup as for now:

Arduino Uno v3
RC522 RFID
Network Shield
Relay chip (for triggering voltage output to the door mechanism)

I am a total rookie with Arduino and have no experience in C, Java etc but i do have JavaScript, ASP (classic) and PHP history.

I am going to try and solve this by my self and hopefully with some help from this forum but if someone have experience in working with these types of functions i am willing to buy services (sometimes it's better to leave it in the hands of pros) so feel free to send me a message with a quote if you feel this is your game.

I have been successful in getting the network shield to go to a website and get a full html response back, it would need some tweaks when integrating with RFID code later on but at least something is working.

When i tried to connect the RFID-reader i went into some trouble. I have been following guides if wire setup as well as using the test codes found in GitHub - miguelbalboa/rfid: Arduino RFID Library for MFRC522

I do get a solid red light from the RFID-reader and the message from Arduino when running "Dumpinfo" from the examples is "Scan PICC to see UID and type..." which would implicate that all is running smooth.
However when i swipe/hold the RFID-tag in front of the reader i get no action at all, i have tested with one tag and one card (the once i got in the package).

So i would say that i am pretty much stuck here.

Any suggestion on how to get pass the RFID-reader situation?

Also if you have some feedback on my project feel free to comment on it.

Oh i have noticed i am not the only one with this type of issue (RFID),

I get a version 1 only and not the 0x-- so maybe i have a even newer card.
I have ordered some new tags that should be in my possession on thursday, will be back with a report.

Sounds like a good project.
I tried making a game once with RFID tags.

I used this RFID shield from Adafruit. You might find their RFID tutorial helpful.

Nice one Pauly.

Thanks for the tip about the RFID-shield. I've ordered one to try out if i get stuck with the current RFID-reader.
I expect long delivery since i'm outside of US so i would still need to get pass the current issue.
Actually the Adafruit shield looks more stable and would suit my set-up better.

Today i have been soldering and i've also tried a few new tags.

At first i got no response but after double checking the soldering and removed the Ethernet shield i got tags to be read (even those that i got with the RFID-reader).

I have tested RFID-RC522 both on Arduino direct and on the Ethernet Shield when it was mounted on the Arduino board.
However the tags only get read if Ethernet Shield is completely removed.

Shouldn't i be able to mount the Ethernet Shield onto the Arduino board and then just add cables on the Ethernet Shield?

Please advice me what i may be doing wrong here.

I've attached picture of the current set-up which is working and you can see the Shield dismounted.

***** EDIT 2 *****
I have solved it by letting RFID use port 8 instead of port 10.

Example of beginning of file:

#include <SPI.h>
#include <RFID.h>
#include <Ethernet.h>

#define SS_PIN 8
#define RST_PIN 9

RFID rfid(SS_PIN, RST_PIN);

New day, new challenges. I have both Ethernet Shield and RFID to run smooth.

Today i need some input on the coding. I have been trying to get RFID to read tag and then execute a http request. (My goal is to send tag-id to web server and then get a true/false or similar back to me).

My code does almost this now but when i read http response back i get each character with a small delay of 100ms so my http response got read back in very very slowly, many seconds for a small website.

When i run the example code called "WebClient" i get http data read much much faster. But the request is made once and in void setup not in loop.

A experienced Arduino "eye" can probably spot my mistake in the code below:

/**

  • Read a card using a mfrc522 reader on your SPI interface
  • Pin layout should be as follows (on Arduino Uno):
  • MOSI: Pin 11 / ICSP-4
  • MISO: Pin 12 / ICSP-1
  • SCK: Pin 13 / ISCP-3
  • SS: Pin 10
  • RST: Pin 9
  • Script is based on the script of Miguel Balboa and Henri de Jong.
  • @version 0.1
  • @author W-man
  • @since 06-02-2015
    */

#include <SPI.h>
#include <RFID.h>
#include <Ethernet.h>

#define SS_PIN 8
#define RST_PIN 9

RFID rfid(SS_PIN, RST_PIN);

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(10,0,0,21);

// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
//IPAddress server(74,125,232,128); // numeric IP for Google (no DNS)

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

char server[] = "www.google.com"; // name address for Google (using DNS)

// Setup variables:
int serNum0;
int serNum1;
int serNum2;
int serNum3;
int serNum4;

void setup()
{
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
SPI.begin();
rfid.init();

// give the Ethernet shield a second to initialize:
delay(1000);
Ethernet.begin(mac, ip);
// print the Ethernet board/shield's IP address:
Serial.print("My IP address: ");
Serial.println(Ethernet.localIP());
}

void loop()
{

// if there are incoming bytes available
// from the server, read them and print them:
if (client.available()) {
char c = client.read();
Serial.print(c);
}

if (rfid.isCard()) {
if (rfid.readCardSerial()) {

/* With a new cardnumber, show it. */
Serial.println(" ");
Serial.println("Card found");
delay(1000);
serNum0 = rfid.serNum[0];
serNum1 = rfid.serNum[1];
serNum2 = rfid.serNum[2];
serNum3 = rfid.serNum[3];
serNum4 = rfid.serNum[4];

//Serial.println(" ");
Serial.println("Cardnumber:");
Serial.print("Dec: ");
Serial.print(rfid.serNum[0],DEC);
Serial.print(", ");
Serial.print(rfid.serNum[1],DEC);
Serial.print(", ");
Serial.print(rfid.serNum[2],DEC);
Serial.print(", ");
Serial.print(rfid.serNum[3],DEC);
Serial.print(", ");
Serial.print(rfid.serNum[4],DEC);
Serial.println(" ");

Serial.print("Hex: ");
Serial.print(rfid.serNum[0],HEX);
Serial.print(", ");
Serial.print(rfid.serNum[1],HEX);
Serial.print(", ");
Serial.print(rfid.serNum[2],HEX);
Serial.print(", ");
Serial.print(rfid.serNum[3],HEX);
Serial.print(", ");
Serial.print(rfid.serNum[4],HEX);
Serial.println(" ");

httpRequest();

}
}

rfid.halt();

}

void httpRequest() {
// if there's a successful connection:
if (client.connect(server, 80)) {
Serial.println("connecting...");
// send the HTTP PUT request:
client.println("GET /search?q=arduino HTTP/1.1");
client.println("Host: www.google.com");
client.println("User-Agent: arduino-ethernet");
client.println("Connection: close");
client.println();

Serial.println("connection executed...");

}
else {
// if you couldn't make a connection:
Serial.println("connection failed");
Serial.println("disconnecting.");
client.stop();
}
}

Your loop() function checks for and reads a single response character, then calls if (rfid.isCard()). How long does that RFID call take? That's seems to be about the only thing that would slow you down.

One optimization may be change if (client.available()) to while (client.available()). That will keep reading characters as quickly as possible as long as they are there, only going on to look for a card once there are no more. That should make it more responsive, but shouldn't hold up card reading too much since you generally won't spend a long time processing responses.

ShapeShifter:
Your loop() function checks for and reads a single response character, then calls if (rfid.isCard()). How long does that RFID call take? That's seems to be about the only thing that would slow you down.

One optimization may be change if (client.available()) to while (client.available()). That will keep reading characters as quickly as possible as long as they are there, only going on to look for a card once there are no more. That should make it more responsive, but shouldn't hold up card reading too much since you generally won't spend a long time processing responses.

Thanks for your help =) I got it to read as expected after changing if to while. The read-speed for isCard is rather quick so it was only that issue.

Next issue is that the script (http request) only fires every second time. First time with any card its ok and i get http response back. Next tag on the reader (same or new) shows only connection failed. Then next tag show http fine and then it continues to runt every second time. Should i close the connection or something after each successful read/http?

The next question is if there is a possibility to return only one string from a http request and not the full header?
I would only need one word back. I know this is possible with Json and so on and i would hope i could create something similar in order to avoid searching returned text string from http request.

Again thanks for any comments.

Note: I am not familiar with the Ethernet library, but I have done a bunch of network programming on other platforms. So while I don't know specifics about the library, I do speak with some experience.

kraspor:
Should i close the connection or something after each successful read/http?

Yes, I would stop the connection after a successful access. It's good programming style, and the examples I see all call stop() on the client when they are done.

In the code you posted, you don't look for the response from the HTTP request. If you close the client right after sending your request, you might kill off the request before it has a chance to complete. You might have to add some code to look for at least the beginning if the response before closing it (I would look for at least the initial "200 OK" status response.

I know this is possible with Json and so on and i would hope i could create something similar in order to avoid searching returned text string from http request.

You get back everything the server sent. Your JSON processing library is likely doing the parsing/processing for you and hiding this from you. If you just want to find the body of the response and skip the headers, perhaps you could read lines until you find the blank line that separates the header and body, and then start reading body lines?

Alrighty then... 8)

With some help from ShapeShifter and jesusverastegui and some other forum threads i have been able to get a first prototype running with a relay as well.

A tag is placed on RFID-reader, then we send tagID with HTTP-request to a server of some kind then we process the returned data (true), if true power will be sent to relay for 3 seconds.

I tried to add a video but failed so you have to settle with a picture.

My code is as follows, please comment any potential errors:

/**

  • Read a card using a mfrc522 reader on your SPI interface
  • Pin layout should be as follows (on Arduino Uno):
  • MOSI: Pin 11 / ICSP-4
  • MISO: Pin 12 / ICSP-1
  • SCK: Pin 13 / ISCP-3
  • SS: Pin 10
  • RST: Pin 9
  • @version 0.1
  • @author kraspor
  • @since 06-02-2015
    */

#include <SPI.h>
#include <RFID.h>
#include <Ethernet.h>

#define SS_PIN 8
#define RST_PIN 9

RFID rfid(SS_PIN, RST_PIN);

// Enter a MAC address for your controller below.
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(10,0,0,21);

// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
char server[] = "www.yourdomainname.com";

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

// Setup variables:
String serNumAll;
String inData;

//Fix relay pin
const int relay = 6;

void setup()
{

Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
SPI.begin();
rfid.init();

//Relay initiate
pinMode(relay,OUTPUT);

// give the Ethernet shield a second to initialize:
delay(1000);
Ethernet.begin(mac, ip);

// print the Ethernet board/shield's IP address:
Serial.print("My IP address: ");
Serial.println(Ethernet.localIP());

}

void loop()
{

// if there are incoming bytes available
// from the server, read them and print them:
while (client.available()) {
char c = client.read();
inData += c;

// see if header http response has ended
if (c == '\n')
{
Serial.print(inData);
inData = "";
}

// if the string is "true" then return message to client
if (inData == "true") {
Serial.write("You got true!\n");
inData = "";

//Kick/close power via relay for 3 seconds
analogWrite(relay,255);
delay(3000);
analogWrite(relay,0);

}
}

if (rfid.isCard()) {
if (rfid.readCardSerial()) {

client.stop();

/* With a new cardnumber, show it. */
Serial.println(" ");
Serial.println("Card found");

serNumAll += rfid.serNum[0];
serNumAll += rfid.serNum[1];
serNumAll += rfid.serNum[2];
serNumAll += rfid.serNum[3];
serNumAll += rfid.serNum[4];

//Serial.println(" ");
Serial.println("Cardnumber:");
Serial.print(serNumAll);
Serial.println(" ");

rfid.halt();
httpRequest(serNumAll);
serNumAll = "";
delay(1000);

}
}

rfid.halt();

}

void httpRequest(String serNumAll) {
// if there's a successful connection:
if (client.connect(server, 80)) {
Serial.println("connecting...");
// send the HTTP PUT request:
client.print("GET /yourfile.php?tagid=");
client.print(serNumAll);
client.println(" HTTP/1.1");
client.println("Host: www.yourdomainname.com");
client.println("User-Agent: arduino-ethernet");
client.println("Connection: close");
client.println();

}
else {
// if you couldn't make a connection:
Serial.println("connection failed");
Serial.println("disconnecting.");
client.stop();
}
}