Topic: This post is about the application of the MF522-AN RFID reader and the Arduino for cards-magic (current stage: Proof-of-concept).
Effect: A randomly picked spectator shuffles a deck of cards, picks out a card of his choice and puts it into an envelope, which he places on a table. The magician is able to tell which card he has chosen, just by concentration – never having touched the card not the deck.
Setup:
Getting the MF522-AN RFID reader working was pretty straightforward based on a script by Dr.Leong (http://www.b2cqshop.com/), which was sent to me after I purchased the hardware at ebay.
Pin on RFID reader |
Meaning |
Connect with Arduino |
Colour of the cable on the photo |
8 |
SS |
Pin 10 |
Yellow |
7 |
SCK |
Pin 13 |
Orange |
6 |
MOSI |
Pin 11 |
Green |
5 |
MISO |
Pin 12 |
Blue |
4 |
Nothing |
— |
|
3 |
M-GND |
Grnd |
Black |
2 |
RST |
Pin 5 |
White |
1 |
M+3.3V |
3.3V |
Red |
|
|
|
|
Wiring the MF522-AN RFID reader with the Arduino
In order to place a RFID chip into every card, I had to find rather thin ones (not built in plastic), which I found at ebay:
“NFC tag sticker label RFID IC 13.56MHz ISO14443A Mifare1k S50 Compatible” sold by zillashop: http://www.ebay.de/usr/zillashop
I then placed the RFID chip between two cards, glued them together (see photo 2). The RFID reader was able to read out the chip through my working desk: I placed the Arduino with the RFID under the desk and placed the envelope above it (on the desk).
I modified the script by Dr. Leong such that it would print the cards name (in case the RFID tag was known, otherwise it would use the standard output of Dr. Leong (as the Chinese characters will not show up here, I deleted the comments).
/* Arduino-program: I will only quote the modified "loop" statement here */
void loop() {
uchar i,tmp;
uchar status;
uchar str[MAX_LEN];
uchar RC_size;
uchar blockAddr;
String mynum = "";
status = MFRC522_Request(PICC_REQIDL, str);
if (status == MI_OK) {
/*
Serial.println("Card detected");
Serial.print(str[0],BIN);
Serial.print(" , ");
Serial.print(str[1],BIN);
Serial.println(" ");
*/
}
status = MFRC522_Anticoll(str);
memcpy(serNum, str, 5);
if (status == MI_OK){
char* cardName=new char[200];
cardName = "";
if (serNum[0]==75) cardName = "Ace of diamonds";
if (serNum[0]==219) cardName = "Ace of hearts";
if (serNum[0]==43) cardName = "Ace of spades";
if (serNum[0]==59) cardName = "Ace of clubs";
if (serNum[0]==235) cardName = "Queen of hearts";
if (cardName=="") {
Serial.println("Unknown card! The card's number is : ");
Serial.print(serNum[0]);
Serial.print(" , ");
Serial.print(serNum[1],BIN);
Serial.print(" , ");
Serial.print(serNum[2],BIN);
Serial.print(" , ");
Serial.print(serNum[3],BIN);
Serial.print(" , ");
Serial.print(serNum[4],BIN);
Serial.println(" ");
} else {
Serial.println(cardName);
}
delay(1000);
)
//Serial.println(" ");
MFRC522_Halt();
}
In order to do something with the output I wrote a small processing script to run on my PC, which had the Arduino attached to it. This is definitely why its currently only a “proof of concept”. In the final stage I will have to find a different method to transfer the information to the magician :)…
I used a modified code from D. Shiffman (http://shiffman.net/2007/11/13/e-mail-processing/). Unfortunately it took me quite some time to get it running, as some class definitions were missing and I needed to download the javax.mail first. I found the solution here: http://hamletbon.wordpress.com/2012/10/08/multithreaded-email-class-in-processing/
import processing.serial.*;
import javax.mail.*;
import javax.mail.internet.*;
import java.util.Properties;
final int LINE_FEED = 10;
Serial arduinoPort;
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
public class Auth extends Authenticator {
public Auth() { super(); }
public PasswordAuthentication getPasswordAuthentication() {
String username, password;
username = "<INSERT YOUR EMAIL USERNAME HERE>";
password = "<INSERT YOUR EMAIL PASSWORD HERE>";
//System.out.println("authenticating. . ");
return new PasswordAuthentication(username, password);
}
}
void setup() {
println(Serial.list());
String arduinoPortName = Serial.list()[2];
arduinoPort = new Serial(this, arduinoPortName, 9600);
arduinoPort.bufferUntil(LINE_FEED);
}
void draw() {
if (arduinoPort.available() > 0) {
final String arduinoOutput = arduinoPort.readStringUntil(LINE_FEED);
println(arduinoOutput);
// Create a session
String host="smtp.gmail.com";
Properties props=new Properties();
// SMTP Session
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.host", host);
props.put("mail.smtp.port", "25");
props.put("mail.smtp.auth", "true");
// We need TTLS, which gmail requires
props.put("mail.smtp.starttls.enable","true");
// Create a session
Session session = Session.getDefaultInstance(props, new Auth());
try {
// Make a new message
MimeMessage message = new MimeMessage(session);
// Who is this message from
message.setFrom(new InternetAddress("<INSERT YOUR EMAIL USERNAME HERE>", "<INSERT YOUR EMAIL USERNAME HERE>"));
// Who is this message to (we could do fancier things like make a list or add CC's)
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("<INSERT TARGET EMAIL ADRESS HERE>", false));
// Subject and body
message.setSubject(arduinoOutput);
message.setText(arduinoOutput);
// We can do more here, set the date, the headers, etc.
Transport.send(message);
println("Mail sent!");
}
catch(Exception e) {
e.printStackTrace();
}
}
}
Putting it all together it resulted in an e-mail to my iPad with subject (and body) being the name of the card, which was in the envelope put on my desk under which I put the RFID unit (wired to the Arduino, which was on USB cable attached to my desktop PC)… 🙂