
EM4100 readers are somewhat popular because they are cheap, widely available and easy to use. You can pick up an EM4100 RFID reader for ~$40 or less. The module used in this example may not work for every EM Reader out there - though it offers an approach to start with. If you do create a new module for a different device, then please share it here at digital-diy.com

It's a type of RFID Card obviously! They operate on the Low Frequency (LF) band (125KHz). In that frequency band there are several kinds of tags that all communicate differently. The EM family of tags come from a single manufacturer; EM Microelectronic. The EM4100 is simply a type of tag from their line of tags that operates at 125KHz. There are other models such as EM4002, EM4102 and the newer EM4200.
There are some standards that several RFID chip makers adhere to, but many chip types (like the EM4100) do not conform to any standard, and several reader manufacturers develop hardware to support reading those types of chips.
A Card Reader does all of the hard work - it looks after energising the card, reads the transmitted RF signal, and if everything went well - it outputs the Card ID. There are two important points to consider when interfacing with a reader:
Discovering how to interface with it should be pretty easy - either via the readers datasheet or an ident plate on the back of it.
After finding out how to interface with it, figuring out the protocol can be interesting! If you have the datasheet, then it will be listed there. If not, make a simple echo program on your PIC, to pass anything onto a terminal program (such as the PK2 UART Tool or iHyperTerminal). This allows you to decode what is going on - it will only take 2-3 cards to discover how the card ID is encapsulated. All you need to find is:
I had to discover what was going on through analysing the raw output, as my datasheet did not describe how the data was encoded. This is not hard to do, consider the following raw hexadecimal outputs for 4 different cards:
$02,$30,$46,$30,$30,$35,$33,$38,$33,$30,$34,$0D,$0A,$03
$02,$31,$31,$30,$30,$34,$36,$35,$45,$45,$32,$0D,$0A,$03
$02,$31,$31,$30,$30,$32,$46,$42,$42,$34,$44,$0D,$0A,$03
$02,$30,$31,$30,$33,$45,$35,$43,$30,$38,$44,$0D,$0A,$03
As I am working with EM4100 cards, I am looking for a 5 byte address (that much I could get from the datasheet). The packet appears to be ASCII encoded, so my Card ID will actually be 10 bytes long.
There are 14 bytes sent with each packet, and it helps to either be familiar with ASCII codes or have an ASCII table handy. I can strip some of the information straight away as the packets have a common setup to what I am used to: ASCII Code (ASC) $02 = Start of Text, ASC $0D = Carriage Return, ASC $0A = Line Feed and ASC $03 = End of Text.
With the above bytes removed ($02, $0D, $0A, $03), I can identify the ASCII formatted 10 byte card ID (the only 10 bytes left!). This also implies there is no CRC being used.
$02,$30,$46,$30,$30,$35,$33,$38,$33,$30,$34,$0D,$0A,$03
$02,$31,$31,$30,$30,$34,$36,$35,$45,$45,$32,$0D,$0A,$03
$02,$31,$31,$30,$30,$32,$46,$42,$42,$34,$44,$0D,$0A,$03
$02,$30,$31,$30,$33,$45,$35,$43,$30,$38,$44,$0D,$0A,$03
A key point to remember here is that the whole packet is ASCII formatted.This means that each of the 10 bytes forms an ASCII code for what the Card ID actually is. For example:
$30,$46,$30,$30,$35,$33,$38,$33,$30,$34 = 0F00538304
$31,$31,$30,$30,$34,$36,$35,$45,$45,$32 = 1100465EE2
$31,$31,$30,$30,$32,$46,$42,$42,$34,$44 = 11002FBB4D
$30,$31,$30,$33,$45,$35,$43,$30,$38,$44 = 0103E5C08D
RFID_EM4100.bas allows both a start and an end symbol to be defined. This tells the program when to start clocking in the Card ID, and when to stop. In this case:
$02,$30,$46,$30,$30,$35,$33,$38,$33,$30,$34,$0D,$0A,$03
$02,$31,$31,$30,$30,$34,$36,$35,$45,$45,$32,$0D,$0A,$03
$02,$31,$31,$30,$30,$32,$46,$42,$42,$34,$44,$0D,$0A,$03
$02,$30,$31,$30,$33,$45,$35,$43,$30,$38,$44,$0D,$0A,$03
Now I have a Start Symbol, Card ID, and an End Symbol - and am ready to use the module, RFID_EM4100.bas
In the following program, I am calling a sub routine which is a blocking call (will not return until something is received). After that happens, the Card ID is displayed in both ASCII and Raw Hex on the PICKit 2 UART Terminal.
Device = 18F2520 Clock = 8 Config MCLRE = Off // all includes can be found @ digital-diy.com ("Swordfish - Module Pack") Include "InternalOscillator.bas" Include "RFID_EM4100.bas" Include "USART.bas" Include "Convert.bas" // display card number in decimal and hex Sub DisplayCardNumber() Dim i As Byte USART.Write("______________________________________",13,10) USART.Write("RFID CARD DETECTED!",13,10) USART.Write("ASCII : ", CardNumber,13,10) USART.Write("RAW HEX: ") For i = 0 To 9 USART.Write(HexToStr(CardNumber(i),2)," ") Next USART.Write(13,10) End Sub // main program loop While true RFID.WaitForCard() DisplayCardNumber() Wend
I am using the PICKit 2 UART Tool to view the program outputs. Here's an animation of several different cards being passed over the reader:

Although I could have made a very simple daughter board for the TAP-28, I was actually joining this project with a Bluetooth module (giving my computer RFID capability!). There were a few too many components, so I made my own development board.
My Card Reader has an RS232 interface (+/-12V) - Given I was using 3.3V with this design, a MAX3223 handled voltage level switching.
It may look like there's a lot going on - but consider its just the following: