Java & RFID Tags

The Java Communication API lets you send commands to and receive responses from RFID readers such as the TI S2000 Micro Reader.


November 01, 2005
URL:http://www.drdobbs.com/architecture-and-design/java-rfid-tags/184406323

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 http://www.ti.com/rfid/docs/products/ 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 javax.com package are:

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:

outputStream =
serialPort.getOutputStream();
outputStream.write(bytearray);

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

Conclusion

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.

DDJ



Listing One

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

import java.io.*;
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) portId.open("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
            outputStream.write(bytearray);
            outputStream.flush();
            
            System.out.println("The following bytes are being written");
            for(int i=0; i<bytearray.length; i++)
                System.out.println(bytearray[i]);
                System.out.println("Tag will be read when its in the 
                    field of the reader");
             } catch (IOException e) {}
    // Set Serial Port parameter
    try {
            serialPort.setSerialPortParams(9600,
                SerialPort.DATABITS_8,
                SerialPort.STOPBITS_1,
                SerialPort.PARITY_NONE);
        } catch (UnsupportedCommOperationException e) {}
     try {
        //Register an event listener object to the port
        serialPort.addEventListener(this);
           } catch (TooManyListenersException e) 
                     {System.out.println("Too Many Listeners");
   } 
        //Specify an event type. On data availability, triggers serialEvent method
    serialPort.notifyOnDataAvailable(true);
           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);
        readThread.start(); 
    }
   public void run() {
    try {
            Thread.sleep(56);
        } 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:
            break;
        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 = inputStream.read(readBuffer);
            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");
            break;
            }
            case 13 :
            {
            System.out.print("RFID is R/W:" + "\t");
            break;
            }
            case 14:
            {
            System.out.print("RFID is MPT/SAMPT:" + "\t");
            break;
            }
            case 15:
            {
            System.out.print("RFID is Other:" + "\t");
            break;
            }
            }
        // 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");
        System.out.println("----------------------------------");
            break;
        }
    }
}
Back to article

November, 2005: Java & RFID Tags

serialPort = (SerialPort) portId.open("SimpleReadApp", 2000) opens COM1 serial port identified in the following code segment 
        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();
                }
            }
        }

Example 1: Opening COM1.

November, 2005: Java & RFID Tags

Figure 1: TI S2000 Micro Reader.

November, 2005: Java & RFID Tags

—————————————————————————————————————————— - - ———————
|Start | Length | Cmd 1  | Cmd 2  | Data      | BCC |
—————————————————————————————————————————— - - ———————

Byte			Contents (hexadecimal value) 
0 		Start Mark (SOH, 01hex) signifies the beginning of the message
1		Length, in bytes, of the following command and data fields
2 		Command Field (1)—Explained below
3 		Command Field (2) (optional)—Explained below
4(3) 			Data Field (1) — explained below
N+3(2)		Data Field (N) — explained below
N+4(3) 		        BCC — explained below

Figure 2: PC-to-micro reader protocol.

November, 2005: Java & RFID Tags

E8Hex = 1110 1000BIN
1 1 1 0  1 0 0 0
| | | |  | | —-
| | | |  | |  |
| | | |  | |   —- Perform single command
| | | |  |  ——— No FBCC calculation
| | | |   ———— Power Burst I value set in Data Field
| | |  —————- Default set to 0
| |  ——————- Power Burst II value set in Data Field
|  ———————- Data values follows in Data Field
 ————————- Command Field (2) follows

Figure 3: Example of bit sequence in Command Field (1).

November, 2005: Java & RFID Tags

06Hex =  0 0 0 0  0 1 1 0BIN

0 0 0 0  0 1 1 0
————— | | |
    |      | | | 
    |      | |  —- No special write timing
    |      |  ——- Wireless synchronization is used
    |       ———- Micro reader calculates DBCC
     ——————— Bits 3-7 reserved

Figure 4: Example of bit sequence in Command Field (2).

November, 2005: Java & RFID Tags

02 08 32

02     0000 0010
08     0000 1000
————————
XOR    0000 1010
32     0011 0010
————————
XOR    0011 1000 = 38 (hex)

Figure 5: Example of BCC calculation.

November, 2005: Java & RFID Tags

Figure 6: TI transponder protocol.

November, 2005: Java & RFID Tags

Figure 7: Read-only transponder data format.

November, 2005: Java & RFID Tags

Figure 8: Read/write transponder data format.

Terms of Service | Privacy Statement | Copyright © 2024 UBM Tech, All rights reserved.