Reading serial data from Sparkfuns magnetic card reader

Hi,

I`m about to develop a card reader system, thar sends the ID of a card to a web-server.

The web-server part is working properly, but I have a problem (I think it`s electrical problem) connecting the card reader to the Arduino.

  • First i tried just to connect the serial pins 2,3 and +5V and GND pins to the bord, and also sendt power to the card reader on the DTR pin. This work fine if i connect to a computer.

  • When connecting to an Arduino, the data i recieve on the serial port is garbage, but I sometimes can see part of the expected data comes through. I have configured the correct baud rate.

  • I noticed that when I`m turning on and of an nearby lamp, the Arduino recieves data !! :roll_eyes: :astonished: And the Serial.available is of course trigged.

  • The CardReader is connected to the Arduino throug a 232 shifter from Sparkfun.

Any suggestions on my wiring, or configuration??

Some questions:

Do you have a link to the datasheet of the reader? sparkfun?
Can you post your code so far?

Do you use Serial.Available() in your code (wild guess what could be the problem)

This is the Card Reader:

And it is connected through this:

And this is the test code running on my mega:

char inByte;

void setup(){
Serial.begin(9600);
Serial1.begin(9600);
}
void loop(){
if (Serial1.available()){
inByte = Serial1.read();
Serial.print(inByte, BYTE);
}
}

You will probably have to examine the data to see what you are receiving when you get valid data and invalid data and filter the data in software.

Change: Serial.print(inByte, BYTE) to:

Serial.print(inByte, HEX); Serial.print(' ');

That way you can see the hex character codes. Scan a few cards and look for a pattern in the values, for example they might always start and/or end with a low value like 1, A, or D. Let us know what you find.

Edit: One source says the data output format is:
%trackOne?;trackTwo?;trackThree?

The display they show, however, shows the format is more like:
%trackOne?;trackTwo?+trackThree?

So, to get the particular track you want select the data between '%' and '?', ';' and '?', or '+' and '?'.

This is the output when I use original code: (Serial.print(inByte, BYTE):wink:
mf¸ïïÿIæ¸ïïïÿmf¸ïïÿZþþÿüïïïÿ (Card swiped 4 times)

The output with changes suggested in replay: (Serial.print(inByte, HEX); Serial.print(' '):wink:

0 6D 66 FFFFFFFF 7F FFFFFFFC FFFFFFEF FFFFFFFF 0 (1. swipe)

0 6D 66 FFFFFFFF FFFFFFFC FFFFFFEF FFFFFFFF 0 (2. swipe)

0 6D 66 FFFFFFFF 7F FFFFFFFC FFFFFFEF FFFFFFFF 0 (3. swipe)

None of them makes sense. It should be many more characters in the card.
It sould look someshung like this: ;3110099999?%3110099999?&31099999?

Looks like available() is not working. A return of FF from Serial.read() is serial language for "no characters available".
Try this intead:

char inByte;

void setup(){
Serial.begin(9600);
Serial1.begin(9600);
}
void loop(){
  inByte = Serial1.read();
  if(inByte != 0xFF)
  Serial.print(inByte, HEX);
}

Edit: Oops. I like a hex display for this stuff, so I changed it.
What platform are you using to program you Arduino? Windows?
And the grounds are connected between the two devices, correct?

Aruduino now sends alot of FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF and dosnt stop.
Added a delay to see more, and this is happening when card is swiped:

FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04D66FFFFFFFEFFFFFFFFFFFFFFFCFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFFF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

Good idea on the delay. Now it will print 10 times a second, and each on its own line.
Mine did the same thing yours did. For some reason, it thinks char is a 32 bit data type. It was returning FFFFFFFF.

Try this. I commented out the Serial1.available() calls to test it.

uint8_t inByte;

void setup(){
Serial.begin(9600);
Serial1.begin(9600);
}
void loop(){
//  if(Serial1.available())
//  {
    inByte = Serial1.read();
    if(inByte != 0xFF) Serial.println(inByte, HEX);
//  }
  delay(100);
}

Swipe the card and see what happens.

Tested this.. And here is the result.

0
6D
E6
FE
7F
B8
EF
EF
0

It is not enough data. And the data is corrupt. I dont think I have a software issue. It seems more like that I have troble with baud rate, or have connected the reader wrong.

Any other suggestions?

if(inByte != 0xFF) Serial.println(inByte, HEX);

is wrong, as the card could also send an 0xFF !! which you will miss.
The solution should be in the proper use of Available(),
furthermore recall that Serial.Read() returns an int not a byte ...

please try this variation

int inByte;   

void setup()
{
  Serial.begin(9600);
  Serial1.begin(9600);
}

void loop()
{
  if (Serial1.available() > 0 )
  {
    inByte = Serial1.read();
    Serial.println(inByte, HEX);
  }
  delay(100);
}

The sparkfun level shifter doesn't seem to support the DTR or RTS signals from which the reader is expecting to get its power supply. Could that be the problem?

I have connected pin 4 and 7 to 5V, so the cardreader has power and the led is green.

If removing the Serial1.available() call and filtering 0xFF characters did not correct the problem, then you cannot assume the Serial1.available() routine is malfunctioning. There may be characters in the receive buffer, and something in your code is interpreting them as 0xFF.

I would now check the baud rates carefully. Insure the Serial1.begin() matches the magnetic reader baud, and Serial.begin() matches the baud rate in the lower right corner of the serial monitor window.

@robtillaart: Thanks for the info on the data size. I did not see the - int at the end of the returns section. If I would have looked at the example, I would have seen it is int. Now it makes sense. 0xFF is not really -1. It is 255. 0xFFFF is an int -1.

My new test code would be:

int inByte;
inByte = Serial1.read();
if(inByte != -1) Serial.write(inByte);

However, in this case I no longer believe it is Serial1.available() that is malfunctioning. It must be something in the serial port settings.

Lets start with the device:

If you connect the reader to a PC, does it capture meaningful data? => capture the stream with putty.exe or another terminal program

Yes, card reader works perfect directly connected to the computer.

I manage to get it work with a ICL232 circuit insterd of using the 232-shifter.

So this case is closed... Tanks for all help with code-examples.