Sie sind auf Seite 1von 19

SUN DOESN'T SUPPORT SERIAL COMMUNICATION

EXTENSION FOR WINDOWS


Official standpoint of Sun is that Windows version of Java
Communication API (JavaComm) is EOLed and will not be
continued. Implementations of the API are currently available
only for Solaris SPARC, Solaris x86, and Linux x86.
The alternative is RXTX - Java library using a native
implementation providing serial and parallel communication
for Java for several operating systems (Windows included).
This library is available under GPL license. Library provides
the same API as Sun's Java Communication API so migration
to RXTX library is very simple - you have only to change
imports declarations.

PREPARING ECLIPSE ENVIRONMENT


Create new Java project
The first thing you need to do is creating new Java project in
Eclipse (for example called JavaSerial).

Download and install RXTX library


Go to the RXTX download page and get the newest version of
RXTX binaries compressed in ZIP file and destined for
Windows operating system.
Go to the home directory of your recently created JavaSerial
Project and create new directory called lib. Unzip
downlowded RXTX package into temporary directory and
copy RXTXcomm.jar, rxtxSerial.dll and rxtxParallel.dll files

into lib directory. Dll files are located in Windows/i368mingw32 directory of RXTX library.
Refresh JavaSerial project by hitting F5 key. Next click the
right mouse button on the JavaSerial project and go to the
Properties/Java Build Path. Select Libraries tab and click Add
JARs button. Select RXTXcomm.jar and just click OK button.

Extend project classpath


If you want to run your JavaSerial project from Eclipse by
clicking Run button you should enclose in classpath all copied
*.dll files as a native libraries. To do this click the right
mouse button on JavaSerial project and go to the
Properties/Java Build Path. Select Source tab and expand
JavaSerial/src tree element. Click on Native library location:
(None) and click Edit button. After the Native Library Folder
Configuration dialog window appears click on Workspace
button and select JavaSerial/lib folder. After all start clicking
OK buttons until you back to the begining.
Congartulations! Now you are ready to run and test you
JavaSerial project in Eclipse.

Test your environment


It's time to make simple test if the created Eclipse
environment is properly configured to run applications based
on RXTX library for Windows.
Create new class named ListAvailablePorts.java and paste
following code.

1. import gnu.io.CommPortIdentifier;
2.
3. import java.util.Enumeration;
4.
5. public class ListAvailablePorts {
6.
7.
8.

public void list() {


Enumeration ports = CommPortIdentifier.getPortIde
ntifiers();

9.
10.

while(ports.hasMoreElements())

11.
System.out.println(((CommPortIdentifier)por
ts.nextElement()).getName());
12.

13.
14.

public static void main(String[] args) {

15.

new ListAvailablePorts().list();

16.
17.

}
}

Run your simple application by clicking Run button and if the


environment is configured correctly you should see following
output in console window:

Stable Library
=========================================
Native lib Version = RXTX-2.1-7
Java lib Version

= RXTX-2.1-7

COM1
LPT1
Number of listed ports depends on number of available ports
in your operating system. If you do not see presented output
please repeat configuration process again.

PHYSICAL EQUIPMENT
The choise of physical equipment which you need to use
during development of RS232 communication application
depends on your needs and capabilities of your avialable
equipment. You should ask yourself following questions:
do I have a RS232 specification of communication
protocol between end-point device and application which I
develop?

is my laptop or PC equipped with serial ports (one or


two?)

do I have access to the end-point device or maybe I


should write an emulator of end-point device?

Assuming that you have no access to the end-point device


and you have only specification of RS232 communication
protocol between device and application one of two following
solutions should be considered.

Two serial ports wired together


If your laptop or PC is equipped with two serial ports you can
simply buy very cheap DB9-DB9 cable and connect two serial
ports together. You will be able to connect end-point device
software emulator to the one of serial ports available in the
operating system and the application to the second of
available serial ports.

Virtual Serial Port Driver 6.0


If you don't have any serial port in your laptop or PC you
should use one of available serial port emulators or simply
buy USB adapter (if you have USB port available).
Virtual Serial Port Driver 6.0 is an excellent commercial serial
port emulator for Windows operating system family which
allows you to create pairs of serial ports. Serial ports within
each pair could be connected together through the virutal
RS232 wire. Then you can connect to the first emulated
serial port an end-point device emulator and to the second
serial port the application making a communication between
these parts. It is great solution if you don't have access to
the device to which you develop RS232 communication
software and if you don't have any serial port on your laptop
or PC - the only thing you should have is a specification of
RS232 communication between device and application.

RS232 APPLICATION EXAMPLE


Now we develop sample application based on RXTX library.
Presented example will be very simple to show important
communication issues and best practices. You can extend this
sample to create more sophisticated applications.

Example communiaction main class


Following steps should be performed to establish serial port
connection:
receive CommPortIdentifier from the system with
specific name (e.g. COM1) - received identifier could be in
use by any other application - check it invoking
portIdentifier.isCurrentlyOwned() method

if received CommPortIdentifier is not in use by different


application, you can open CommPort (which in our case is
instance of SerialPort)

the next step is to pass all setup communication


parameters: baudrate, number of data bits, number of
stop bits and possible parity bit

the last step is to retrieve InputStream and


OutputStream for sending and receiving raw bytes
As shown below for receiving raw bytes it is started new
Thread which takes as parameter InputStream from serial
port.

1. import gnu.io.CommPortIdentifier;
2. import gnu.io.SerialPort;
3.

4. public class RS232Example {


5.
6.

public void connect(String portName) throws Except


ion {

7.

CommPortIdentifier portIdentifier = CommPortIdenti


fier.getPortIdentifier(portName);

8.
9.

if (portIdentifier.isCurrentlyOwned()) {

10.
11.
12.
imeout

System.out.println("Port in use!");
} else {
// points who owns the port and connection t

13.
SerialPort serialPort = (SerialPort) portIdenti
fier.open("RS232Example", 2000);
14.
15.

// setup connection parameters

16.

serialPort.setSerialPortParams(

17.
38400, SerialPort.DATABITS_8, SerialPort.S
TOPBITS_1, SerialPort.PARITY_NONE);
18.
19.

// setup serial port writer

20.
CommPortSender.setWriterStream(serialPort
.getOutputStream());

21.
22.

// setup serial port reader

23.
new CommPortReceiver(serialPort.getInputS
tream()).start();
24.

25.

26.
27.
public static void main(String[] args) throws E
xception {
28.
29.
// connects to the port which name (e.g. COM1)
is in the first argument
30.

new RS232Example().connect(args[0]);

31.
32.
// send HELO message through serial port usin
g protocol implementation
33.
CommPortSender.send(new ProtocolImpl().get
Message("HELO"));
34.
35.

}
}

Serial port data receiver


As you can see CommPortReceiver is a Thread instance with
run() implemented method which is performed in inifite loop
until java application is broken by the user.

While there is opened InputStream by the end-point device


in.read() method blocks and waits for incoming raw bytes.
Each byte is passed to the protocol manager which handles
all protocol issues (for example recognizes messages from
raw bytes). When end-point device breaks the opened
InputStream then in.read() method starts to return -1 value
without blocking. Because waiting for external device in
infinite loop without in.read() blocking method could be
destructive for performence of operating system sleep
method is introduced to decrease number of in.read()
executions.
1. import java.io.IOException;
2. import java.io.InputStream;
3.
4. public class CommPortReceiver extends Thread {
5.
6.

InputStream in;

7.

Protocol protocol = new ProtocolImpl();

8.
9.

public CommPortReceiver(InputStream in) {

10.
11.

this.in = in;
}

12.
13.

public void run() {

14.

try {

15.

int b;

16.

while(true) {

17.
18.
returns -1

// if stream is not bound in.read() method

19.

while((b = in.read()) != -1) {

20.

protocol.onReceive((byte) b);

21.

22.

protocol.onStreamClosed();

23.
24.
heck again

// wait 10ms when stream is broken and c

25.

sleep(10);

26.

27.

} catch (IOException e) {

28.

e.printStackTrace();

29.

} catch (InterruptedException e) {

30.

e.printStackTrace();

31.
32.

}
}

33.

Protocol
Protocol is used to handle all incoming bytes, segregate them
and create recognized messages. The interface of Protocol
implementation allows to inform protocol manager about
each incoming byte and about broken stream situation.
1. public interface Protocol {
2.
3.

// protocol manager handles each received byte

4.

void onReceive(byte b);

5.
6.

// protocol manager handles broken stream

7.

void onStreamClosed();

8. }
In our case protocol implementation is simple: message is
always ended with new line character. Colleaction of received
bytes creates String message which could be recognized.
When new message is recognized (new line character
appears or stream closes) then onMessage() method is called
to handle recognized message. If you develop more
complicated example (and I am sure you will do) logic of
triggered actions depending on recognized message should
be placed in external class (some kind of interpreter).

In our case when HELO message comes then OK message


should be sent as a response. If OK message is received then
acknowledge should be sent as a response (OK ACK).
1. public class ProtocolImpl implements Protocol {
2.
3.

byte[] buffer = new byte[1024];

4.

int tail = 0;

5.
6.

public void onReceive(byte b) {

7.

// simple protocol: each message ends with new line

8.

if (b=='\n') {

9.

onMessage();

10.

} else {

11.

buffer[tail] = b;

12.

tail++;

13.
14.

}
}

15.
16.
17.

public void onStreamClosed() {


onMessage();

18.

19.
20.

/*

21.
oked

* When message is recognized onMessage is inv

22.

*/

23.
24.

private void onMessage() {


if (tail!=0) {

25.

// constructing message

26.

String message = getMessage(buffer, tail);

27.
System.out.println("RECEIVED MESSAGE: " +
message);
28.
29.

// this logic should be placed in some kind of

30.

// message interpreter class not here

31.

if ("HELO".equals(message)) {

32.
);
33.

CommPortSender.send(getMessage("OK")
} else if ("OK".equals(message)) {

34.
CK"));
35.

CommPortSender.send(getMessage("OK A
}

36.

tail = 0;

37.

38.

39.
40.

// helper methods

41.

public byte[] getMessage(String message) {

42.

return (message+"\n").getBytes();

43.

44.
45.
{

public String getMessage(byte[] buffer, int len)

46.

return new String(buffer, 0, tail);

47.
48.

}
}

Serial port data sender


1. import java.io.IOException;
2. import java.io.OutputStream;
3.
4. public class CommPortSender {
5.
6.

static OutputStream out;

7.
8.

public static void setWriterStream(OutputStream ou


t) {

9.

CommPortSender.out = out;

10.

11.
12.

public static void send(byte[] bytes) {

13.

try {

14.
System.out.println("SENDING: " + new Strin
g(bytes, 0, bytes.length));
15.
16.
// sending through serial port is simply writin
g into OutputStream
17.

out.write(bytes);

18.

out.flush();

19.

} catch (IOException e) {

20.

e.printStackTrace();

21.

22.
23.

}
}

Running RS232 example

In order to run serial port communication example you need


to run two instances of developed application:
the first as an end-point device which is connected to
the port COM1

the second as the application connected to the port


COM2
Moreover you have to have connected COM1 and COM2 port
together (using DB9-DB9 cable or using virtual wire from
emulating serial port software).

Follow steps below to run two instance of application in


Eclipse environment with different command line parameters:
Click right mouse button on RS232Example class and
select Run As/Open Run Dialog

Choose Arguments tab and type in Program arguments


text area the first parameter COM1

Click Apply button and then Run button


You should see following output in output console which
means that the first instance has been strated and sent HELO
command to the not bound serial port.

Stable Library
=========================================
Native lib Version = RXTX-2.1-7
Java lib Version

= RXTX-2.1-7

SENDING: HELO
Next repeat above steps but type COM2 in Program
arguments text area. Switch between output consoles using
button with monitor icon and compare results. You should
have two output consolse with results as presented below.

The first console (COM1 - 1 instance)


After the second instance had been started HELO message
was received. Then OK message was sent as a response.
Then acknowledge of OK message was received.
Stable Library
=========================================
Native lib Version = RXTX-2.1-7
Java lib Version

= RXTX-2.1-7

SENDING: HELO

RECEIVED MESSAGE: HELO


SENDING: OK

RECEIVED MESSAGE: OK ACK

The second console (COM2 - 2 instance)


The second instance sent HELO message receiving OK
message. Then acknowledge of OK message was sent to the
first instance.
Stable Library
=========================================
Native lib Version = RXTX-2.1-7
Java lib Version

= RXTX-2.1-7

SENDING: HELO

RECEIVED MESSAGE: OK
SENDING: OK ACK

CONCLUSIONS
When you receive information about that Sun doesn't support
serial communication for Windows system environment you
starts desperately searching alternative. In consequence
there is very good free alternative which is used in several
projects (and works fine) - RXTX library. Moreover you can in

simple way prepare development environment to work on


your project effectively not having end-point device or even
serial ports installed in your laptop or PC.

Das könnte Ihnen auch gefallen