Channels ▼

JVM Languages

Java & RFID Tags

Source Code Accompanies This Article. Download It Now.

November, 2005: Java & RFID Tags

Shamshad develops RFID systems in Java for the supply chain and mining industries. He can be contacted at [email protected]

An RFID system consists of an antenna and transceiver, which read data transmitted by a transponder via radio frequency (RF). The combined transceiver and antenna are called the "RFID reader." The transponder, referred to as the "RFID tag," is an integrated circuit containing RF circuitry. It transmits data when it comes within the electric or magnetic field of the antenna. The antenna transmits data to a processing unit where it is manipulated according to whatever business needs. The reader is connected to the processing unit or a computer's communication port.

Commands are sent from the computer to the reader, which then activates the transponder. The transponder's response is read by the reader, which transmits the data to the PC's communication port.

In this article, I examine how you use the Java Communication API to send commands to and receive responses from the Texas Instruments S2000 Micro Reader (see Figure 1). The TI S2000 Micro Reader (see evalKits/RI-K2A-001A.shtml) is an intelligent module providing RF and control functions to read and program TI-RFID transponders. It is equipped with a Serial Communications Interface (SCI) that can be directly connected to a PC. The computer's communication port in this case is the RS-232 serial port.

Micro Reader Communication Protocol

At the outset of RFID development, it is important that you understand the communication protocol involved in sending signal commands from PCs to micro readers, and from micro readers back to computers. Figure 2 presents the byte sequence and its meaning for sending commands from PCs to micro readers.

The "Command Field" (see Table 1) defines the mode in which the micro reader operates and determines the operation that is to be carried out in the transponder. Depending on the setting of the relevant bits, the corresponding information specified in the Data Fields will be sent to the transponder (or not). Thus all functions of each particular transponder type can be executed. Tables 1(a), 1(b), and 1(c) describe the available settings for the PC-to-micro reader communication protocol.

If bit 5 (Power Burst II) is set for, say, programming and locking (see Figure 3), the micro reader automatically operates in single mode. Thus, users are enabled to validate the programming or lock response before a further cycle is started. If bit 2 (FBCC calculation) and bit 6 (Data) are set, the micro reader automatically calculates a 2-byte BCC over the data to be sent to the transponder and adds it to the protocol. When bits 2 and 6 are set, the PC must not send the 2-byte FBCC to the micro reader. Bit 4 (Power Pause Duration) is for future use and must not be set when addressing standard TI-RFID transponders.

If Command Field (2) is not present, standard TI-RFID write timings are used and wireless synchronization is switched on/off according to the status of input line WLSC. Also, the settings specified in Command Fields (1) and (2) are only valid during the execution of the current command (see Figures 3 and 4).

The BCC field, see Byte N+4(3) in Figure 2, is a 1-byte value of the Longitudinal Redundancy Check calculation (XORed bytes) for the preceding message. The calculation is performed on the entire message, excluding the Start-Mark. Figure 5 is an example of the BCC calculation.

Tables 2(a), 2(b), and 2(c) describe the micro reader-to-PC communication protocol. In most of the cases, you are mainly interested in the data embedded in the transponder. The data sent by the micro reader to the PC is sequenced as described in Table 2(a). In Table 2(a), the BCC field is a 1-byte value of the Longitudinal Redundancy Check calculation (XORed bytes) for the preceding message. The calculation is performed on the entire message excluding the Start-Mark.

The TI transponder protocol needs to be sent by the PC to the transponder via the micro reader. For simplicity, I only consider the read operation of RO and W/R transponders; see Figure 6. Figure 7 illustrates the transponder response for read only and read/write transponders, while Figure 8 presents the read/write transponder data format.

The Java Communications API

The Java Communication API provides a means to communicate with the outside devices via serial or parallel ports. Classes and interfaces are packaged in the javax.comm package. Classes and Interfaces in the package are:

  • Interfaces: CommDriver, CommPortOwnershipListener, ParallelPortEventListener, and SerialPortEventListener.
  • Classes: CommPort, CommPortIdentifier, ParallelPort, ParallelPortEvent, SerialPort, and serialPortEvent.
  • Exceptions: NoSuchPortException, PortInUseException, and UnsupportedCommOperationException.

Listing One is a Java program that reads an RFID tag. The steps it implements to read RFID tags via serial ports are:

  1. Identify the port to which the reader is attached to the PC.
  2. Open and claim the ownership of the port.
  3. Resolve port ownership contention between multiple Java applications.
  4. Create an OutputStream associated with the port.
  5. Write the stream of data to the port. The stream of the data must conform to the PC-to-micro reader protocol. After the data is successfully written to the port, the reader switches into one of the modes as specified in the data field of the stream.
  6. Register an event listener to the port.
  7. Specify an event type: notifyOnDataAvailable().
  8. The event type calls the interface method serialEvent().
  9. Within the serialEvent method, the RFID tag data is read. When the tag is in the reader's field, it transmits data to the reader, which in turn, transmits to the PC via serial port.
  10. The data is formatted and converted into the hexadecimal form.

Listing One can be divided into three functional parts:

  • Open and take the ownership of the communication port, COM1, to which the reader is connected; see the code excerpt in Example 1.
  • Sending commands to switch the reader to one of its operating modes. In Listing One, a command is sent via the serial port to switch the reader to "continuous normal mode," where the reader continuously reads whenever a tag comes to its field. The code:

outputStream =

  • sends the command to the port by writing the bytestream detailed in Table 3.
  • Register an event listener to the port, specify an event type, and handle the event. The tag data is read when an RFID tag comes in the field of the reader. This makes data available at the port of the PC. Availability of the data triggers the notifyOnDataAvailable() event, which is listened by the serialEvent() method where the data is fetched from the reader to the PC.

Figure 9 is a sample read sequence upon running Listing One.


The Java program I present here lets the reader operate in continuous normal mode by sending bytes of stream. The data read by the RFID reader is transmitted to the PC via serial port. Once the data is available in the processing unit, it all depends on the application as to how those data are manipulated.


Listing One

/* Sample java code to read an RFID tag */

import java.util.*;
import javax.comm.*;

public class RFIDTagRead implements Runnable, SerialPortEventListener {
    static CommPortIdentifier portId;
    static Enumeration portList;

    InputStream inputStream;
    SerialPort serialPort;
    Thread readThread;
    //Array consisting of SOH, length, command, data, BCC
    static byte[] bytearray = {0x01, 0x02, 0x09, 0x32, 0x39};
    static OutputStream outputStream;
    static int n =0;    
    public static void main(String[] args) {
    //Enumerate a list of available ports 
        portList = CommPortIdentifier.getPortIdentifiers();
    // Identify the ports. I connected the reader with COM1
        while (portList.hasMoreElements()) {
            portId = (CommPortIdentifier) portList.nextElement();
            if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
                if (portId.getName().equals("COM1")) {
        System.out.println("The port is: " + portId.getName());
                    RFIDTagRead reader = new RFIDTagRead();

    public RFIDTagRead() {
        try {
        //Open the COM1 port and name it MicroReader with timeout 2000ms
            serialPort = (SerialPort)"SimpleReadApp", 2000);
        } catch (Exception e) {System.out.println("Port Error");}
    try {
            outputStream = serialPort.getOutputStream();
        // Write the stream of data conforming to PC to reader protocol
            System.out.println("The following bytes are being written");
            for(int i=0; i<bytearray.length; i++)
                System.out.println("Tag will be read when its in the 
                    field of the reader");
             } catch (IOException e) {}
    // Set Serial Port parameter
    try {
        } catch (UnsupportedCommOperationException e) {}
     try {
        //Register an event listener object to the port
           } catch (TooManyListenersException e) 
                     {System.out.println("Too Many Listeners");
        //Specify an event type. On data availability, triggers serialEvent method
           try {
        //Associate an InputStream object with this port.
                inputStream = serialPort.getInputStream();
              } catch (IOException e) {}
    //Start a thread to handle the time-to-read the tag
        readThread = new Thread(this);
   public void run() {
    try {
        } catch (InterruptedException e) {} 
    //This method is called by notifyOnDataAvailabe()
    public void serialEvent(SerialPortEvent event) {
    switch(event.getEventType()) {
        case SerialPortEvent.BI:
        case SerialPortEvent.OE:
        case SerialPortEvent.FE:
        case SerialPortEvent.PE:
        case SerialPortEvent.CD:
        case SerialPortEvent.CTS:
        case SerialPortEvent.DSR:
        case SerialPortEvent.RI:
        case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
        case SerialPortEvent.DATA_AVAILABLE:
    n++; //to count the number of readings
    System.out.println("The reading description of RFID Tag" + " " + n);
    //array size must not be less than the number of bytes to be read     
        byte[] readBuffer = new byte[20]; // to store the read data
    int numbyte = 0;
             try {
                 while(inputStream.available() >0) {
            // Read the RFID data and store in the byte array
             numbyte =;
            System.out.println("Number of Bytes read: " + numbyte);
              } catch (IOException e) {} 
        if( readBuffer[0] == 1) /*check if start bit is detected */
            int length = readBuffer[1];
            // Identify the Transponder type
            switch(readBuffer[2]) {
            case 12 :
            System.out.print("RFID is RO:" + "\t");
            case 13 :
            System.out.print("RFID is R/W:" + "\t");
            case 14:
            System.out.print("RFID is MPT/SAMPT:" + "\t");
            case 15:
            System.out.print("RFID is Other:" + "\t");
        // Write the actual tag reading in Hexadecimal  
        for( int m = length+1; m > 2; m--)
        System.out.print(Integer.toHexString(readBuffer[m] & 255));
        System.out.println(" ");
        System.out.println("\t" + "Read Sucessful");
Back to article

Related Reading

More Insights

Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.