To my great surprise it turns out you can nowadays get an RFID reader with 2 tags for somewhere between 7$ and 10$. Better yet, interfacing these to Arduino is well documented and several libraries are available for that purpose.
My friend who bought a couple of these asked me to see if I can read the tags directly from a Linux based ARM board (for example Raspberry Pi). It turned out to be rather easy as long as you aren’t interested in anything but the ID of the card. This can be done using rpi-rc522 library (NOT written by me). It sadly currently lacks any documentation or a Makefile so here are my notes on how to get it running.
First you have to connect the rc522 and RPi over the SPI interface. It will look something like this:
Then you have to install the bcm2835 library. Assuming that you have gcc and other essential development stuff already installed you can achieve it this way:
wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.35.tar.gz tar -zxf bcm2835-1.35.tar.gz cd bcm2835-1.35 ./configure sudo make install |
After that you can compile and run the rpi-rc522 with the following commands:
sudo apt-get install subversion svn checkout http://rpi-rc522.googlecode.com/svn/trunk/ rpi-rc522-read-only cd rpi-rc522-read-only/rc522 gcc config.c rfid.c rc522.c main.c -o rc522_reader -lbcm2835 sudo cp RC522.conf /etc/ ./rc522_reader -d |
You should see tag IDs in the output of the program as they are read. You can put these into the /etc/RC522.conf file and map each ID to a specific command to run there.
hi, if you are using SPI, why you connect SDA and SLC pin ?
thank you
I have no idea why they labeled the outermost pin as SDA.
It’s actually SPI’s SS
See http://s4.electrodragon.com/wp-content/uploads/2012/03/MF522-AN-5.jpg for better pinout description.
There’s no SLC pin, you probably misread SCK for SLC.
Hi Kadara,
good work.
It was the only fully working TUT and Code that worked for me.
But i’ve got some problems over here…
ive written a script which toggles an led.
normal shell run: all normal.
executed from the config of the rfid tool -> Nothing happens…
May you can help me
Regards
Florian form Germany π
thank you for the answer
i still have a question, what pin you connect for SDA n SCK on RSPI pin ?
Hi David,
i hope, i can help you a bit.
Here is a link to photos of my setup(just compare through the colours):
https://www.dropbox.com/sh/5hy5n273rna2s62/R_mMX_7NCS
This hardware setup works fine for me.
Just the green cable is unnessesary.(IRQ)
Good Luck
FLorian
hi florian,
that’s great ! thank you..
i appreciate that
hi Florian,
couple of hypothesis why you shell script might not run when called from the reader program
execl(“/bin/sh”,”sh”,”-c”,str,NULL);
Is your normal shell the same as /bin/sh and does your script work with it?
To debug it try to run /bin/sh -c ‘the command in your config’
Hi hadara,
its just a very small script. Here: http://pastebin.com/vJ7MkUU5
iam normally using bash… and with your command given it does nothing except empty lines with “>”. no output….
just like this
>
and is there a way to export the read serial? so that i use this programm just for reading?
i hope you can help me..
Florian
You probably forgot to terminate the single quotes around the script name.
Since your script doesn’t take any arguments you can just remove the quotes anyway and just test with something like:
/bin/sh -c /path/to/your/script.py
As to reading new serials there’s no good direct support but following hacks should work.
If you don’t describe any known serials in the configuration file and run the program in the debug mode it will print all the read serials into it’s output which you can read with other programs.
For example if you just want to extract serials from the output of the reading program and print out just the serial then something like this should work:
./rfid_reader -d 2>&1 | awk ‘{ print $5 }’ | cut -d ‘=’ -f 2
If you actually want to use the read serial in your python program then something like this would make more sense:
./rfid_reader -d 2>&1 | python /tmp/rfid_reader.py
where rfid_reader.py is comething like this:
import sys
while 1:
line = sys.stdin.readline()
if line == '':
break
if not line.startswith("New tag"):
continue
serial = line.split()[-1].split("=", 1)[1]
print(serial)
Another method would be to execute the reading program from your python script using subprocess.Popen() and read its output that way.
I don’t have the rc522 reader at hand anymore so none of this was actually tested.
I took a another look at the code of the library and I believe the reason why it doesn’t work with your script is that the rc522 reader binary drops root privileges to the UID given in the configuration file after doing the hardware initialization.
While this is good practice from the security perspective it also means your script isn’t called in the root privileges anymore. Accessing file /root/status.txt in your script and using RPi.GPIO module both probably require root access and will fail because of that.
The methods with piping that I described in my previous comment should still work though.
thx for your fast reply.
i want to use your last suggestion.
with subprocess. It now opens the process, and read all output…
Code: http://pastebin.com/W79M7abn
but i want to read just the serial. and after reading once: terminate subprocess, do some commands and then jump back to the loop and open the process again and so on
Iam new to python .. already codes java and php π
i hope you can help me again
Florian
killing the reading subprocess after each read tag doesn’t make much sense.
I suggest you let it run and do your stuff when the new tag is read.
Here’s a simple wrapper class that you can use for example.
You have to make a tiny modification to the main.c of the rc522 library and recompile it.
Look for the fprintf() containing “New tag: and add fflush(stderr); after that so that
the end result would look something like this:
if (debug) {
fprintf(stderr,"New tag: type=%04x SNlen=%d SN=%s\n",CType,SN_len,sn_str);
fflush(stderr);
}
This is just a way to get around the output buffering when using pipes. Otherwise python process wont see the serials until output buffer of the rfid_reader process is filled.
Wow.
You. are. amazing π
It works! π
but a small thing doesnt work π
i want to read from a .txt file. this works ^^
but i want to check for every new read serial, if this serial is in the text file.
with my code it works 1 time. no more.
I hope you can help me a last time π
i appreciate that
Yours Florian π
Edit:
now it works every time.. forgot fobj.close()
But how can i read multiple serials an then print e.g. the names after the serials from the .txt?
.txt like that:
[2f75b800]; Peter Pan
hope you can help me a very last time π
try something like this
Looks great.
But doesnt work π
my whole code: http://pastebin.com/RFeuR59Y
error:
Traceback (most recent call last):
File “./rfid_reader.py”, line 68, in
a= get_serialmap(sys.argv[1])
NameError: name ‘get_serialmap’ is not defined
but it is defined? :O
It’s defined as a class member. Remove the indentation before it so that it would be just a top level function.
ah… i oversaw it ..
okay. still another array error:
Traceback (most recent call last):
File “./rfid_reader.py”, line 66, in
print (get_serialmap(sys.argv[1]))
IndexError: list index out of range
thx π
well sys.argv is a list of command line arguments and sys.argv[1] is argument number 1.
In your case you probably want to define a variable containing your file name and use that as an argument instead.
ok. works again π
but it does not yet do, what i intend ..
i want tu print only this name, which belongs to the serial wich is read.
maybe check everytime if the serial is in the file and then print just this line?
well the get_serialmap() function returns mapping from serial to name. you can use something like:
serialmap = get_serialmap(filename)
if serial in serialmap:
print(“known tag with name”, serialmap[serial])
It’s up to you how often you want to re-read the mapping file…
Great! You’re awesome!
just a tiny thing:
my output is like this:
(‘known tag with name:’, ‘Peter Pan’)
how can this be?
snippet:
if __name__ == ‘__main__’:
datei=”/root/status.txt”
reader = RFIDReaderWrapper(“./rc522_reader -d”)
while 1:
fobj = open(“/root/status.txt”,”r+”)
serial = reader.read_tag_serial()
# blink the lights etc.
#print(serial)
serialmap = get_serialmap(datei)
#print serialmap
if serial in serialmap:
print(“known tag with name:”, serialmap[serial])
#print (get_serialmap(datei))
fobj.close()
use this instead:
print(βknown tag with name: %sβ % serialmap[serial])
the point is that in python 2.X print is a keyword so
print(“a”, b) prints out a tuple that consists of 2 elements: string a and variable b.
in python 3.X print() is a function, so
print(“a”, b) wouldn’t print the extra parentheses there because it would be just a call to the function print with 2 arguments.
the expression print(“a %s” % str(b)) should work in both python2 and python3 because in that case python2 will see it as a keyword print that is followed by string that is surronded by useless parenthesis and python3 will think of it as a function call.
Well…
I did’nt know, that python 2 was installed…
i’ve installed python 3..
I thank you very much for your help.
I want to publish my whole code on the internet.
Of course with you Name in the Credits π
Thank You π
hi, i’ve got problem here π
when i : #./rc522_reader -d
Collision
Collision
Collision
….
any idea ??
All is working in debug mode. Good
Bat I have not understand what do rc522_reader not in debug mode…
Write a log file ?
Thank you π
in general the collision happens when the reader sees multiple tags at once (for example when you wave your wallet at it that contains multiple rfid cards).
I assume the same can happen if you have noisy electrical connections
in the normal mode it’s meant to execute commands defined in the configuration file for the cards that are defined there.
unknown cards are read and memory dump is written into the directory that is defined under NEW_TAG_PATH variable in the configuration. By default this is /tmp
As far as I can see there’s no good way to just continuously read serials of all the cards that it sees without the debug mode. Probably the author of the library didn’t need that…
I’m trying to configure this for a school project, and I was wondering if you have an example of what the code would look like in the /etc/RC522.conf file for the IDs of the cards. I have some experience with programming, but not an extensive knowledge. I’ve looked at a few examples on the web, but I am still unclear as to how to proceed.
Also do the ID cards have to be saved in the RC522.conf file to stop them from going to the /tmp/?
In my (very simple) mind, it would be something like this:
if (code) = ID
run command
Obviously this is not how it would actually look, just kind of what I think the logic behind it would be.
Any help is definitely appreciated.
Thanks,
Jeff
There’s an example configuration file in the projects repository @ http://code.google.com/p/rpi-rc522/source/browse/trunk/rc522/RC522.conf
So yeah basically it’s just:
[card_ID] command to execute
If you don’t want to be memory dumps of unknown cards to be saved under /tmp you can just remove the NEW_TAG_PATH option from the configuration.
Hello,
I was wondering if you could help me. I am new to this so this question may sound simple.
I have followed your instructions and now have the RFID reader recognizing the cards and fobs (thanks)
I will be using a dual relay (5V DC Two 2 Channel Relay Module ) to activate a small solenoid. The problem i have is i need the activation of the RFID to set one of the RPi’s GPIO pins to low to activate the relay. I am hoping you might be able to point me in the right direction as i have no clue what to do next. I am also new to code.
Thanks
Bryn
There are many ways of doing this, one would be the approach that uses unix pipes that we discussed with Florian in this comment thread earlier.
What I would suggest instead is to write a simple HTTP service that can turn the light on or off based on the request URI. Then you can easily call it from the configuration of the rc522 utility by using wget command against specific URL on your server (which might run on the same or different machine).
I originally tested the library with this simple python script that runs a standalone webserver on port 8080 and plays different sounds when different URLs are accessed. You can use it as a basis and just replace sound playing with pin toggling.
You then just have to use someting like this in your rc522 configuration:
Hi,
Thanks for the info Hadara, im assuming it was for me. Unfortunately i didnt understand most of what you said, i am an ultra newby at this and as yet have no clue what im doing. If you could possibly explain it like your talking to an idiot ( that would be me) i would really appreciate it. If you dont have the time thats ok also. I am looking at the RC522.conf file now in leafpad and not sure if its the right file. also is it just the number of the keyfob or card that i use.
Thanks again.
Bryn
Hi bryn,
i think i could help you π
After much time I spend in my reader, I’ve created exactly what you want to do. (I think so :P)
Look right here: https://sourceforge.net/projects/rc522pythonscript/
If you have the 5V Relais for arduino you have to change some small resistors. If you’re interested, just let me know π
Regards, Florian
Florian, i tried your software above but am having issues. I tried the Text file one first, but got the following Syntax error.
File “rfid_reader.py line 16
filename=/root/db.txt
SyntaxError: invalid syntax.
I couldn’t try the SQL one, because I need better instructions as to how to set up the database.
On another note, I couldn’t get the basic RC522.conf file to execute commands. When i scan my cards in debug mode, I get the following..
Type:0400, Serial: 75305f74
New tag: type=0400 SNlen=4 SN=[75305f74]
If i edit the RC522.conf file in /etc, and add to the bottom
[75305f74] wget http://MyIP:8000
Then scan my card again in debug mode, i get:
Type: 0400, Serial 75305f74
Exit
But no command is ever executed? Any help would be greatly appreciated.
Thanks
craig
Thank you so much hadara, for making this, and to Florian for posting his pictures.
I am using the Raspberry Pi Rev. 2, and the Sunfounder RFID-RC522.
For anyone who is having issues with this certain model, the pin layout in as below:
RFID-RC522 – Rpi
VCC- pin 1, 3.3 volts
RST- pin 22, GPIO25
GND- pins, 6, 9, 14, 20, or 25, I personally used pin 6
MISO- pin 21, GPIO9
MOSI- pin 19, GPIO10
SCK- pin 23, GPIO11
NSS- pin 24, GPIO7
IRQ- Don’t Attach to rpi
I was having problems installing subversion in debian, it would ask if you are sure with so many bytes of space being taken up
after installation [Y/n]
I was doing Y , enter key, and it would abort, so I tried just hitting the enter key, no y, and it worked.
I’ve got multiple collisions. Checked wiring 5 times, replaced RFID reader with another one but still no success. Any help would be greatly appreciated π
when i put those codes into termonal on the pi it says bcm2835_init: Unable to open /dev/mem: Permission denied
what happened
hi, sorry for my bad english π
work perfect with nfc chip but nothing appears with rfid chip or card…. why?
thanks π
Hi, I am also facing the same problem which David has mentioned. I am getting multiple collisions in the output.
I have checked my wiring and connections but everything is fine. Also, there is only ONE RFID tag around.
Guys, please help me out
Hello,
I have the same issue as Craig here…
I have it connected, if I scan cards in the debug mode it comes up telling me something like :
Type:0400, Serial: 75305f74
New tag: type=0400 SNlen=4 SN=[75305f74]
If i edit the RC522.conf file in /etc, and add to the bottom
[75305f74] wget http://MyIP:8000
Then scan my card again in debug mode, i get:
Type: 0400, Serial 75305f74
Exit
But no command is ever executed?
I’ve tried different commands and different cards but can’t get anything to execute…
Has anyone found a solution to this?
Thanks in advance π
Ryan
Solved my own issue
For the reader to execute the commands you put into the config file you have to run :
sudo nohup /bin/rc522_reader &
So I put that command into
/etc/rc.local
And has been working great ever since π
Hi , thanks you a lot for this simply procedure to use this technology. I’ve installed all , no problem , i use this to open gate .
But i’ve seen that after a time .. 1 day 6 h or 12 h , script stop working .. but when i reboot or reopen script system work normally … you have some idea ?
I use Raspbian , rfid mc522 standard as you , out but not warn about water or other
thanks and sorry for english
Hi all,
can you help me, how about to save ID of Tag to SQL database with java, please reply this comment to my email tajudinsubki@gmail.com.
thanks
First i recommend to update library bcm2385 :
For rasberry pi 2 is good use 1.40 version not 1.35 , last 1.42 has some problems
wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.40.tar.gz
After for new kernel we must cut user root control to escape from many command issue , for example my command has gip control that not work as guest !
before compilate rc522 , go on main and at line 70 – 74 :
HW_init(spi_speed,gpio);
read_conf_uid(&uid);
setuid(uid);
InitRc522();
exclude uid control if
and all go π
hallo alex,
kannst du das nochmal auf deutsch schreiben.
dein englisch versteh ich nΓ€mlich nicht π
danke.
hi alex,
does your modification “before compilate rc522 , go on main and at line 70 β 74…”
solve your issue “after a time .. 1 day 6 h or 12 h , script stop working”?
jay
hi there,
rc522 is working great, but to push something to the db from the python script you first need to setup corresponded mysql database with the tables given… it would be nice if you could release the db-import file for creating such tables trough the python script you guys provided.
table rfid_card with rows name,money,counter,access
http://sourceforge.net/projects/rc522pythonscript
thx
Hello guys,
I`ve made the database scheme.
It can be seen/downloaded here: http://pastebin.com/Tij2qum6
I also upload it at my sourceforge page.
Greetings
Florian | otti96 AT t-online.de
has anyone tested this setup with a raspi v2 ?
I used it with the b+ and it works fine but my raspV2-Setup makes problems.
Maybe I got wiring problems but maybe, you know any software-problems ?
Greetings
Steffen
.