Magnetic strip card reader project

Hello friends
I am a novice student.
I want to convert the following C language code to Arduino but I do not know how this is possible
Please help me

https://www.maximintegrated.com/content/dam/files/design/tools/tech-docs/4095/an4095_sw.zip

Could You unzip that code and post it here, in code tags?
I could think about compiling that C code directly and see how it works.

#include <stdio.h>
#include <reg5240.h>

// 0123456789012345678901234567890123456789012345678901234567890 123
char char7bit[64] = " !'#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_";

// 0123456789012345
char char5bit[16] = "0123456789:;<=>?";

// Initialize serial port 0 to 9600 baud using 22.1184 MHz crystal

void serialInit()
{
PCON |= 0x80;
SCON0 = 0x50;
TMOD |= 0x21;
TH1 = 0xDC;
CKCON |= 0x10;
TCON = 0x50;
SCON0 |= 0x02;
}

// Generate a long delay for card reset and read intervals.

void longDelay()
{
int i, j;

for (i = 1; i < 5; i++) {
for (j = 1; j < 5000; j++) {
;
}
}
}

// Generate a shorter delay (used between STROBE/DATA transitions)

void delay()
{
int i;

for (i = 1; i < 1000; i++) {
;
}
}

// Release the DATA line (P0.0) and allow it to float high.

void dataHigh()
{
P0 |= 0x01;
delay();
}

// Drive the DATA line (P0.0) low.

void dataLow()
{
P0 &= 0xFE;
delay();
}

// Release the STROBE line (P0.1) and allow it to float high.

void strobeHigh()
{
P0 |= 0x02;
delay();
}

// Drive the STROBE line (P0.1) low.

void strobeLow()
{
P0 &= 0xFD;
delay();
}

// Reset the card reader IC and cause it to clear its track A/B/C memory.

void resetCardReader()
{
dataHigh();
strobeHigh();
longDelay();

dataLow(); // Force DATA low
longDelay();
strobeLow(); // Drive STROBE low, then high again
strobeHigh();
strobeLow(); // Drive STROBE low, then release DATA
dataHigh();
longDelay();

strobeHigh(); // Drive STROBE low and high again two more times
strobeLow(); // to complete the reset and leave the card reader
strobeHigh(); // IC in the 'ready' state, prepared to scan a magstripe.
strobeLow();
}

// Wait for the DATA line to be driven low by the card reader.

void waitForDataLow()
{
int i = 0xFF;

dataHigh(); // Make sure that DATA is floating high

while ((i & 1) == 1) {
i = P0;
}
}

// Clock a single bit value out of the card reader by driving STROBE high,
// then low, and reading the DATA line.

int readBit()
{
int i;

strobeHigh(); // Drive STROBE high
strobeLow(); // Drive STROBE low (DATA line now contains bit)

i = P0;
if ((i & 1) == 0) {
return 1; // Low on DATA line indicates '1' bit
} else {
return 0; // High on DATA line indicates '0' bit
}
}

// Clock out and decode a 7-bit character from the track memory, returning the
// character value. 7-bit (alphanumeric) characters are found on track A only.

char read7BitChar()
{
int i, c;

// Each character is composed of 7 bits, which we clock out of the track memory
// beginning with the least significant bit. The 7th bit is parity, which is ignored.

c = 0;
for (i = 1; i < 128; i *= 2) {
c |= (readBit() * i);
}
c &= 0x3F;

return char7bit[c]; // Decode and return the character using the 7-bit table
}

// Clock out and decode a 5-bit character from the track memory, returning the
// character value. 5-bit (numeric+symbol) characters are found on tracks B and C.

char read5BitChar()
{
int i, c;

// Each character is composed of 5 bits, which we clock out of the track memory
// beginning with the least significant bit. The 5th bit is parity, which is ignored.

c = 0;
for (i = 1; i < 32; i *= 2) {
c |= (readBit() * i);
}
c &= 0x0F;

return char5bit[c]; // Decode and return the character using the 5-bit table
}

void main()
{
int i;

serialInit();
printf("DS5250 Magstripe Card Reader Demo\r\n");

P0 = 0xFF;

while (1)
{
resetCardReader();
printf("\r\n");
printf("Waiting for card swipe...\r\n");
printf("\r\n");

  waitForDataLow();      // DATA low indicates card swipe has begun
  strobeHigh();
  longDelay();
  strobeLow();
  longDelay();
  waitForDataLow();      // DATA low indicates card swipe has completed

  // Discard preamble - 16 bit identifier code for card reader IC

  for (i = 0; i < 16; i++) {
     readBit();
  }

  // Track A - 76 characters, 7 bits per alphanumberic character including parity

  printf("Track A > ");   
     
  for (i = 0; i < 76; i++) {
     putchar(read7BitChar());
  }
  printf("\r\n\r\n");

  // At this point, we've read 532 bits of the 704-bit Track A memory on the card reader IC.
  // Flush the remaining 172 bits.

  for (i = 0; i < 172; i++) {
     readBit();
  }

  // Track B - 40 characters, 5 bits per numeric/symbol character including parity

  printf("Track B > ");   
     
  for (i = 0; i < 40; i++) {
     putchar(read5BitChar());
  }
  printf("\r\n\r\n");

/*
// In order to read Track C (which is rarely used on cards), we simply need to flush another
// (704-(40*5)) = 504 bits from the track memory as above, and then read another 107 characters
// from Track C as follows:

  for (i = 0; i < 504; i++) {
     readBit();
  }

  // Track C - 107 characters, 5 bits per numeric/symbol character including parity

  printf("Track C > ");   
     
  for (i = 0; i < 107; i++) {
     putchar(read5BitChar());
  }
  printf("\r\n\r\n");

*/

}
}

Okey.

This code:

void serialInit() { PCON |= 0x80; SCON0 = 0x50; TMOD |= 0x21; TH1 = 0xDC; CKCON |= 0x10; TCON = 0x50; SCON0 |= 0x02; }

looks like:

Serial.begin(9600)

Read the forum guidelines to see how to properly post code.

Use the IDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in code tags.

Thanks, but this is not all projects
I want to read magnet card information with Arduino
But I did not find any site that used a magnet head reader like my head reading
My head looks like the one below and I do not know how to connect it to the Arduino

image

Can you post a link to the data sheet for your reader?

:pray: :pray: :pray: :pray:

You want to read magnetic cards. What information do You want to use, how, for what, will You use it?

I need it for my university project
I only need to read the three-track information

Read the data sheets to learn details. As I could se that reader can be powered with 5 volt. Then a common 5 volt controller like an Arduino UNO can be used.
It's not my home territory but I think that SPI communication will read the card reader. Other helpers have more knowledge than I about SPI.

1 Like

It seems that the information that you will need in order to read the output from the reader is contained in one or more of these documents (from the data sheet linked in reply #8).

SHIFT-OUT TIMING
Refer to MagTek specification 99875337 (99875336 or 99875259 for 5V units) for details of the Shift-
Out Timing.

The shiftIn() function may be of interest for reading the data.

tnx for reply :pray: :pray: :pray: :pray:

hello
I want to read three magnetic card information track...
My reader head is similar to the picture below
image

I did not find any project on the internet that used a head like mine
Please guide me. I am a student and I do not have enough information. What should I do to start this project?

datasheet

Same question posted here >>> Magnetic strip card reader project - #6 by avsahcsdf

Posting the same question in more than one place is "cross posting". Cross posting is against the rules. Cross posting wastes time.

You should flag this post and ask a moderator to merge it with the other post in Project Guidance.

Except for cross posting, also note that Installation and Troubleshooting is not for problems with (or advise on) your project. Your topic has been moved to a more suitable location on the forum.

The information you require is in the reference documents listed in the PDF you linked to. You will not find that information on an Arduino forum.
Paul

@avsahcsdf

TOPIC MERGED.

Could you take a few moments to Learn How To Use The Forum.

Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum.

This seems to be the document that shows the bit timing:

STROBE is a digital input to the ASIC and should be normally held high. When the DATA line goes low at the end of a card swipe, STROBE should be pulsed low twice to complete the required “handshake” and shift out stored data in the ASIC buffer to the DATA output.

Each track is 608 bits, starting with the first 1-bit scanned. As you continue to strobe, the head sends Track A, Track B, and Track C bits in the order the bits were read. Then Track C, Track B, and Track A bits, each in reverse bit order. The pattern then repeats until you reset the head (power off?)

Sounds easy enough. 76 bytes per track. 3 or 6 tracks, depending on if you want to store the reversed versions or not.

const byte StrobePin = 2;
const byte DataPin = 3;
const byte PowerPin = 4;

byte ForwardABuffer[76];
byte ForwardBBuffer[76];
byte ForwardCBuffer[76];
byte BackwardABuffer[76];
byte BackwardBBuffer[76];
byte BackwardCBuffer[76];

byte ReadByte()
{
  byte b = 0;
  for (int i = 0; i < 8; i++)
  {
    digitalWrite(StrobePin, LOW);
    b <<= 1;
    b |= !digitalRead(DataPin); // LOW = 1 and HIGH == 0
    digitalWrite(StrobePin, HIGH);
  }
  return b;
}

void ReadTrack(byte buffer[76])
{
  for (int i = 0; i < 76; i++)
    buffer[i] = ReadByte();
}

void ResetHead()
{
  // Power down the head
  digitalWrite(PowerPin, LOW);

  delay(10);

  // Power up the head
  digitalWrite(PowerPin, HIGH);

  delay(10);
}

void setup()
{
  pinMode(DataPin, INPUT);

  digitalWrite(StrobePin, HIGH);
  pinMode(StrobePin, OUTPUT);

  // Power up the head
  pinMode(PowerPin, OUTPUT);
  digitalWrite(PowerPin, HIGH);
}

void loop()
{
  if (digitalRead(DataPin) == LOW)
  {
    // Falling Edge means data is ready

    // Strobe twice to get to the data
    digitalWrite(StrobePin, LOW);
    digitalWrite(StrobePin, HIGH);
    digitalWrite(StrobePin, LOW);
    digitalWrite(StrobePin, HIGH);

    ReadTrack(ForwardABuffer);
    ReadTrack(ForwardBBuffer);
    ReadTrack(ForwardCBuffer);
    ReadTrack(BackwardCBuffer);
    ReadTrack(BackwardBBuffer);
    ReadTrack(BackwardABuffer);

    ResetHead();

    // Process the raw bits here
    
  }
}
1 Like

For hook-up, see the diagrams on Page 20.

1 Strobe <- Arduino digital I/O pin
2 Data -> Arduino digital I/O pin
3 Vdd <- Arduino digital I/O pin
4 Ground -> Arduino Ground
5 Shield -> Arduino Ground

1 Like