Java Serial Com Port Examples: Everything You Need to Know about Serial Communication in Java
- michaelcooper1988
- Aug 11, 2023
- 7 min read
The solution I remember settling on was to create a small command-line program in C that echoed stdin to the serial port and serial port in to stdout. Then, I launched this program from my java process. I don't have the code but there are lots of examples on the web for c programs that write to linux serial ports.
jSerialComm is a Java library designed to provide a platform-independent way to access standard serial ports without requiring external libraries, native code, or any other tools. It is meant as an alternative to RxTx and the (deprecated) Java Communications API, with increased ease-of-use, an enhanced support for timeouts, and the ability to open multiple ports simultaneously.
Java Serial Com Port Examples
To access the contents of the library in your project, make sure to import com.fazecast.jSerialComm.* into your java files. You can then generate a list of all available serial ports on your system (real or virtual), by calling the following static method:
Replace the username parameter with your current username. (If you are not sure what your username is, type whoami and it will tell you.) If you are using SUSE 11.3 or higher, replace the '-a -G' flags with a single '-A' flag. Log out and you should have access to the serial port after logging back in.
Although this library was designed to be as simple and flexible as possible, you can enable a number of different modes of operation via manipulation of the serial port timeout values and the interface through which you choose to access the serial port.
Unfortunately, Sun didn't pay much attention to serial communication in Java. Sun has defined a serial communication API, called JavaComm, but an implementation of the API was not part of the Java standard edition. Sun provided a reference implementation for a few, but not all Java platforms. Particularly, at the end of 2005 Sun silently withdrew JavaComm support for Windows. Third party implementations for some of the omitted platforms are available. JavaComm hasn't seen much in the way of maintenance activities, only the bare minimum maintenance is performed by Sun, except that Sun apparently responded to pressure from buyers of their own Sun Ray thin clients and adapted JavaComm to this platform while dropping Windows support.
SerialPundit is another feature rich library for accessing serial port in Java. It includes features like detecting when a USB-UART device like FTDI232 has been plugged into system , automatically identifies operating system and CPU architecture, does not require any installation, comprehensively documented, well tested and have a support/discussion group as well.
The API uses a callback mechanism to inform the programmer about newly arriving data. It is also a good idea to study this mechanism instead of relying on polling the port. Unlike other callback interfaces in Java (e.g. in the GUI), this one only allows one listener listening to events. If multiple listeners require to listen to serial events, the one primary listener has to be implemented in a way that it dispatches the information to other secondary listeners.
Once the software is installed it is recommended to examine the samples and JavaDoc directories. It makes sense to build and run one of the sample applications to verify that the installation is correct. The sample applications typically need some minor adaptations in order to run on a particular platform (e.g. changes to the hard-coded com port identifiers). It is a good idea to have some serial hardware, like cabling, a null modem, a breakout box, a real modem, PABX and others available when trying out a sample application. Serial_Programming:RS-232 Connections and Serial_Programming:Modems and AT Commands provide some information on how to set up the hardware part of a serial application development environment.
Note:JavaComm itself obtains the default list of available serial port identifiers from its platform-specific driver. The list is not really configurable via JavaComm. The method CommPortIdentifier.addPortName() is misleading, since driver classes are platform specific and their implementations are not part of the public API. Depending on the driver, the list of ports might be configurable / expendable in the driver. So if a particular port is not found in JavaComm, sometimes some fiddling with the driver can help.
The initialization of a serial port is straight forward. Either individually set the communication preferences (baud rate, data bits, stop bits, parity) or set them all at once using the setSerialPortParams(...) convenience method.
The simple way of reading and/or writing from/to a serial port as demonstrated in the previous sections has serious drawbacks. Both activities are done with blocking I/O. That means, when there is
The mentioned "twist" is that JavaComm provides some limited support for asynchronous I/O via an event notification mechanism. But the general solution in Java to achieve non-blocking I/O on top of the blocking I/O system is to use threads. Indeed, this is a viable solution for serial writing, and it is strongly recommended to use a separate thread to write to the serial port - even if the event notification mechanism is used, as explained later.
Once the listener is implemented, it can be used to listen to particular serial port events. To do so, an instance of the listener needs to be added to the serial port. Further, the reception of each event type needs to be requested individually.
Using a separate thread for writing, separate from some main application thread, implies that there is some way to hand off the data which needs to be written from the application thread to the writing thread. A shared, synchronized data buffer, for example a byte[] should do. Further, there needs to be a way for the main application to determine if it can write to the data buffer, or if the data buffer is currently full. In case the data buffer is full it could indicate that the serial port is not ready, and output data has queued up. The main application will have to poll the availability of new space in the shared data buffer. However, between the polling the main application can do other things, for example updating a GUI, providing a command prompt with the ability to abort the sending, etc.
Referring to the skeleton event handler presented in the section Setting up a serial Event Handler, one can now use a shared ring buffer from section A simple, thread-safe Ring Buffer Implementation to support the OUTPUT_BUFFER_EMPTY event. The event is not supported by all JavaComm implementations, therefore the code might never be called. However, in case the event is available it is one building block for ensuring best data throughput, because the serial interface is not left idle for too long.
The following example assumes that the data's destination is some file. Whenever data becomes available it is fetched from the serial port and written to the file. This is an extremely simplified view, because in reality one would need to check the data for an end-of-file indication to, for example, return to the modem command mode.
JavaComm is strictly concerned with the handling of a serial interface and the transmission of data over that interface. It does not know, or provide, any support for higher-layer protocols, e.g. for Hayes modem commands typically used to control consumer-grade modems. This is simply not the job of JavaComm, and not a bug.
There seems to be a trend to abandon the JavaComm API, and using RxTx directly instead of via the JCL wrapper, due to Sun's limited support and improper documentation for the JavaComm API. However, RxTx's documentation is extremely sparse. Particularly, the RxTX people like to make a mess of their versions and package contents (e.g. with or without integrated JCL). Starting with RxTx version 1.5 RxTx contains replacement classes for the public JavaComm classes. For legal reasons they are not in the java.comm package, but in the gnu.io package. However, the two currently available RxTx versions are packaged differently:
The first option has already been explained. The second option is surprisingly simple. All one has to do to port some application from using JavaComm to using RxTx 2.1 is to replace all references to java.comm in the application source code with references to gnu.io. If the original JavaComm application was properly written there is nothing more to do.
The Java Communications (a.k.a. javax.comm) API is a proposed standard extension that enables authors of communications applications to write Java software that accesses communications ports in a platform-independent way. This API may be used to write terminal emulation software, fax software, smart-card reader software, and so on.
In this article we will show you how to use javax.comm to communicate with a serial device based on RS-232. We'll also discuss what the javax.comm API provides and what it doesn't provide. We'll present a small example program that shows you how to communicate to the serial port using this API. At the end of the article we'll briefly detail how this javax.comm API will work with other device drivers, and we'll go over the requirements for performing a native port of this API to a specific OS.
RS-232 stands for Recommend Standard 232; the C simply refers to the latest revision of the standard. The serial ports on most computers use a subset of the RS-232C standard. The full RS-232C standard specifies a 25-pin "D" connector, of which 22 pins are used. Most of these pins are not needed for normal PC communications, and indeed, most new PCs are equipped with male D-type connectors having only 9 pins. For more on RS-232, see the Resources section.
A complete API specification for serial and parallel communication ports. (In this article we consider serial ports only.) Without a common API in your development efforts, workload will increase because you'll have to provide support to serial devices.
The basic I/O via a subclass of Java IO streams. For input and output, the javax.comm API uses streams; the concept of streams should be familiar to all Java programmers. It is important to reuse Java concepts when building new functionality or the APIs will become unwieldy. 2ff7e9595c
Comments