Serial + Java = The World (Mostly)

Whether it's an optional add-on or a part of the original base,a large percentage of modem devices still make use of serialcommunications for their connectivity. Communicating with thesedevices in Java requires the use of a vendor supplied serialsupport to provide the basic byte-wise communications capability.As the connected devices get more intelligent, communications ceaseto be merely byte streams and become streams of multi-byte messagesor “packets” so code is needed to wade through the raw data streamand isolate the individual messages. Finally, a solution resilientto change has become imperative. As even newer devices are added, asolution that not only copes with change, but also gracefullyaccommodates it is necessary.

For example, a serial port is used to retrieve GlobalPositioning System (GPS) information using the National MarineElectronics Association (NMEA) format. The code has been developedand tested against a Trimble Lassen-SK8 device, which is a 12V unitwell suited for automobile applications.

Figure 1: Overall data flow

Working Through the Solution

As with most problems, the overall problem can be divided intosmaller elements and then solved individually. Defining the smallproblems is the first step in the process:

  1. Read the bytes from the serial port
  2. Extract and validate the messages
  3. Provide access to data in the message
  4. Define the listener interface
  5. Retrieve the GPS location.

To simplify the issue, each of the above problems is assigned toa class, and then each class is implemented to solve itsproblem(s). For example, three Java classes and an Interface can bereserved (see Figure 1). The GpsTransport class will take care ofthe first two duties, the GpsMessage class will take care of thethird duty, the GpsTransportListener Interface will handle dutyfour, and the Gps class is the master object that will be thesubsequent application code's focal point.

Reading the Bytes from the Serial Port

A transport is responsible for sending and/or receivingmessages. In the case of the GpsTransport, the problem of sendingmessages can be overlooked, and the focus can be placed on how toprocess input messages from the GPS unit. Since the application andother activities should be executed while the user is waiting forinput from the InputStream, the GpsTransport must create andmaintain an internal thread that will continuously process it. Thecode for reading the serial port is contained in the methodGpsTransport.run0. This code begins executing on its own threadwhen the method shown below, GpsTransport.start0, is called.

Next the basics must be addressed. In this case, the basicsconsists of the fundamental serial communications capability. Here,the serial support that is part of the VisualAge Micro Editionproduct is employed, but any similar serial support package couldbe utilized (such as Sun Microsystems' javax, comm). TheGpsTransport makes use of subclasses of the abstract InputStreamclass to accomplish its work. The InputStream class defines asimple protocol to read information from various sources in astandard way. By using this protocol, developers can apply the samemethodology to talk to either serial or file I/O. SeveralInputStream subclasses exist, but the SerialPortlnputSteam is usedfor serial support and the Filelnputstream is used for file I/Osupport.

The SerialPortlnputstream will be used to read the bytes fromthe serial port. Since the serial I/O is implemented by using JavaNative Interface (JNI) to call the Operating System API's to readthe serial port, developers should be careful to minimize thesystem overhead. They do this by calling the read(byte[] buffer)method with a large buffer instead of calling the single read()method for each byte. This way minimizes the number of internalcalls made to read the entire buffer.

It's important to note that the above code contains a whole loopthat continues until isRunning0 returns false. The GpsTransportclass contains a complimentary GpsTransport. stop0 method sets therunning flag to false, which will cause the loop to exit. Thisallows the thread to be cleanly stopped when the transport has beenrequested to stop processing by another thread.

Extracting the Messages

The NMEA 0183 message format is astraightforward variable length packet of 79 bytes or less. Allbytes are in ASCII characters so the packets are directly readable.The messages have the general form ……..

$IDMSG, D1,D2,D3,D4……,Dn*CS[CR][LF]


Message start character

Two letter message source identifier

Three letter message identifier

Field delimiter

A data field element

The checksum delimiter

Two ASCII characters that indicate the hexadecimal checksumvalue

Message termination characters

The next activity in processing the inputbytes involves extracting a GPS message from the raw data. This isaccomplished by scanning the bytes read for the NMEA protocoldelimiters to find the boundaries of the particular message thatwas just received. The NMEA 0183 message format is explainedfurther in the sidebar.

Below is the code that ensures a message is complete, extractsthe bytes, and creates the GpsMessage instance for furtherprocessing by other objects:

Figure 2: Packetizing the input stream

After a message has been extracted, the message must bevalidated. The validation of a GPS message involves ensuring themessage follows the defined format, and the checksum is valid.Validation of the message insures the application does not receiveinvalid data. This responsibility is assigned to the message classitself. This code is contained in the GpsMessage. isValid() methodand is used as follows:

Anyone who has an interest in receiving valid messages and is alistener of the transport will now be notified. After notification,the processing continues looking for the next message. Thisprocessing continues forever until the transport is stopped via theGpsTranspOrt. stop() method discussed earlier.

By using only the InputStream protocol in the GpsTransport, anyInputStream can be supported as the source of the GPS data. This isvery important because during the testing of this code, theFilelnputStream can test by creating and using a file as our GPSsource. That way developers don't need real operational hardwarefor complete system testing. They can also use the FilelnputStreamto simulate data that may not be easy to create in the currenthardware configuration. This is handy for GPS devices as they don'toperate well inside buildings, so actual data can be “captured”, ornew data even invented—this is how GPS code can be testedagainst exotic tropical locations—and the code tested withthe simulated stream from a file.

Accessing the Data

GPS Fix Data : This message has 14 datafields of the following form.

Position UTC



GPS Quality

Number of satellites used

Horizontal dilution of precision

Antenna altitude in meters

Geoidal separation in meters

Age of differential GPS data

Differential reference station ID

The GpsMessage contains information about asingle GPS message received from the InputStream. The message willbe responsible for returning the various data fields containedwithin the message. The message also helps the transport determineif the message is valid by insuring the checksum is correct. Forexample, the GPS Fix Data message is the message that provideslatitude and longitude data. The message instance would be able toanswer any of these values for this message.

Defining the Listener Interface

The GpsTransportListener interface defines the messageReceivedmethod that will be called when a message is received by thetransport. A message is passed as a parameter on themessageReceived notification method so that the receiving objectthat is listening can interrogate the message for any desireddata.

That the GpsTransport does not care about the implementation ofthe GpsTransportListener is an important concept. Many classes mayimplement the GpsTransportListener to perform various functions.For example, a transport debug class could be created to print allmessages received to the System.out or a log file. In thissolution, the Gps class will implement the GpsTransportListener toget the latitude and longitude.

Getting the GPS Location

The Gps class implements the GpsTransportListener and registersits interest in receiving all valid messages that are received. TheGps class' messageReceived method uses the GpsMessage parameter toretrieve any desired data from the GPS messages it receives. Inthis example , it explicitly looks for the GPS Fix Data message andsaves the current latitude and longitude.

Creating a New Transport

To support a new hardware device, these steps should be followedto create and test a new transport:

  1. Get all the documentation available about the device. Thisincludes the hardware information, the communication information(e.g. baud rate), and the message format information.
  2. Get the device and run any vendor supplied test program toinsure the device is correctly connected to your machine.
  3. Build new transport software by starting simple and iteratingcode until the desired function is complete. Since Java is highlyportable from one hardware platform to another, for convenience,most of the development and testing could be done on a developmentmachine (e.g., Windows NT) and later tested on the runtimemachine.
  4. Perform the final testing on the target machine.

Further Design Considerations

At this point, developers should examine other aspects ofpossible application solutions. An important consideration is howdoes the application code interact with the Gps object. Oneimmediate solution is to have the Gps class provide its ownlistener interface to trigger when the GPS location has changed.That way the application code could register interest with the Gpsobject for the information it is interested in, and wouldsubsequently be notified at the appropriate time, when the datachanges.

The granularity of this solution could range anywhere from whenan individual data item has changed (such as the latitude) toindicating only that the Gps object has changed in some manner, andthe particulars would be determined by further interrogation of theGps object. The granularity of the listener / notification schemewould be tuned to a developer's particular applications informationneeds and performance considerations.

Another possibility is for the individual data items themselvesto have listener interfaces. That way the latitude and longitudevalues could be encapsulated in classes like GpsLatitude andGpsLongitude and could be interacted with directly, as opposed toalways going through the Gps object to get the information. Thiswould be a great way to connect up the individual elements of theGps information to their respective individual user interfacecomponents.

Finally, the grand unification scheme should be considered.Defining a measurement interface that any measurement from anydevice could support would allow applications to receive deviceinformation in a common way.

In fact, going even further, all devices could be supported viathree simple concepts:

  1. A measurement is data sent to or received from a hardwaredevice
  2. A command is an operation or set of operations performedagainst a hardware device
  3. A signal is a notification received from a hardwaredevice.

That way, by having a common interface, application code wouldbe tremendously resilient to change. New devices, not conceived oforiginally, could be introduced to the already written applicationcode and would work fine, as long as they implemented the commoninterface. Some simple tests can be performed to see whether devicesoftware is truly resilient; the application code should not haveto be changed as a result of:

  • Changes in message formats. For example, the GPS informationcould be provided via other format than NMEA (e.g., TrimbleStandard Interface Protocol).
  • Moving to another communication device. For example, movingfrom serial to USB.

The common theme in all this discussion is the tradeoff ofinflexible simplicity for slightly more complicated flexibility.Just a little more thought and effort will pay off later in waysthat developers may not be able to foresee today.

It is relatively easy to interface with serial devices.Hopefully, developers will contemplate and employ some of theprocedures and techniques presented here whereby you can handlealmost any serially interfaced device. And not only standard RS232serial, but for an assortment of other very active serial stylebusses in use by many industries.

Maybe you have gained an appreciation for the problem ofplanning for change, even though we didn't have the space to dealwith the complete story. For example, we have an extremely robustsolution that we have used to communicate not only with a lame setof devices on an automobile bus (which changes from manufacturer tomanufacturer), but the solution smoothly handles multiple “packet”oriented communications means, serial and beyond.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.