Reader for magnetic stripes


This page describes a program for a PIC16C84 that reads information from a magnetic strip on a plastic card, and presents the information on a LCD-display. You need a reader that reads track 2 on the card. They are sometimes available on radio amateur fleamarkets.
Here you can get the code as a zipped archive. It comes with no guarantees at all, but if you find it useful, I would be glad if you told me.

(Updated code 18 Jul, 1998)

Introduction

Cards with magnetic strip has a coding based on ISO-7811. All standardization institutes always want to have money for it, but The Dread Pirate Robert has managed to collect various information on magnetic card information. (OOPPSS link apperently gone dead) A guy I've found on the Net has made the same thing as I, but for 68HC11.
There are three tracks encoded on the magnetic stripe.Track 2 is the track read by most entrance system available, and consist of numerical information. The numerical information is often the number printed on the card, consisting of 16 numbers. At least on pay cards as Visa.

Output from the reader

Reader is what I call the unit into which you insert your card. From that unit you get a clock signal and a data signal. Sometimes you get a signal if there's a card in the reader or not. Please note that in my reader this signals was open collector outputs, so I had to connect pullup resistances to +5V. The reader also needs power supply, +5V and GND.

The code on the card is self clocked, so you get a clockpulse for each bit that comes out. I used the clockpulse to generate interrupts for the processor.

Coding of information on the card

The information on the card is formatted as:
...0000<Start sentinel><N Characters><End sentinel> <LRC>000...
where the zeros are bits set to zero and LRC means Longitudinal Redundancy Check (more about that later).

The characters is nibbles with one parity bit encoded, in total five bits per character. Parity is such that total number of bits in a character, including parity, is odd. Note that characters are coded with LSB first, and parity last.

LRC is calculated using the following procedure (from the standard):
The value of each bit in the LRC character, excluding the parity bit, is defined such that the total count of one bits encoded in the corresponding bit location of all characters of the data message, including the start sentinel, data, end sentinel, and LRC character, shall be even.

The parity bit is the parity bit for the LRC character.

Implementation

The card reading routine is based on a huge state machine with approxamitly 20 states, implemented with computed goto's. By "reusing" many states, the code is still quite small. About 350 words, with display handling and everything.
First step is to find the start sentinel. It's done by looping each bit that comes (at each interrupt) and compare if all bits so far resembles to a start sentinel. When start sentinel is found the state machine goes on finding the message. The code handles at this time a maximum of 16 characters. Visa cards and so on uses 16 characters, thats why the limit is set to 16. Just by increasing the buffer you should be able to read more than 16 characters. By the way, display routines must be changed to. It calculates the parity, and LRC.

Thanks to

The LCD display routines is thanks to Jacob Rengman, and are little tuned by me. I also owe him a great thanks for helping me out when this project went into problem. As support he has made a PC-program in Pascal that reads the card reader via the gameport, and presents it as ones and zeroes on the screen.
[Back to my project page]
[Copyright © 1996, 1997, 1998 Stefan Petersen, spe@stacken.kth.se ]