Swipe Cards are used nowadays at many locations that include Point of Sale Terminals, Access Control, ATM Machines, Motorway Toll, Airline Tickets Verification, Vending Machines, etc. They connect to the host Microprocessor through Direct I/O interface, RS-232 serial ports or USB. Swipe Cards used in Financial Transaction have a defined size, Track Encoding and card Data Format. Debit Card and Credit Card are example of Financial Transaction Card. As the Financial Transaction Cards and information related to them are available easily, they are used in this project. Details of FTC are provided as under. Card Dimensions, Encoding and Data Format for credit cards as per ISO7813
Swipe Card Reader Connector Magtek is world renowned swipe card manufacturer. Card reader used in this project is Magtek Part number 2105004 which is 101mm compatible, Dual Track (Track 1 & 2) Swipe card reader with cover. The Card has TTL compatible direct I/O interface, as detailed below:
Signal Timing The timing of signal on CARD PRESENT, STROBE and DATA is as under
Connecting Card Reader to the AVR Project Board Below is the schematic of the wiring of the card to the AVR project board to capture the track 1 of the card.
The wiring is depicted in the following picture.
J1 in the schematic is the swipe card 8 pin connector. Note: Remove the MAX 232 from the project board, or use any other port pin for DATA signal as the PD0 and PD1 are directly connected to the MAX 232. TRACK 1 DATA FORMAT The following is typical for Track 1 data. The Track 1 data format includes the following items: 1. Approximately 62 leading clocking zeros 2. The Start Sentinel "%" 3. Up to 76 alphanumeric characters selected by the user 4. The end sentinel "?" 5. The LRC (longitudinal redundancy check character) 6. Trailing clocking zeros (minimum of 62) to the end of the card Each data character is in a 7-bit (6 plus parity) alphanumeric format. The data is in the format "parity, 32, 16, 8, 4, 2, 1". Parity is odd (an odd number of "one's" in each character). The character is written "backwards" on the card starting with the least significant digit and ending with the parity bit. The card data format is "1, 2, 4, 8, 16, 32, parity". Decoding Reader Output The usual way to gather card data from a TTL (Transistor-Transistor Logic) swipe magnetic card reader as described in the Magtek Application Note is as follows: 1. Connect the strobe line to an interrupt port on the CPU that is programmed to interrupt on the falling edge of the strobe. 2. Connect the data line to an ordinary CPU port pin. 3. Connect the card present line to another ordinary CPU port pin. All three of the above signals are quiescently high (VCC). When a card is swiped, the first signal to go low (active) is Card Present. It will go low after 14 to 15 head flux reversals have been read. These initial strobes are not output on the strobe line. After Card Present goes low, the strobes are output on the strobe line. Storing data should not begun until the data line goes low (indicating a one) and the strobe line falls. When this occurs, the CPU starts to store the data in RAM (Random Access Memory) until the strobes stop because the card has cleared the head. Approximately 150ms later, Card Present returns to VCC. When this occurs, the CPU analyzes the data in RAM and converts it to the ASCII. Software for Decoding Track 1 The Software that does this is listed below. Note that the code listed here has some limitation as below
SwipeCard.h #define TK1_int SIG_INTERRUPT0#define CARD_PRESENT ((PIND & 0x80)==0) #define CARD_NOTPRESENT ((PIND & 0x80)==0x80) #define TRACK1_DATA ((~PIND) & 1) SwipeCard.c #include <avr/io.h>#include<avr/interrupt.h> #include "SwipeCard.h" #define BitVal(x) (1 << (x)) unsigned char DataBits[100]; unsigned char Scratch, ptrS, ptrD; unsigned char Leadingzero=1; void ConvertASCII(void ); void main(void ) { MCUCR |= BitVal(ISC01) | BitVal(ISC00); GICR = BitVal(INT0); ptrS = ptrD = 0; sei(); while(1){ while(CARD_NOTPRESENT){ } Leadingzero = 1; while(CARD_PRESENT){ } ConvertASCII(); } } SIGNAL(TK1_int) { if(Leadingzero){ if(TRACK1_DATA == 1) { Leadingzero=0; Scratch = 0x40; ptrS = 1; ptrD = 0; } } else { Scratch = Scratch >> 1 | ((TRACK1_DATA)?0x40:0); ptrS++; if (ptrS == 7){ ptrS = 0; DataBits[ptrD] = Scratch; Scratch = 0; ptrD++; } } } void ConvertASCII(void ){ unsigned char i; for(i=0; i< ptrD; i++){ DataBits[i] = (DataBits[i] & 0x3F) + 0x20; } } Last Updated: Dec-2008 |







