0% found this document useful (0 votes)
127 views23 pages

Comunicare Seriala

1. The document discusses reading data from a COM port in Java. It provides a sample Java program that can be used to read incoming data from a COM port and process it. 2. The program opens the specified COM port, sets the port parameters like baud rate, and starts a thread to continuously read available data from the port's input stream. 3. When data is available, it is read from the input stream and printed to the console. This provides a simple way to read incoming serial data in Java.

Uploaded by

Marius Branzila
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
127 views23 pages

Comunicare Seriala

1. The document discusses reading data from a COM port in Java. It provides a sample Java program that can be used to read incoming data from a COM port and process it. 2. The program opens the specified COM port, sets the port parameters like baud rate, and starts a thread to continuously read available data from the port's input stream. 3. When data is available, it is read from the input stream and printed to the console. This provides a simple way to read incoming serial data in Java.

Uploaded by

Marius Branzila
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd

Client server

Most projects that deal with hardware and devices, needs to communicate with
them using the COM port of the PC or Server. For example if there is a modem
that is connected to a server via its COM port and the Java program has to
read the output of the modem then the Java program has to read the COM port
for any incoming data.
This sample Java program can be used to Read from a COM port for incoming
data and process it. Note that you will need to change the Port number to
COM1 or COM2 or any other ports as required.

Also if you are using unix based machines then you will have to uncomment the
/dev/term/a instead of COM.

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

public class SimpleRead implements Runnable,


SerialPortEventListener {
static CommPortIdentifier portId;
static Enumeration portList;

InputStream inputStream;
SerialPort serialPort;
Thread readThread;

public static void main(String[] args) {


portList = CommPortIdentifier.getPortIdentifiers();

while (portList.hasMoreElements()) {
portId = (CommPortIdentifier)
portList.nextElement();
if (portId.getPortType() ==
CommPortIdentifier.PORT_SERIAL) {
if (portId.getName().equals("COM1")) {
// if
(portId.getName().equals("/dev/term/a")) {
SimpleRead reader = new SimpleRead();
}
}
}
}

public SimpleRead() {
try {
serialPort = (SerialPort)
portId.open("SimpleReadApp", 2000);
} catch (PortInUseException e)
{System.out.println(e);}
try {
inputStream = serialPort.getInputStream();
} catch (IOException e) {System.out.println(e);}
try {
serialPort.addEventListener(this);
} catch (TooManyListenersException e)
{System.out.println(e);}
serialPort.notifyOnDataAvailable(true);
try {
serialPort.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException e)
{System.out.println(e);}
readThread = new Thread(this);
readThread.start();
}
public void run() {
try {
Thread.sleep(20000);
} catch (InterruptedException e)
{System.out.println(e);}
}

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:
byte[] readBuffer = new byte[20];

try {
while (inputStream.available() > 0) {
int numBytes =
inputStream.read(readBuffer);
}
System.out.print(new String(readBuffer));
} catch (IOException e) {System.out.println(e);}
break;
}
}
}
Comunicarea pe porturile seriale n java
Lucrarea 0. Comunicarea pe porturile seriale n java
1. Obiectivul lucrrii
2. Noiuni preliminare
2.1 Instruciuni de instalare Java Communication API
3. Listare porturi disponibile
4. Deschiderea unui port serial
5. Deschiderea unui port paralel
6. Scrierea i citirea de pe un port
6.1 Scriere i citire n mod sincron
6.2 Scriere i citire n mod asincron

1. Obiectivul lucrrii

Scopul acestei lucrri este de a prezenta modul de accesare a portului serial


i paralel folosind limbajul de programare Java.

2. Noiuni preliminare

Java 2 Standard Edition nu are suport pentru accesarea porturilor seriale.


Suportul pentru accesarea porturilor seriale este oferit de SUN prin
intermediul pachetului Java Communication API. Prin intermediul acestui
pachet programatorul poate accesa porturile seriale i paralele ntr-o manier
independent de platform. Pentru a putea accesa porturile seriale i paralele
pachetul Java Communication trebuie instalat ulterior.

Arhitectura librrii pentru accesarea porturilor seriale i paralele este


prezentat n figura 1.
Figura 1. Structura Java Communication API.

n cadrul librriei Communication API sunt definite dou clase principale: clasa
SerialPort i clasa ParallelPort. Aceste clase motenesc clasa CommPort
(aceasta este o clas abstract) i definesc cele dou tipuri de porturi ce pot fi
accesate prin intermediul Communication API.

Constructorii claselor SerialPort i ParallelPort nu sunt publici, astfel nct


obinerea unei instane a acestor clase se realizeaz prin intermediul unor
metode statice. Pentru a obine lista de porturi disponibile se folosete metoda
static CommPortIdentifier.getPortIdentifiers(). Metoda returneaz o list de
obiecte de tip CommPort ce identific toate porturile disponibile i care pot fi
deschise. Pentru fiecare obiectele de tip CommPort se poate apela metoda
open() pentru a deschide respectivul port. De asemenea obiectul poate fi
convertit la tipul SerialPort sau ParallelPort n funcie de tip de port pe care il
reprezint. Fiecare dintre clasele SerialPort i ParallelPort conin metodele
necesare pentru a putea seta parametrii specific fiecrui tip de port.

2.1 Instruciuni de instalare Java Communication API


Java 2 Standard Edition nu include pachetul Java Communication API
necesar pentru lucrul cu porturi seriale. Pentru a avea acces la porturile
seriale si a putea trimite i citi date pe porturile seriale si paralele (standardele
RS323 i IEEE 1284) va trebui s desccai i s instalai pachetul Java
Communication API.
Versiunea curent a acestei librrii este 3.0 dar pentru aceast versiunea nu
se ofer suport pentru sistemul de operare Windows. Pentru a putea lucra din
Windows va trebui s instalai versiunea anterioar a acestei librrii Java
Communication API 2.0.

Instruciuni de instalare pentru platforma Windows


1. Descrcai pachetul Java Communication API 2.0
2. Copiai fiierul win32com.dll n directorul <jdk>\jre\bin
3. Copiai pachetul comm.jar n directorul <jdk>\jre\lib\ext
4. Copiai fiierul javax.comm.properties n directorul <jdk>\jre\lib
S-a notat cu <jdk> calea ctre directorul de instalare al J2SE (de exemplu
c:\java\jdk.1.5.0).

3. Listare porturi disponibile

Aplicaia prezentat n aceast seciune exemplific modul n care se poate


utiliza librria Communication API pentru a afia la consol toate porturile
seriale i paralele disponibile pe calculator. Dup cum s-a precizat deja
librria pune la dispoziia programatorului metoda static
CommPortIdentifier.getPortIdentifiers() ce returneaz un obiect de tip
Enumeration ce conine lista de porturi disponibile.

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

public class Main {

public static void testComm(){


System.err.println("Test port.");
Enumeration portList = CommPortIdentifier.getPortIdentifiers();

while(portList.hasMoreElements()){
CommPortIdentifier cp = (CommPortIdentifier)portList.nextElement();
System.err.println("Port name="+cp.getName());
//System.out.println(portList.nextElement().toString());
}
}

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Main.testComm();
}

}
4. Deschiderea unui port serial

Aceast seciune prezint modul n care poate fi deschis un port serial pentru
a realiza operaii de scriere i citire.

Paii necesari pentru a deschide un port serial sunt urmtorii:


1. Obinerea obiectului de tip ComPortIdentifier ce identific portul dorit.
2. Conversia obiectului la tipul CommPort i deshiderea portului prin apelarea
metodei open() din cadrul obiectului de tip ComPortIdentifier. Atenie dac portul
este deja deschis de ctre o alt aplicaie atunci metoda open() va eua i va
returna o excepie.
3. Construirea obiectelor de tip flux de intrare i flux de ieire pentru a scrire
respectiv a citi date folosind metodele getInputStream i getOutputStream.

package commtest;
import javax.comm.*;
import java.io.*;

public class OpenSerialPort {


static int TIMEOUTSECONDS = 5;
static int BAUD = 38400;

public static void main(String[] args) throws Exception{

DataInputStream is;
PrintStream os;

CommPortIdentifier thePort = CommPortIdentifier.getPortIdentifier("COM12");

CommPort communicationPort = thePort.open("Test app", TIMEOUTSECONDS * 1000);

SerialPort serialPort = (SerialPort) communicationPort;

serialPort.setSerialPortParams(BAUD, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);

try {
is = new DataInputStream(serialPort.getInputStream());
} catch (IOException e) {
System.err.println("Can't open input stream: write-only");
}
os = new PrintStream(serialPort.getOutputStream(), true);
System.out.println("Ready to do read / write on port "+serialPort.getName());
}

}
5. Deschiderea unui port paralel

Aceast seciune prezint modul n care poate fi deschis un port serial pentru
a realiza operaii de scriere i citire.

Deschiderea portului paralel pentru scriere i citire se face n mod similar ca i


in cazul portului serial, doar c obiectul generic de tip CommPort va trebui
convertit la tipul ParallePort pentru a avea acces la metodele specifice portului
paralel.

package commtest;
import javax.comm.*;
import java.io.*;

public class OpenParallelPort {


static int TIMEOUTSECONDS = 5;
static int BAUD = 38400;

public static void main(String[] args) throws Exception{

DataInputStream is;
PrintStream os;

CommPortIdentifier thePort = CommPortIdentifier.getPortIdentifier("LPT1");

CommPort communicationPort = thePort.open("Test app", TIMEOUTSECONDS * 1000);

ParallelPort paralelPort = (ParallelPort) communicationPort;

try {
is = new DataInputStream(serialPort.getInputStream());
} catch (IOException e) {
System.err.println("Can't open input stream: write-only");
}
os = new PrintStream(serialPort.getOutputStream(), true);
System.out.println("Ready to do read / write on port "+serialPort.getName());
}

6. Scrierea i citirea de pe un port

Operaiile de scriere i citire a porturilor se pot face n dou moduri

Pachetul Communication API permite realizarea de operaii de scriere citire


att n mod sincron ct i in mod asincron.
6.1 Scriere i citire n mod sincron

Comunicarea n mod sincron presupune existena unui protocol de


comunicaie intre aplicaia Java i dispozitivul extern conectat prin portul serial
sau paralel n cadrul cruia se cunoate exact ordinea comenzilor i a
rspunsurilor ce sunt schimbate prin intermediul portului deschis. La fiecare
comand transmis se cunoate exact ce rspuns trebuie s soseasc de la
dispozitivul conectat. Dup fiecare comand transmis aplicaia ateapt
rspunsul de la dispozitivul cu care realizeaz comunicarea.

package commtest;
import javax.comm.*;
import java.io.*;

public class SincronCommunication {

static int TIMEOUTSECONDS = 5;


static int BAUD = 38400;
BufferedReader is;
PrintStream os;
SerialPort serialPort;

/** Creates a new instance of SincronCommunication */


public SincronCommunication(String port) throws Exception{

CommPortIdentifier thePort = CommPortIdentifier.getPortIdentifier(port);


CommPort communicationPort = thePort.open("Test app", TIMEOUTSECONDS * 1000);
serialPort = (SerialPort) communicationPort;

serialPort.setSerialPortParams(BAUD, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);

try {
is = new BufferedReader(new InputStreamReader((serialPort.getInputStream())));
} catch (IOException e) {
System.err.println("Can't open input stream: write-only");
}
os = new PrintStream(serialPort.getOutputStream(), true);
System.out.println("Ready to do read / write on port "+serialPort.getName());
}

public void send(String command){


os.print(command);
os.println("\r\n");
}

public boolean expect(String expected) throws IOException{


String response = is.readLine();
return response.indexOf(expected)>=0;
}
public void commProtocol() throws Exception{
// Send the reset command

send("MESSAGE 1");
if(!expect("OK 1"))
System.err.println("ERROR: Device has not sent back expected response.");
send("MESSAGE 2" );
if(!expect("OK 2"))
System.err.println("ERROR: Device has not sent back expected response.");

try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
is.close();
os.close();
}

public static void main(String[] args) throws Exception{


SincronCommunication sc = new SincronCommunication("COM12");
//start communication protocol
sc.commProtocol();
}
}

6.2 Scriere i citire n mod asincron

Comunicarea n mod asincron presupune c nu se cunoate exact n avans


ordinea n care au loc operaiile de scriere i de citire. n acest caz aplicaia va
trebui s poat sa fie notificat atunci cnd apare un eveniment pe portul
deshis. Pachetul Communication API ofer posibilitatea comunicaiei n mod
asincron folosind pentru aceasta ablonul de proiectare Observer \
Observable (sau altfel spus modelul orientat pe evenimente). Communication
API permite nregistrarea de obiecte de tip Observer (sau Listeners) care sunt
notificate n momentul n care un eveniment apare pe portul deschis.
package commtest;
import javax.comm.*;
import java.io.*;
/**
*
* @author mihai
*/
public class AsincronCommunicationEvents extends Thread implements SerialPortEventListener {
static int TIMEOUTSECONDS = 5;
static int BAUD = 38400;
BufferedReader is;
PrintStream os;
SerialPort serialPort;
/** Creates a new instance of AsincronCommunicationEvents */
public AsincronCommunicationEvents(String port) throws Exception {
CommPortIdentifier thePort = CommPortIdentifier.getPortIdentifier(port);
CommPort communicationPort = thePort.open("Test app", TIMEOUTSECONDS * 1000);
serialPort = (SerialPort) communicationPort;

serialPort.setSerialPortParams(BAUD, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);

try {
is = new BufferedReader(new InputStreamReader((serialPort.getInputStream())));
} catch (IOException e) {
System.err.println("Can't open input stream: write-only");
}
os = new PrintStream(serialPort.getOutputStream(), true);
System.out.println("Ready to do read / write on port "+serialPort.getName());
serialPort.notifyOnDataAvailable(true);
serialPort.addEventListener(this);
}

public void serialEvent(SerialPortEvent event) {


System.err.println("New event arrived.");
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:
try {
String response = is.readLine();
System.err.println("Response received:"+response);
} catch (IOException e) {}
break;
}
}

public void run(){


try {
//just wait for 20 seconds
Thread.sleep(20000);
} catch (InterruptedException ex) {ex.printStackTrace();}
}
public static void main(String[] args) throws Exception{
AsincronCommunicationEvents sc = new AsincronCommunicationEvents("COM12");
//start communication protocol
sc.start();
}
}
The Java Communications API: A Working
Example - By Rick Proctor
By: Rick Proctor

Abstract: A How-To on accessing serial ports in the Windows environment using the Java
Communications API

Introduction
In this article well discuss using the Java Communications API to access COM ports in
Windows. The following example is taken from a java program that reads barcodes from an
omni-directional scanner. It checks the barcode against a remote object and, based on the
results, sends codes to a PLC (program logic controller) to fire a diverter arm.

The Java Communications API


Sun provides an API extension for communicating with parallel and serial ports, specifically
for Solaris and Windows environments. The API can be found
athttp://java.sun.com/products/javacomm. There are also third party APIs and an open
source implementation from http://www.rxtx.org that works on several platforms including
Linux.

Using the API, you can create an object for each port (enumeration), open ports, resolve
port contention between Java objects, and perform asynchronous and synchronous
communications.

Installing the Java Communications API in a Windows


Environment
There are some tricks involved in getting the Java Communications API to correctly interact
with the Windows system. Among the items that you download from Sun are three very
important files:

comm.jar
win32com.dll

javax.comm.properties

For the JVM to recognize the serial ports, proper placement of these files is important. Ive
read lots of messages on the boards, tried various ways of placing these files in a Windows
system, and have found the following installation methods to be effective:

comm.jar should be placed in:


%JAVA_HOME%/lib

%JAVA_HOME%/jre/lib/ext

win32com.dll should be placed in:

%JAVA_HOME%/bin

%JAVA_HOME%/jre/bin

%windir%System32

javax.comm.properties should be placed in:

%JAVA_HOME%/lib

%JAVA_HOME%/jre/lib

Once youve done this, compile and execute one of the sample programs provided by Sun
to ensure that youve properly installed everything.

Installing the Java Communications API to run in JBuilder


Depending on how youve configured JBuilder, you may need to install the win32com.dll
and the javax.comm.properties files in their corresponding directories within the JVM
running under JBuilder. For example, I use the JVM that came with JBuilder 9 as well as an
external JVM I downloaded from Sun. To make JBuilder properly run the api, I placed the
winw32comm.dll and the javax.comm.properties file in their corresponding folders
underneath the path C:JBuilder9jdk1.4.

Next you need to add the comm.jar package to JBuilder. This is relatively simple. On the
JBuilder Menu across the top click on Project

Click on Project Properties:


Select the Required Libraries tab:
Click the add button:
Click on the New button and enter a name for your library and select the path to the Java
Communications API and click on the OK button:
Now youre ready to write your first program using the Java Communications API.

The Program
The example were going to use reads input from one serial port (COM4) and sends data to
another serial port (COM 5) (note: You do not have to use COM4 and COM5. Use any
available serial ports on your system.). Our program is named ComContol.

ComControl

package serialio;

//Sun's serial port driver


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

public class ComControl implements Runnable, SerialPortEventListener


{
static CommPortIdentifier portId1;
static CommPortIdentifier portId2;

InputStream inputStream;
OutputStream outputStream;
SerialPort serialPort1, serialPort2;
Thread readThread;
protected String divertCode = "10";
static String TimeStamp;

To access the comm.jar package we must first import javax.comm.*. We also import
java.io.* to gain access to the InputStream and OutputStream classes. Finally, we import
the java.util.* class to provide access to the EventListener class.

Notice that ComControl implements the Runnable interface. We implement the Runnable
interface because we want the class to run as a thread. There are two ways we could do
this. First, we could extend the Thread class. In doing so, we would have access to all of
public methods of Thread. Or, we could implement the Runnable interface. It provides a
single abstract method called run(). Using one or the other really depends on what were
doing. In this example were overriding the run() method and not any other methods of
Thread. A good rule of thumb is to implement Runnable when overriding the only run()
method, extend Thread to access its other methods.

Note: We didnt need to import a package for the Thread class because it is part of the
java.lang package.

ComControl also implements the SerialPortEventListener interface. Like other event


listeners, the SerialPortEventListener interface extends the EventListener interface (defined
in the java.util package). Without getting into too much detail, listeners use Javas
delegation model where events are treated as objects. The delegation model allows a
program to delegate event handling to a listener by registering the listener at runtime.
Whenever an event occurs for a particular listener, it is dispatched to all of the listeners
registered for it. The event is dispatched by calling a method of the corresponding event
interface.

We now need to set up some variables. Since were using two serial ports, we define the
objects portId1 and portId2 with a datatype of CommPortIdentifier. CommPortIdentifier is the
main class that controls access to serial ports. CommPortIdentifier is used to negotiate with
the driver to discover which communication ports are available and then select a port for
opening. It uses methods in other classes like CommPort and SerialPort to communicate to
the port.

We must also set up an InputStream (inputStream) to read the data coming through the
serial port and an OutputStream (outputStream) to send data to the serial port. The
InputStream class is part of the java.io package.

Next, we create some SerialPort objects: serialPort1 and SerialPort2. SerialPort is an


abstract class that defines the low-level interface to a RS-232 device such as a serial port. It
defines the minimum functionality needed to communicate with a serial port.

We define a Thread (readThread) because earlier we implemented the Runnable interface.


As a result, were going to instantiate a Thread object after weve taken care of some
housekeeping items.

main() method

public static void main(String[] args) {

try {
portId1 = CommPortIdentifier.getPortIdentifier("COM4");
portId2 = CommPortIdentifier.getPortIdentifier("COM5");
ComControl reader = new ComControl();
}

catch
(Exception e) {
TimeStamp = new java.util.Date().toString();
System.out.println(TimeStamp + ": COM4 " + portId1);
System.out.println(TimeStamp + ": COM5 " + portId2);
System.out.println(TimeStamp + ": msg1 - " + e);
}
};

Lets now take a look at the main() method. We start by putting everything in a try block. We
do this because it is possible that the serial ports were looking for do not exist or are busy.
Inside our try block we attempt to get a Handle for the serial ports (portId1 and portId2) by
executing the ComPortIdentifier.getPortIdentifer() method. This method returns a
ComPortIdentifier object and throws a NoSuchPortException if a particular port does not
exist. The last thing we do in the try block is instantiate ComControl using a constructor that
we will talk about in the following section.

After the try block, we have a catch block. In this example, were catching any Exception
that may occur. We could just have easily caught just the NoSuchPortException. The first
thing we do is load the current date and time into a string called TimeStamp. While its not
necessary to do this, it is useful if for logging to an external file.

Using System.out.println(), we display the port identifier objects for COM4 and COM5. We
want to see if either of the port identifier objects are nulla null value indicates that the
program could not find the port. Finally, we display the exception itself.

ComControl() Constructor

public ComControl() {

try {
TimeStamp = new java.util.Date().toString();
serialPort1 = (SerialPort) portId1.open("ComControl",
2000);
System.out.println(TimeStamp + ": " + portId1.getName()
+ " opened for scanner input");
serialPort2 = (SerialPort) portId2.open("ComControl",
2000);
System.out.println(TimeStamp + ": " + portId2.getName()
+ " opened for diverter output");

} catch (PortInUseException e) {}
try {
inputStream = serialPort1.getInputStream();
} catch (IOException e) {}
try {
serialPort1.addEventListener(this);
} catch (TooManyListenersException e) {}
serialPort1.notifyOnDataAvailable(true);
try {

serialPort1.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);

serialPort1.setDTR(false);
serialPort1.setRTS(false);

serialPort2.setSerialPortParams(9600,
SerialPort.DATABITS_7,
SerialPort.STOPBITS_1,
SerialPort.PARITY_EVEN);

} catch (UnsupportedCommOperationException e) {}

readThread = new Thread(this);


readThread.start();
}

We start the ComControl() constructor with a try block. In this case, we are instantiating
SerialPort objects (serialPort1 and serialPort2) by executing portId1s and portId2s open()
method. Recall portId1 and portId2 are ComPortIdentifier objects and the open() method
comes from ComPortIdentifier. It throws the PortInUseException. In our example, well
ignore this exception and go on. In the real world you would most likely want to handle this
exception.

The open() method were using in this example has two parameters. The first parameter is a
string containing the name of the application opening or owning the port. This parameter is
useful in resolving contention issues between programs. The next parameter is an int
containing the timeout in milliseconds that the open() method will wait for a port to open.

We have added a couple of System.out.println() methods that use our TimeStamp string
and a ComPortIdentifier.getName() method (portId1.getName() and portId2.getName()
where portId1 and portId2 are ComPortIdentifier objects). The getName() method returns
the system assigned name of the serial port. In our case this should be COM4 and COM5.

In order to check for incoming data on the serialPort1 object we just created, we need to call
its .getInputStream() method. Well see the results of this event later. The .getInputStream()
method throws an IOException. We want to ignore this because often the serial port will be
idle.

After weve opened the ports, we need to register an EventListener for COM4. Again we
create a try block and invoke the addEventListener() method within it. The exception for the
addEventListener is TooManyListenersExeception. In this case, thats not an issue so well
ignore the exception.

Next we define the properties of our serial ports using the setSerialPortParams() method.
This method allows us to set the flow control, data bits, parity, and stop bits. We are
concerned only with the Data bits, stop bits, and parity. The device that were using in this
case does not have the Data Terminal Ready (DTR) wire pinned out so well use the
serialPort1.setDTR() method to set DTR to false. Our input device doesnt support Request
To Send (RTS) handshaking either, well use the serialPort1.setRTS() method to set RTS to
false.

Note: The settings I use in this example apply to the serial devices Im connecting to. Your
serial devices may (probably) have completely different settings. Check with your device
manual for the proper settings.

The last thing we want to do is to create a Thread. This We define a Thread (readThread)
and execute its start() method.

run() method
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
}

As noted earlier, we implemented the Runnable interface. Now, we override the run()
method of that interface. Reviewing the code above youll see that were calling the
Thread.sleep() method within a trycatch block. The sleep() method is actually an
overloaded method within the Thread class. It can be passed either a long that represents
the time in milliseconds that you want the thread to cease execution, or it can be passed a
long and an int that represents the time in milliseconds plus the time in nanoseconds that a
thread will sleep. We want the thread to sleep for 100 milliseconds.

serialEvent() method

Now that weve built the code to create and start a SerialPortEventListener object
(ComControl), we need to do something when events occur. Thus, we override the
SerialPortEventListener interfaces abstract serialEvent() method. This method is executed
when a serial event occurs. It receives a SerialPortEvent object.

Lets take a look at the code.

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:
StringBuffer readBuffer = new StringBuffer();
int c;
try {
while ((c=inputStream.read()) != 10){
if(c!=13) readBuffer.append((char) c);
}
String scannedInput = readBuffer.toString();
TimeStamp = new java.util.Date().toString();
System.out.println(TimeStamp + ": scanned input
received:" + scannedInput);
inputStream.close();
if(scannedInput.substring(0,1).equals("F")){
outputStream = serialPort1.getOutputStream();
outputStream.write(divertCode.getBytes());
System.out.println(TimeStamp + ": diverter
fired");
outputStream.close();
} else {
System.out.println(TimeStamp + ": diverter not
diverted");
}
} catch (IOException e) {}

break;
}
}

Looking at the code youll see a set of case statements. We test these case statements by
using event.getEventType() method; where event is the object that was passed to the
serialEvent() method. The getEventType() method returns an int.

Although Ive defined several cases here, primarily to show you everything you can check
for in a serial event, in this example you and I are only interested in 2 events:
SerialPortEvent.OUTPUT_BUFFER_EMPTY and SerialPortEvent.DATA_AVAILABLE. In the
case of OUTPUT_BUFFER_EMPTY, we want to break out of the serialEvent method
altogether because weve finished receiving data. In the case of DATA_AVAILABLE, we
want examine the data coming from our serialPort1 object and, if its the data were looking
for, send data to our serialPort2 object.

If you refer back to the ComControl() constructor, youll see that we attempted to read bytes
into our static inputStream object using the serialPort1.getInputStream() method. In the
DATA_AVAILABLE case well interpret the bytes coming from the serialPort1 object. Weve
created a while block that reads each byte coming in from serialPort1 and tests to see
whether the byte is an ANSI character 10 (linefeed) or an ANSI character 13 (carriage
control). The reason we do this is because the input device is sending a carriage
control/linefeed at the end of each transmission. If the inputStream byte is anything other
than a carriage control/linefeed we want to store in our readBuffer object.

As soon as a carriage return/linefeed combination is encountered we break out of the while


block. Although we can deal with a Stringbuffer, depending on the situation my personal
preference is to use the toString() method in order to create a String object. We will create
String object is called scannedInput. And, because I like to see whats going on during
program execution, well write the info using System.out.println().

If the first character of the scannedInput string is an F then we want to send a signal to the
serialPort2 object. Serial port objects can be written to using OutputStream objects. First,
we obtain serialPort2s OutputStream by calling the getOutptStream() method. Previously
we created a String called divertCode that contains 10. In our example, a divertCode of
10 tells a Program Logic Controller (PLC) to fire a particular diverter. Since we want to
write this string to our serialPort2 object, we use the .write() method of the OutputStream
object outputStream. The write() method is looking for an array of byte datatypes, so we
have to convert the divertCode string to a byte array using the .getbBytes() method. After
weve written to serialPort2, we log the information and break out of the serialEvent method
and wait for the next serialEvent to occur.

You might also like