How to send String to RFID reader and wait for response

Hi All,

I am new to arduino programming. I have to read the response of active RFID ( Tagsense ZR-100) by sending the commands from arduino. The spec says if I send Command string 55020081 to the reader the response from reader should be AA06008101010304.

Description of Host to reader : http://cdn.shopify.com/s/files/1/0040/3302/files/ZR-x-Protocol-v3-8_-_Reader_Commands.pdf?1268171267

The reader is correctly detecting tag IDs but its not responding to the command sent. I think the reader is not getting correct commands from the arduino board to respond. I am struck with how to send the string 55020081 to the reader.

For correct operation suggested : 8 bits
• No parity
• 1 stop bit
• Baud rate – 57600 bps
• Flow Control - None

My code below :

char val = 0;

byte initPort = { 0x55, 0x02, 0x00 , 0x81 };

void setup()
{

Serial.begin(57600);
Serial1.begin(57600);
}

void loop()
{
//Serial1.write(initPort,sizeof(initPort));
Serial1.write(initPort,sizeof(initPort));
//Serial.print(" I am here ");
Serial.flush();

if ( Serial1.available() > 0){
//Serial.print("I am here");
val = Serial1.read();
//Serial1.print(i);
Serial.print(val);

}

}

Please read how to use this forum, section 7.

After you write the config byte you expect an immediate response, but serial communication is slower than your processor and Serial1.available() > 0 will not be true, at least for a while. Besides, your Serial1.write() may be discarded because it doesn’t conform to the message format, not sending a at the end of the byte array. Finally, it is obvious that you cannot get the expected response AA06008101010304 by reading a single byte.

Thank you..

But if I put " Serial1.write(initPort,sizeof(initPort)); " in void setup() and try to read the serial1 port then also I am unable to get the response I am expecting from the
RFID reader back.

What ever I put on the serial port 1 : Serial1.write(initPort,sizeof(initPort));, the same thing I am getting when I try to read the serial port in loop function.

I didn’t mean you should send the initPort array in setup(), that depends on the logic of your program. But consider that initPort is a misnomer: you are not initializing the port, you are sending a message which corresponds to “Read queue entries command”. And you should know how to interpret the response.

In order to initialize the port you would call Serial1.begin() passing a configuration byte, such as SERIAL_8N1, but this happens to be the default so you don’t really need it. See http://arduino.cc/en/Serial/Begin.

Back to the messaging issue, a quick and dirty solution, actually more a debug step than a solution, is to add a delay() between Serial1.write() and Serial1.available(). Two seconds (2000 msecs) should be enough for the reply to arrive. If it doesn’t, I would blame the missing in the message.

Assuming that you get a reply, whatever, a better implementation of the send-receive protocol is based on the definition of states, avoiding delay(), within loop(). At the moment you have only two states: doing nothing, waiting for response. The actions and state transitions are: when doing nothing you can send messages to the device, as soon as the message is sent enter the waiting for response state; when waiting for response you check available() and read the response, do something with it and return to the doing nothing state.

I changed the code as below adding = ’ \r ’ in the sending message and adding delay between sending the message and waiting for response. Still I am not able to get the serial data back from RFID reader.

Pls find the code I uploaded to arduino Mega 3.3 V :

char val = 0;

byte initPort = { 0x55, 0x02, 0x00 , 0x09 , ‘\r’ };

void setup()
{

Serial.begin(57600);
Serial1.begin(57600);

}

void loop()
{

Serial1.write(initPort,sizeof(initPort));
delay(2000);

if ( Serial1.available() > 0){
//Serial.print(“I am here”);
val = Serial1.read();
//Serial1.print(i);
Serial.print(val,BIN);
//Serial.print(“I am here”);

}

}

It just occurred to me that since you are on a Mega your Serial1 is provided by the standard Serial library. Unfortunately the Serial library knows nothing about the protocol you are using, the need to put an "envelope" before each command (as explained in the document you linked), and the low level details of serial communication (which are implemented in a software driver, that's why you can access the device from a PC).
Sorry I should have thought of that before. But I'm afraid that unless you can find a specific library for the Arduino, your only option is to implement the protocol yourself, too much of a challenge I believe.
I can be wrong, of course.

Thank you SIr.

I believe the envelope information mentioned in the document is the information that needs to be sent to the reader ( asking reader to send back some information like version number etc) not addressed to the tag.

Can this problem be solved if I use some pins as softwareserial ports .?? And you have mentioned about specific library can you please elaborate more on this .??

There are RFID examples, and libraries, for the Arduino. See for example Arduino Playground - PRFID. As far as I can see, they all use the SoftwareSerial library, implementing some kind of protocol over it. Now SoftwareSerial is just a library that implements in software what a dedicated chip implements in hardware. It's interesting because it allows one to implement very many protocols over a serial line, increasing the number of devices that can communicate with the Arduino, but it's not a protocol development kit.

The protocol you need has two parts: one is message/response, you send a certain sequence (envelope+command) and expect some other sequence. This is relatively easy to implement (you may have to adapt to a reduced message set). But there's an underlying serial protocol (implemented by the PC driver) which cares for things like addressing and preventing collisions when two devices want to communicate at the same time. To me, this protocol looks hard to implement because it has to be very precise in the timing of signals.

A comparison with the I2C protocol in Arduino may be informative. It requires both hardware and software to operate, precise synchronization between devices, can only use certain ports. This is why I mentioned dedicated libraries: if someone has been able to develop an Arduino library for your device you can feel confident that it is going to work, but if nobody ever did you can't tell if it is due to lack of interest or to hardware limitations.

I googled unsuccessfully about that, just found this: https://sites.google.com/site/keywonthesis/RFID-Reader; I confess I didn't read it.

@sandeshgv
What part of:-

Please read how to use this forum, section 7.

Did you not understand.
Posting code how it is supposed to be is a common courtesy when asking for help.

Thank you Sir,

But the serial library standard used in arduino has by default same no of bits, parity and stop bits as given in the document attached. Also I am able to read the data transmitted by the reader.

If you can let me give some simple protocol implementation or any way I can take care in coding I will be happy to do that.

Hi, so maybe there’s nothing special in the protocol after all, so let’s start over:

My understanding is that using the Arduino you were able to send the string 55020081 to the reader, and read the response from the reader, something like AA06008101xxxxxx. Now, if this is the case, you are able to compose any command to the reader.

The reader commands are listed on pp 14-15. The format is described by table 2 on p 13.
You can send Query Reader Time, command 0x09. The command takes no arguments. The most complicated thing seems to decide what to put in the descriptor field, but since this is a reader function command it will be all zeroes. The packet will be made of descriptor field (1 byte) + command (1 byte), so the packet size will be 2:
0x55 – start byte
0x02 – packet size
0x00 – descriptor field
0x09 – command

Answer will be AA 07 00 09 01 xx xx xx xx (4 bytes for the time), but I’m just guessing.
Overall you have about twelve commands, most of which I’m afraid don’t make sense to me, but you can probably try and see. Some will require parameters and you’ll have to set the packet size accordingly, but the descriptor field should remain 0. You may define twelve or so different byte arrays so you can keep them as reference.

Then you will probably want to parse the answer so that you can tell whether it’s success or error. You should check the response code first, then any values returned. For any problem, don’t forget section 7.

Thanks again Sir,

Out of curiosity I modified my code to see how the command string is sent on a Serial port ( RX0, TX0) in other words monitor.

Pls find the code below.

char val = 0;

void setup()
{
  
Serial.begin(57600); 

}


void loop()
{   
     
      Serial.write((byte)0x55);
      Serial.write((byte)0x02);
      Serial.write((byte)0x00);
      Serial.write((byte)0x00);

 
}

I am getting the output as : U U U U ..............

I modified the code to

 Serial.write(initPort,sizeof(initPort));
 delay(5000);

even then the output is : U U U U ..

Nothing wrong: ascii 55 (hex) is the letter U, while 2 and 0 are nonprintable characters that may give a blank or some strange sign. Since you are writing them within loop() the sequence repeats forever. http://en.wikipedia.org/wiki/ASCII

Code uploaded :

void loop()
{   
     
  
Serial.write(initPort,sizeof(initPort));
delay(3000);
  
      if ( Serial1.available() > 0){
      //Serial.print("I am here");
      val = Serial1.read();
      //Serial1.print(i);
      Serial.print(val);
      //Serial.print("I am here"); 
      

      }
 
}

No change in the output : U U U

What I am guessing is what ever I send on serial1 will be in a buffer and the same buffer is read again in serial.read1 . So what ever I am sending the same thing I am receiving back.
Even if I switch off the RFID reader then also I keep getting : U U U ............

I feel I am seriously missing something here...

Hardware description :

As given in the docu : http://tagsense.com/images/stories/products/activereaders/ZR-100-long-range-Embedded-Reader-data-brief-v1.pdf

Tx TTL ( RFID reader ) -- RX1 ( Arduino)
Rx TTL ( RFID reader) --- TX1 ( Arduino)

I am supplying power to Arduino through USB
and RFID reader is powered using 5V connected to RS232 5V ( See docu )

The first write() you do

Serial.write(initPort,sizeof(initPort));

is directed to Serial. You aren't going to get a response on Serial1, so Serial1.available() will be 0 and the block where you read and print val will not be executed. You'll just get the endless U U U that you wrote in the first Serial.write().

Thanks and I changed to Serial1.write but the output : U U U

remains same

Back to your previous remarks:

sandeshgv:
What I am guessing is what ever I send on serial1 will be in a buffer and the same buffer is read again in serial.read1 . So what ever I am sending the same thing I am receiving back.

Hardware description :
As given in the docu : http://tagsense.com/images/stories/products/activereaders/ZR-100-long-range-Embedded-Reader-data-brief-v1.pdf

Tx TTL ( RFID reader ) -- RX1 ( Arduino)
Rx TTL ( RFID reader) --- TX1 ( Arduino)

I am supplying power to Arduino through USB
and RFID reader is powered using 5V connected to RS232 5V ( See docu )

The serial input and output buffers are separate, if you write() something in the buffer you are not going to read() from it. Unless the wires form a loopback, that sends back what you write. This happens if you connect TX and RX directly, or they get connected somewhere further in the circuit. I would double check the wiring, also using a multimeter, to exclude any closed circuit between RX and TX or TX1.

Then I cannot be sure about what I'm going to say now - I don't have a Mega and never had to look into its issues - but from what I read in the Serial documentation (here) in addition to TX1 and RX1 also the ground of the Mega must be connected to the ground of the device. I don't see a risk in doing so because the voltage is the same, but I don't want to give advice only based on what I read without having tried it, so please check yourself.