How to Interfacer RFID reader that outputs in HEX

Hi Guys just got this RFID serial reader from a local dealer:

After connecting it, using a serial terminal, I learnt it outputs its data in HEX (in ascii I got scrambled code), below theres a example scanning two different tags.

My question is now: How do I interface it with arduino, I had an id-12, and the serial output was already ascii, and the exampled here worked perfectly.

Thanks in advance.

Hi,

HEX is just the way the serial terminal is displaying the output as a human-readable value. It could have shown you a stream of 1's and 0's but that would have even been harder to read for us. To the Arduino this is all the same but it's up to us to define whether the information is treated as numbers, characters, bytes, hex or bitmaps etc.

Do you know what values you were expecting to see with the tags you have?
Geoff

You must connect the 5V of the Arduino to the Vcc(+) pin of the reader, the GND of the Arduino to the GND(-) of the reader and the TX of the reader to the Rx of the Arduino (pin number 0). After that you must write the code for your Arduino.

strykeroz:
Hi,

HEX is just the way the serial terminal is displaying the output as a human-readable value. It could have shown you a stream of 1's and 0's but that would have even been harder to read for us. To the Arduino this is all the same but it's up to us to define whether the information is treated as numbers, characters, bytes, hex or bitmaps etc.

Do you know what values you were expecting to see with the tags you have?
Geoff

Geoff:

Sorry for the late reply, yes I do know the values I am expecting. I also experimented using another RFID reader. This was anise thing to have since the antenna was printed on the PCB. Unfortunatelly I can't make it work.

I used this code:

/*------------------------------------------------------------------
This is a sample code for RDM630 RFID reader by Spekel(Spekel.se)
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
http://creativecommons.org/licenses/by-nc-sa/3.0/
-------------------------------------------------------------------*/
#include <SoftwareSerial.h>
#define rxPin 0
#define txPin 1
char code[20];
int val = 0;
int bytesread = 0;
//------------------------------------
//create a Serial object RFID
SoftwareSerial RFID= SoftwareSerial(rxPin, txPin);

void setup()
{
  Serial.begin(9600);
  Serial.println("Serial Ready");
  RFID.begin(9600);
  Serial.println("RFID Ready");
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
}
void loop()
{
  val = 0;
  bytesread = 0;

  while(bytesread < 12)
  {
    // read 12 digit code
    val = RFID.read();
    if(val == 3)
    { // if header or stop bytes before the 10 digit reading
      break; // stop reading
    }

    if(val != 2)
    {
      code[bytesread] = val; // add the digit
      bytesread++; // ready to read next digit
      code[bytesread] = '\0'; // add the NULL
    }
  }

  if(bytesread >= 12)
  { // if 12 digit read is complete
    Serial.print("Tag: [");
     delay(3000);
    for(int i=0; code[i]!='\0' ; i++)
    {
      Serial.print(code[i]);
    }
    Serial.println("]"); //print the whole 13 bytes
  }
  
  delay(3000);
}

I am a bit lost since I am not getting the output from the RFID as expected... I can see the reader module blinks whenever a tag is closer, and connecting it directly to the serial adapter is working.

Any idea?

I am a bit lost since I am not getting the output from the RFID as expected

So what did you get a d what were you expecting?

Do you know if the baud rate is right and is the signal the right way up?

Grumpy_Mike:

I am a bit lost since I am not getting the output from the RFID as expected

So what did you get a d what were you expecting?

Do you know if the baud rate is right and is the signal the right way up?

The baud is correct. I have this tag stored, so I know the number I should be getting, instead (and according to the code I used) i am currently getting this:

Tag: [ÿÿÿÿÿÿÿÿÿÿÿÿ]

aleza:
Tag: [ÿÿÿÿÿÿÿÿÿÿÿÿ]

So your answer is right there.

Your code is receiving the value (in val) of -1 each time it does thisval = RFID.read();and finds nothing to read. That -1 as an integer is then stored as a char here code[bytesread] = val; // add the digitEach time a -1 is read (ie there's nothing to read) it stores that accented y character. Check SoftwareSerial Read() for confirmation of the -1 returned when it finds nothing in the buffer.

To confirm this further, if you run this test code

char codeval;
int val = -1;

void setup() {
  Serial.begin(9600);
  Serial.println("Ready");
  Serial.println("val\tchar");
  Serial.print(val);
  Serial.print('\t');
  codeval = val;
  Serial.println(codeval);
}

void loop() {
}

You'll get this result

Ready
val	char
-1	ÿ

So you need to test that there is something there to read before just storing what you receive. You can do that either by testing val for -1 or by only doing the read of RFID after you find RFID..available() > 0 . ie, that there is something in the buffer to be stored at all.

Check SoftwareSerial Available() for more info on that.

Cheers !
Geoff

While it could be reading an empty serial port, it could also be that the signal is upside down.

Disconnect the reader from the arduino but still keep it powered up. Measure the output of the reader with a multimeter. You should see 5V when there is no card present.

If you see 0V here then the signal needs inverting with a transistor.

If you see a minus voltage here then you have an RS232 output and that needs converting in hardware before you feed it into your Arduino.

I have this code from another project modify it to cover your needs

byte readCard[6]; // Sotres an ID read from the RFID reader
byte checksum = 0; // Stores the checksum to verify the ID 

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:
  byte val = 0; // Temp variable to hold the current byte
  if(Serial.available() > 0) // Waits for something to come on the serial line
  {
    if((val = Serial.read()) == 2) // First Byte should be 2, STX byte 
    { 
      getID();
    }
  }

}

// If the serial port is ready and we received the STX BYTE (2) then this function is called 
// to get the 4 BYTE ID + 1 BYTE checksum. The ID+checksum is stored in readCard[6]
// Bytes 0-4 are the 5 ID bytes, byte 5 is the checksum
void getID()
{
  byte bytesread = 0;
  byte i = 0;
  byte val = 0;
  byte tempbyte = 0;
  // 5 HEX Byte code is actually 10 ASCII Bytes. 
  while ( bytesread < 12 ) // Read 10 digit code + 2 digit checksum
  { 
    if( Serial.available() > 0) // Check to make sure data is coming on the serial line
    { 
      val = Serial.read(); // Store the current ASCII byte in val
      if((val == 0x0D)||(val == 0x0A)||(val == 0x03)||(val == 0x02)) 
      { // If header or stop bytes before the 10 digit reading
        break; // Stop reading 
      }
      if ( (val >= '0' ) && ( val <= '9' ) ) // Do Ascii/Hex conversion
      {
        val = val - '0';
      } 
      else if ( ( val >= 'A' ) && ( val <= 'F' ) ) 
      {
        val = 10 + val - 'A';
      }
      if ( bytesread & 1 == 1 ) // Every two ASCII charactors = 1 BYTE in HEX format
      {
        // Make some space for this hex-digit by
        // shifting the previous hex-digit with 4 bits to the left:
        readCard[bytesread >> 1] = (val | (tempbyte << 4));
        if ( bytesread >> 1 != 5 ) // If we're at the checksum byte,
        {
          checksum ^= readCard[bytesread >> 1]; // Calculate the checksum using XOR
        };
      } 
      else // If it is the first HEX charactor
      {
        tempbyte = val; // Store the HEX in a temp variable
      };
      bytesread++; // Increment the counter to keep track
    } 
  } 
  bytesread = 0;
}

Grumpy_Mike:
While it could be reading an empty serial port, it could also be that the signal is upside down.

Disconnect the reader from the arduino but still keep it powered up. Measure the output of the reader with a multimeter. You should see 5V when there is no card present.

If you see 0V here then the signal needs inverting with a transistor.

If you see a minus voltage here then you have an RS232 output and that needs converting in hardware before you feed it into your Arduino.

Hey thanks for the reply, I tested it and without a card I get a 5v reading.

I tested it and without a card I get a 5v reading.

OK that means your software is reading a serial buffer that is empty.

strykeroz:

aleza:
Tag: [ÿÿÿÿÿÿÿÿÿÿÿÿ]

So your answer is right there.

Your code is receiving the value (in val) of -1 each time it does thisval = RFID.read();and finds nothing to read. That -1 as an integer is then stored as a char here code[bytesread] = val; // add the digitEach time a -1 is read (ie there's nothing to read) it stores that accented y character. Check SoftwareSerial Read() for confirmation of the -1 returned when it finds nothing in the buffer.

To confirm this further, if you run this test code

char codeval;

int val = -1;

void setup() {
 Serial.begin(9600);
 Serial.println("Ready");
 Serial.println("val\tchar");
 Serial.print(val);
 Serial.print('\t');
 codeval = val;
 Serial.println(codeval);
}

void loop() {
}


You'll get this result


Ready
val char
-1 ÿ


So you need to test that there is something there to read before just storing what you receive. You can do that either by testing val for -1 or by only doing the read of RFID after you find RFID..available() > 0 . ie, that there is something in the buffer to be stored at all.

Check [SoftwareSerial Available()](http://arduino.cc/en/Reference/SoftwareSerialAvailable) for more info on that.

Cheers !
Geoff

Thanks, thats correct I am not getting nothing read.

I tried this, a simple "software serial example" modified for this:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

void setup()  
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.println("Goodnight moon!");

  // set the data rate for the SoftwareSerial port
  mySerial.begin(4800);

}

void loop() // run over and over
{
  if (mySerial.available())
    Serial.write(mySerial.read());

}

this is the output I got:

Goodnight moon!
øøúùøøøúùøøøúùøøøúùøøøúùøøøúùøøøúùøøøúùøøøúùøøøúùøøøúùøøøúùøøøúùøøøúùø

I think it has to do with the encoding... this is the data sheet for the reader: http://rsmart.com.cn/datasheet/chip_cl/EM4100_DS.pdf

Cant figure out how to decode it =(, this is completely different from ID12 or RDM 630 readers.

Thanks

Try using

    Serial.write(mySerial.read() , HEX);

So you can see the individual bytes.

Grumpy_Mike:
Try using

    Serial.write(mySerial.read() , HEX);

So you can see the individual bytes.

Mike:

thanks for the hand, this was a breakthrough I am getting something. Recapping as to understand, what just happened. Data was coming in Hex, and we convert it?

This is the current output: F8F8FAF9F8 I can't figure whats this, (in my first post I posted how it looked when using a direct terminal connection), but this doesn't look like it.

Does this change with diffrent tokens?

Grumpy_Mike:
Does this change with diffrent tokens?

Yes, this is another TAG FFFAF8F8FC

Ok then I don't see what your problem, what you are reading is the tag data.

yes, it changes>

This is another tag:

Read by an ID12: 28 01 62 F9 19 AB

Read by this Reader (using a ttl adapter and a terminal) : 28 00 b1 f9 19

The middle part is tricking me... AB must be the CRC.

Any idea....?

BTW> sorry for long reply times. Work has become a time consuming activity.

AB must be the CRC.

Yes I agree.

The middle part is tricking me

They are practically identical:-

00B1 in binary is 0000 0000 1011 0001
0162 in binary is 0000 0001 0110 0010

So there is just a shift of one place to the left between these two numbers.
Some times different readers do things to the code from the tokens so to discourage people from using different makers readers in the same system.
I would say the true raw number is more likely to be the one with the check sum.