Magstrip Track Reader

Hello Everyone,

Read Track 1 & Track 2 cards on MAgStripe (Refer Magstrip.png) simultaneously on Arduino Mega 2560.

I found a library where a person had already programmed this sort of project on Arduino, but only for Single Track Reading - Google Code Archive - Long-term storage for Google Code Project Hosting. , So i wanted to take it further by reading TRACK 1 and TRACK2 ...

I altered the library to read an additional track with 2 more interrupts

/---- Library Code------/
Please attached file - Magstripe_final.cpp

/----Library Header----/

#ifndef MAGSTRIPE_H
#define MAGSTRIPE_H


#if ARDUINO < 100
#  include <WProgram.h>
#else
#  include <Arduino.h>
#endif 
//#include "../PinChangeInt/PinChangeInt.h"


// The data and clock pins depend on the board model...
#if defined(__AVR_ATmega32U4__)
   // Arduino Leonardo and Arduino Micro:
#  define MAGSTRIPE_RDT 3  /* data pin (blue) */
#  define MAGSTRIPE_RCL 2  /* clock pin (green) */
#else
   // Arduino Uno and Arduino Mega:
#  define MAGSTRIPE_RDT1 2  /* data pin (White) */
#  define MAGSTRIPE_RCL1 3  /* clock pin (Yellow) */
#  define MAGSTRIPE_RDT2 21  /* data pin (Orange) */
#  define MAGSTRIPE_RCL2 20  /* clock pin (Brown) */
#endif

#define MAGSTRIPE_CLS 4  /* card present pin (Green) */


// Cards can be read in one of these possible ways...
enum ReadDirection { READ_UNKNOWN, READ_FORWARD, READ_BACKWARD };


class MagStripe {
    public:
        // The CLS pin can be changed from the default...
        MagStripe(unsigned char cls=MAGSTRIPE_CLS);

        // Initialize the library (attach interrupts)...
        void begin1(unsigned char track1);
        void begin2(unsigned char track2);
        // Deinitialize the library (detach interrupts)...
        void stop();

        // Check if there is a card present for reading...
        bool available();

        // Read the data from the card as ASCII...
        short read1(char *data, unsigned char size);
        short read2(char *data, unsigned char size);
        // The direction of the last card read...
        enum ReadDirection read_direction();

    private:
        unsigned char pin_cls;
        unsigned char track1;
        unsigned char track2;
        enum ReadDirection direction;

        void reverse_bits1();
        void reverse_bits2();
        bool verify_parity(unsigned char c);
        bool verify_lrc1(short start, short length);
        bool verify_lrc2(short start, short length);
        short find_sentinel1(unsigned char pattern);
        short find_sentinel2(unsigned char pattern);
        short decode_bits1(char *data, unsigned char size);
        short decode_bits2(char *data, unsigned char size);


};


#endif  /* MAGSTRIPE_H */

/------ INO TRACK READER-----/

#include <MagStripe_final.h>


// Visual feedback when the card is being read...
static const byte READ_LED = 13;
static const byte ERROR_LED = 12;

MagStripe card;

static const byte DATA_BUFFER_LEN = 108;
 char data1[DATA_BUFFER_LEN];
 char data2[DATA_BUFFER_LEN];

void setup()
{
  pinMode(READ_LED, OUTPUT);
  pinMode(ERROR_LED, OUTPUT);
  
  // The card data will be sent over serial...
  Serial.begin(9600);
  
  // Initialize the library for reading track 2...
  card.begin1(1);
  card.begin2(2);

  // Start with the feedback LEDs off...
  digitalWrite(READ_LED, LOW);
  digitalWrite(ERROR_LED, LOW);
}

 
void loop()
{
  // Don't do anything if there isn't a card present...
  if (!card.available()) {
    return;
  }
  
  // Show that a card is being read...
//  digitalWrite(READ_LED, HIGH);
  {
    char data1[DATA_BUFFER_LEN];
 char data2[DATA_BUFFER_LEN]; short aux=0;
 
 
   while(aux < DATA_BUFFER_LEN)
   {
     data1[aux]=data2[aux]=0x00;
     aux++;
   }
  // Read the card into the buffer "data" (as a null-terminated string)...
  short chars1 = card.read1(data1, DATA_BUFFER_LEN);
   short chars2 = card.read2(data2, DATA_BUFFER_LEN);
  // Show that the card has finished reading...
 // digitalWrite(READ_LED, LOW);
  


  // Send the data to the computer...
  Serial.println(data1);
  Serial.println(chars1, DEC);
  Serial.println();
  Serial.println(data2);
    Serial.println(chars2, DEC);
  }
}

**Current Problems **
1. There is only one PIN present which can say CARD PRESENT (5 - gREEN), But cannot identify which Card was it? TRack 1 Or Track 2? If I use card.available() it will read the same value as it belongs to same pin....
2. When only Reading Track 1 Or Track 2 cards (Individually) on Pin 2 (data) & Pin 3 (clock) Or Pin 21 & Pin 20 (As interrupts are attached on these pins as per -- attachInterrupt() - Arduino Reference ) works fine...
But when if all the pins are connected
White - Pin 2 - DAta - Track 1
Yellow - pin 3 - Clock - Track 1
Orange - Pin 21 - Data - Track 2
Brown - Pin 20 - Clock - Track 2
Green - Pin 4 - CARD PRESENT
Ground + 5V
The Following Test case was tested, but results where not in the right way

--- Swipe a Track 1 card --- Displays data (chars1 = 60) , while displays chars2= -1 for Track2 card
--- Swipe a Track 2 card --- Displays NULL data with -1 (chars 1 and chars 2)
--- Swipe a DUAL Track card -- Displays data in Track 1 (chars = 78) , while displays chars2 = -1 for track2 data --- The card contains both the track data

Or I have set the interrupt in a wrong way for TRAck 2 or TRack 1?

Basic Problem is the interrupt routine or something not sending the right stuff...

MagStripe_final.cpp (11.7 KB)

1 Like