Java/Arduino - Read data from the Serial Port - java

I've got a program in Java where I have to read the information that an Arduino is sending.
I took the Java code from here. Now, I didn't really understand how it works, but I tried to modify it and I got this:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import java.util.Enumeration;
public class Serial implements SerialPortEventListener {
SerialPort serialPort;
private static final String PORT_NAMES[] = {
"/dev/tty.usbserial-A9007UX1", // Mac OS X
"/dev/ttyUSB0", // Linux
"COM3", // Windows
};
private BufferedReader input;
private static OutputStream output;
private static final int TIME_OUT = 2000;
private static final int DATA_RATE = 115200;
public void initialize() {
CommPortIdentifier portId = null;
Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
while (portEnum.hasMoreElements()) {
CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
for (String portName : PORT_NAMES) {
if (currPortId.getName().equals(portName)) {
portId = currPortId;
break;
}
}
}
if (portId == null) {
System.out.println("Could not find COM port.");
return;
}
try {
serialPort = (SerialPort) portId.open(this.getClass().getName(),TIME_OUT);
serialPort.setSerialPortParams(DATA_RATE, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
input = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
output = serialPort.getOutputStream();
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
}
catch (Exception e) {
System.err.println(e.toString());
}
}
public synchronized void serialEvent(SerialPortEvent oEvent) {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
String inputLine=input.readLine();
System.out.println(inputLine);
} catch (Exception e) {
System.err.println(e.toString());
}
}
}
public synchronized void close() {
if (serialPort != null) {
serialPort.removeEventListener();
serialPort.close();
}
}
public Serial(String ncom){
if(Integer.parseInt(ncom)>=3 && Integer.parseInt(ncom)<=9)
PORT_NAMES[2] = "COM" + ncom;
initialize();
Thread t=new Thread() {
public void run() {
try {Thread.sleep(1000000);} catch (InterruptedException ie) {}
}
};
t.start();
System.out.println("Serial Comms Started");
}
public synchronized void send(int b){
try{
output.write(b);
}
catch (Exception e) {
System.err.println(e.toString());
}
}
public synchronized int read(){
int b = 0;
try{
b = (int)input.read();
}
catch (Exception e) {
System.err.println(e.toString());
}
return b;
}
}
I create the object Serial with the COM port I need in the main program, then I use Serial.read and Serial.write when I need it.
Serial.write works great, Arduino gets the data and show it in a LCD Display. The problem is Serial.read. When the program is running, it keep read from serial port (around every 40 ms), but that doesn't mean Arduino sent something. Arduino sends a byte only when a button is pushed. So, when the Java code is running, it throws "n" Exception before read something, and this couses so much lag.
I know I need something like Serial.available(), I tried input.available(), but it doesn't work. I don't know how to solve this problem.
If you have a code that working, I'd be so much grateful if you could give it to me. I just need two methods, read and write, I don't care how the code works :D
EDIT:
I changed the Serial class, now it has again this method as apremalal said
public synchronized void serialEvent(SerialPortEvent oEvent) {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
String inputLine=null;
if (input.ready()) {
inputLine = input.readLine();
panel.read(inputLine);
}
} catch (Exception e) {
System.err.println(e.toString());
}
}
}
and in the other class (Panel in this case) I've got this:
public void read(String data){
System.out.println(data);
System.out.println(data == "255");
if(data == "255")
//code here
}
It print the values correctly but data == "255" is always false, even if I really get a 255
....I tried to do Integer.parseInt but nothing changed. Why the hell?
EDIT 2: Ok solved :\
public void read(String data){
serialRead = Integer.parseInt(data);
if(serialRead == 255)
//code here
}
Now it's work..don't know why I had to do this... meh whatever :)

You don't want to specifically write a read function it's already there in the sample code.As TheMerovingian pointed out you can check the input Buffer before reading.Here is the working code which I have used in one of my projects.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import java.util.Enumeration;
public class SerialTest implements SerialPortEventListener {
SerialPort serialPort;
/** The port we're normally going to use. */
private static final String PORT_NAMES[] = { "/dev/tty.usbserial-A9007UX1", // Mac OS X
"/dev/ttyUSB0", // Linux
"COM35", // Windows
};
private BufferedReader input;
private OutputStream output;
private static final int TIME_OUT = 2000;
private static final int DATA_RATE = 9600;
public void initialize() {
CommPortIdentifier portId = null;
Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
//First, Find an instance of serial port as set in PORT_NAMES.
while (portEnum.hasMoreElements()) {
CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
for (String portName : PORT_NAMES) {
if (currPortId.getName().equals(portName)) {
portId = currPortId;
break;
}
}
}
if (portId == null) {
System.out.println("Could not find COM port.");
return;
}
try {
serialPort = (SerialPort) portId.open(this.getClass().getName(),
TIME_OUT);
serialPort.setSerialPortParams(DATA_RATE,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
// open the streams
input = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
output = serialPort.getOutputStream();
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
} catch (Exception e) {
System.err.println(e.toString());
}
}
public synchronized void close() {
if (serialPort != null) {
serialPort.removeEventListener();
serialPort.close();
}
}
public synchronized void serialEvent(SerialPortEvent oEvent) {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
String inputLine=null;
if (input.ready()) {
inputLine = input.readLine();
System.out.println(inputLine);
}
} catch (Exception e) {
System.err.println(e.toString());
}
}
// Ignore all the other eventTypes, but you should consider the other ones.
}
public static void main(String[] args) throws Exception {
SerialTest main = new SerialTest();
main.initialize();
Thread t=new Thread() {
public void run() {
//the following line will keep this app alive for 1000 seconds,
//waiting for events to occur and responding to them (printing incoming messages to console).
try {Thread.sleep(1000000);} catch (InterruptedException ie) {}
}
};
t.start();
System.out.println("Started");
}
}
EDIT : serialEvent function is responsible for reading the buffer.
public synchronized void serialEvent(SerialPortEvent oEvent) {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
String inputLine=null;
if (input.ready()) {
inputLine = input.readLine();
System.out.println(inputLine);
}
} catch (Exception e) {
System.err.println(e.toString());
}
}
// Ignore all the other eventTypes, but you should consider the other ones.
}

The BufferedReader class has a ready() method that returns True if "the buffer is not empty, or if the underlying character stream is ready." and False otherwise. So you could add a check in the read() method to make sure there is data to be read before trying to read.
public synchronized int read(){
int b = 0;
try{
if (input.ready()) {
b = (int)input.read();
}
}catch (Exception e) {
System.err.println(e.toString());
}
return b;
}
It looks like the code has a try-catch in place to handle if those things fail, which is possibly what causes your lag because try-catch are quite expensive. So the input.ready() check should result in fewer exceptions.

Related

JVM Closing with Java result 255 error

I write a Java code to receive data from arduino using RXTX Library through COM ports. When Java receiving and printing it in the console if the arduino suddenly removed then JVM closing with error JAVA Result 255. how to catch that error.When arduino suddenly removed it should print "device removed".
package arduino.recieve;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.TooManyListenersException;
public class NewClass implements SerialPortEventListener {
SerialPort serialPort = null;
private static final String PORT_NAMES[] = {
// "/dev/tty.usbmodem", // Mac OS X
// "/dev/usbdev", // Linux
// "/dev/tty", // Linux
// "/dev/serial", // Linux
"COM3"};
private String appName;
private BufferedReader input;
private OutputStream output;
private static final int TIME_OUT = 1000; // Port open timeout
private static final int DATA_RATE = 9600; // Arduino serial port
public boolean initialize() {
try {
CommPortIdentifier portId = null;
Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
// Enumerate system ports and try connecting to Arduino over each
//
System.out.println("Trying:");
while (portId == null && portEnum.hasMoreElements()) {
// Iterate through your host computer's serial port IDs
//n2
CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
System.out.println(" port" + currPortId.getName());
for (String portName : PORT_NAMES) {
if (currPortId.getName().equals(portName)
|| currPortId.getName().startsWith(portName)) {
// Try to connect to the Arduino on this port
//
// Open serial port
serialPort = (SerialPort) currPortId.open(appName, TIME_OUT);
portId = currPortId;
System.out.println("Connected on port" + currPortId.getName());
break;
}
}
}
if (portId == null || serialPort == null) {
System.out.println("Oops... Could not connect to Arduino");
return false;
}
// set port parameters
serialPort.setSerialPortParams(DATA_RATE,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
// add event listeners
try {
serialPort.addEventListener(this);
} catch (TooManyListenersException e) {
{
System.out.println(" Too Many Listeners ");
}
}
serialPort.notifyOnDataAvailable(true);
// Give the Arduino some time
try {
Thread.sleep(2000);
} catch (InterruptedException ie) {
}
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
//
// Handle serial port event
//
public synchronized void serialEvent(SerialPortEvent oEvent) {
try {
switch (oEvent.getEventType()) {
case SerialPortEvent.DATA_AVAILABLE:
if (input == null) {
input = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
}
String inputLine = input.readLine();
System.out.println(inputLine);
break;
default:
break;
}
} catch (Exception e) {
System.out.println("Hello");
}
}
public static void main(String[] args) throws Exception {
NewClass test = new NewClass();
test.initialize();
}
}
There are several other event types generated by the serial port that you could maybe try and detect to see if one happens when the arudino gets disconnected. Unfortunately, it doesn't look like there is a DTR event which would probably be the best indicator that something has gone wrong, but the SerialPort class does have an isDTR() method. You could be checking that periodically and if that goes false, then it probably means you've lost the connection to the arduino. You could maybe do that check in a separate thread, or perhaps on every CTS change event.
serialPort.notifyOnDataAvailable(true);
serialPort.notifyOnCTS(true);
...
switch (oEvent.getEventType()) {
case SerialPortEvent.DATA_AVAILABLE:
if (input == null) {
input = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
}
String inputLine = input.readLine();
System.out.println(inputLine);
break;
case SerialPortEvent.CTS:
if (!serialPort.isDTR()) {
// do something
}
break;
default:
break;
}
Probably having a small worker thread that just checks DTR status would be a better solution though.

sending integers from Java to Arduino uno on serial port

I have an issue in my serial communication between Java and arduino board, arduino can send Java bytes and Java is able to print them, Java is taking them as inputs. My problem is when I tend to use the serial port as an output for Java to send java with streams (Buffered, dataoutput...), and no byte is received by Arduino, and this is verified because i asked Arduino to send the bytes received and the it's always zero.can anyone give an advice? appreciate it.
My java code is the following:
package Arduino;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;
import java.util.Enumeration;
public class SerialClass implements SerialPortEventListener {
public static int ch = 2;
public SerialPort serialPort;
/** The port we're normally going to use. */
private static final String PORT_NAMES[] = {
"/dev/tty.usbserial-A9007UX1", // Mac OS X
"/dev/ttyUSB0", // Linux
"COM19", // Windows
};
public static BufferedReader input;
public static BufferedWriter output;
//public static BufferedOutputStream out= new BufferedOutputStream(output);
//public static DataOutputStream data= new DataOutputStream(out);
/** Milliseconds to block while waiting for port open */
public static final int TIME_OUT = 2000;
/** Default bits per second for COM port. */
public static final int DATA_RATE = 9600;
public void initialize() {
CommPortIdentifier portId = null;
Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
//First, Find an instance of serial port as set in PORT_NAMES.
while (portEnum.hasMoreElements()) {
CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
for (String portName : PORT_NAMES) {
if (currPortId.getName().equals(portName)) {
portId = currPortId;
break;
}
}
}
if (portId == null) {
System.out.println("Could not find COM port.");
return;
}
try {
// open serial port, and use class name for the appName.
serialPort = (SerialPort) portId.open(this.getClass().getName(),
TIME_OUT);;
// set port parameters
serialPort.setSerialPortParams(DATA_RATE,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
// open the streams
input = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
output= new BufferedWriter(new OutputStreamWriter(serialPort.getOutputStream()));
// add event listeners
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
serialPort.notifyOnOutputEmpty(true);
} catch (Exception e) {
System.err.println(e.toString());
}
}
public synchronized void close() {
if (serialPort != null) {
serialPort.removeEventListener();
serialPort.close();
System.out.println("port closed");
}
}
public static synchronized void writeData() {
System.out.println("I'm in...");
try {
output.write(ch);
output.close();
System.out.println("Sent: " + ch);
} catch (Exception e) {
System.out.println("could not write to port");
}
}
public synchronized void serialEvent(SerialPortEvent oEvent) {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
String inputLine=input.readLine();
// input.close();
System.out.println(inputLine);
} catch (Exception e) {
System.err.println(e.toString());
}
}
}
public static void main(String[] args) throws Exception {
SerialClass main = new SerialClass();
main.initialize();
SerialClass.writeData();
}
}
My arduino code is:
byte valeur;
int val;
int led = 13;
char buffer[10];
void setup()
{
Serial.begin(9600);
pinMode(led, OUTPUT);
}
void loop(){
delay(10000);
//val= Serial.parseInt();
//Serial.println( val );
if ( Serial.available ()) {
Serial.println("In if");
Serial.readBytes( buffer , 10 );
//val = valeur - '0';
//Serial.println( val ) ;
Serial.println( buffer[0] , DEC ) ;
if( buffer[0] == 2 ) { //Switch on the LED, if the received value is 1.
Serial.println("Val = 2");
digitalWrite(led, HIGH);
}
else if( buffer[0] == 1) { //Switch off the LED, if the received value is 1.
Serial.println("Val = 1");
digitalWrite(led, LOW);
}
}
else{
Serial.readBytes( buffer , 10 );
Serial.println( buffer[0] , DEC ) ;
Serial.println( "No data Available" );
}
// Serial.println("Succesfully received.");
}
and the result in java is (after uploading the arduino code to arduino uno):
I'm in...
Sent: 2
0
No data Available
I managed to send a char to arduino by using jserialcomm library. The method looks like this:
// imports I make in my class
import javax.swing.*;
import java.awt.FlowLayout;
import java.awt.event.*;
import com.fazecast.jSerialComm.*;
import java.io.PrintWriter;
code in method
System.out.println("connect");
port = SerialPort.getCommPort("COM5"); // change if different
port.setComPortTimeouts(SerialPort.TIMEOUT_SCANNER,0,0);
port.openPort();
//port.setBaudRate(9600);
System.out.println(port.getBaudRate());
try {Thread.sleep(600); } catch(Exception e) {} // I think this sleep is a must until it opens
System.out.println(port.isOpen());
if(port.isOpen()) {
System.out.println("port open!");
try {Thread.sleep(500); } catch(Exception e) {}
PrintWriter output = new PrintWriter(port.getOutputStream());
output.write(2);
try {Thread.sleep(800); } catch(Exception e) {}
output.flush();
System.out.println("char sent");
try {Thread.sleep(600); } catch(Exception e) {}
port.closePort();
}
}
else {
// disconnect from the serial port
//port.closePort();
}
}

Read and Write from serial port in java without listener event

I want to read bytes from the serial port and write to it sequentially.Is there any way i can read and write from/to the serial port by creating two separate functions for read and write in java?.I wrote a program but here,serialPort.getInputStream() is giving a null pointer exception even after opening the desired COM port.
This is my code
package PhyCom;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.TooManyListenersException;
import javax.comm.CommPortIdentifier;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;
import javax.comm.UnsupportedCommOperationException;
import javax.xml.bind.DatatypeConverter;
public class COMConnect_DLMS
{
public static InputStream inputStream;
public static OutputStream outputStream;
SerialPort serialPort;
public long baudRate=19200;
public int dataBits=SerialPort.DATABITS_8;
public int stopBits=SerialPort.STOPBITS_1;
public int parity=SerialPort.PARITY_NONE;
boolean portFound = false;
String defaultPort="COM1";
static Enumeration portList ;
public static CommPortIdentifier portId;
public COMConnect_DLMS()
{
initialize();
}
private void initialize()
{
System.out.println("Establishing connection to UART");
portList = CommPortIdentifier.getPortIdentifiers();
while (portList.hasMoreElements())
{
portId = (CommPortIdentifier) portList.nextElement();
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL)
{
if (portId.getName().equals(defaultPort))
{
System.out.println("Found port: "+defaultPort);
portFound = true;
}
}
}
try
{
serialPort = (SerialPort) portId.open("SimpleReadApp", 2000);
}
catch (PortInUseException e) {}
System.out.println(portId.getName());
try
{
inputStream=serialPort.getInputStream();
}
catch (IOException e) {e.printStackTrace();}
/*try
{
serialPort.addEventListener((SerialPortEventListener) this);
}
catch(TooManyListenersException e){}
serialPort.notifyOnDataAvailable(true);*/
try
{
// set port parameters
serialPort.setSerialPortParams((int) baudRate, dataBits,stopBits,parity);
}
catch (UnsupportedCommOperationException e) {}
try
{
outputStream=serialPort.getOutputStream();
}
catch (IOException e) {}
}
public void serialEvent(SerialPortEvent event)
{
if(event.getEventType()==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);}
}
}
public static void writePacket(byte[] msg)
{
System.out.println("Writing \""+DatatypeConverter.printHexBinary(messageString));
try
{
// write string to serial port
outputStream.write(msg);
// System.out.println("written");
}
catch (IOException e) {}
}
}
And also I want to more about NullPointerException in case of serial ports.Thank you.Your suggestions will be appreciated.
Well, this is a bit of an issue:
try {
serialPort = (SerialPort) portId.open("SimpleReadApp", 2000);
} catch (PortInUseException e) {
}
You've got an empty catch block if, for whatever reason, you can't open that specific port. Worse, you're not reporting what happened, or why it decided to fail connecting.
But this is what's breaking you. You ignore any errors that happen with your serialPort variable and leave it set to null. It's initialized this way as a field.
If you fail to get an instance from your call, then you shouldn't continue. Consider either:
Placing a System.exit(1) call in your catch block to indicate that your program cannot continue, or
(Better option) Wrap everything in that initialize method that has to do with serialPort in your try...catch.

Reading from a port in Java

Here is the scenario:
1. I have a GSM modem which is connected to my computer, It's working I can read and send SMS via the built-in program.
2. The port assign to my gsm modem is COM11 . I saw it from DeviceManager -> modems -> myModem-> Advance -> AdvancePortSettings.
3. I write the Java code to read incomming message.
The code is as follows:
public class PScanner implements SerialPortEventListener, Runnable {
CommPortIdentifier pid = null;
SerialPort sp;
BufferedReader input;
OutputStream output;
public PScanner() {
try {
Enumeration e = CommPortIdentifier.getPortIdentifiers();
while (e.hasMoreElements()) {
CommPortIdentifier cpi = (CommPortIdentifier) e.nextElement();
if (cpi.getName().equals("COM11")) {
pid = cpi;
break;
}
}
sp = (SerialPort) pid.open(getClass().getName(), 2000);
sp.setSerialPortParams(115200, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
InputStream is = sp.getInputStream();
input = new BufferedReader(new InputStreamReader(is));
output = sp.getOutputStream();
sp.addEventListener(this);
sp.notifyOnDataAvailable(true);
new Thread(this).start();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public synchronized void serialEvent(SerialPortEvent oEvent) {
System.out.println("serialEvent CallBack");
}
public synchronized void close() {
if (sp != null) {
sp.removeEventListener();
sp.close();
}
}
#Override
public void run() {
try {
Thread.sleep(20000);
} catch (InterruptedException ex) {
Logger.getLogger(PScanner.class.getName()).log(Level.SEVERE, null, ex);
} finally {
System.out.println("done");
}
}
}
When I send an SMS on the GSM modem, I am not getting in serialEvent() call back method.
Do anyone know what is going on? I am not getting any error or exceptions.
This isn't a definitive answer, but your code has made several question marks appear above my head.
To answer why you're not getting anything in the method listening on the SerialEvent, it might be that you are adding the listener after the event has happened.
Try moving sp.addEventListener(this); further up, just after 'pid.open'.
However think a bit about what the thread is doing. All your code is in the constructor of your class, then at the end of the constructor, after everything has happened, you call thread.start(), so none of your code is running in a separate thread. Your run method actually does nothing except send the thread to sleep after everything has happened.
Move all your code from the constructor to the run() method if you want it to run in a separate thread.
The following code , is to send and read message using a GSM module, this may help you
import java.sql.*;
import java.io.*;
import java.util.*;
import java.text.*;
import gnu.io.*;
public class SerialComm implements SerialPortEventListener
{
int result=0;
static CommPortIdentifier portId=null;
Enumeration portList=null;
static InputStream inputStream=null;
static OutputStream out=null;
static SerialPort serialPort=null;
static int srate=9600;//B-Rate
String data=null;
int i=0;
String number="";
int status=0;
public String recvdData="aa";
String pswd="";
String actualpswd="";
public static void main(String args[])
{
SerialComm obj=new SerialComm();
}
public SerialComm()
{
try
{
if(this.detectPort())
{
if(this.initPort())
{
//Thread.sleep(2000);
// sendMessage();
}
}
}
catch(Exception e)
{
System.out.println("Error in SerialComm()-->"+e);
}
}
public boolean detectPort()
{
boolean portFound = false;
//String defaultPort = "/dev/ttyUSB0";
String defaultPort = "COM1";
try
{
portList = CommPortIdentifier.getPortIdentifiers();
while (portList.hasMoreElements())
{
CommPortIdentifier portID = (CommPortIdentifier) portList.nextElement();
if (portID.getPortType() == CommPortIdentifier.PORT_SERIAL)
{
if (portID.getName().equals(defaultPort))
{
this.portId=portID;
System.out.println("Found port: "+portId.getName());
portFound = true;
break;
}
}
}
if (!portFound)
{
System.out.println("port " + defaultPort + " not found.");
}
}
catch(Exception e)
{
portFound = false;
}
return portFound;
}
public boolean initPort()
{
try
{
serialPort = (SerialPort) portId.open("SerialCommApp", 2000);
}
catch (PortInUseException e)
{
System.out.println("Port in use-->"+e);
}
try
{
inputStream = serialPort.getInputStream();
out=serialPort.getOutputStream();
}
catch (IOException e)
{
System.out.println("IO Error-->"+e);
}
try
{
serialPort.addEventListener(this);
}
catch (TooManyListenersException e)
{
System.out.println("Too many LIstener-->"+e);
}
serialPort.notifyOnDataAvailable(true);
try
{
serialPort.setSerialPortParams(srate, SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN | SerialPort.FLOWCONTROL_RTSCTS_OUT);
}
catch (UnsupportedCommOperationException e)
{
System.out.println("Error while setting parameters-->"+e);
}
System.out.println("Port Initialized....");
return true;
}
public synchronized void serialEvent(SerialPortEvent event)
{
switch (event.getEventType())
{
case SerialPortEvent.DATA_AVAILABLE:
System.out.println("DATA_AVAILABLE");
byte[] readBuffer = new byte[1024];
int numBytes=1024;
data="";
try
{
Thread.sleep(100);
while (inputStream.available() > 0)
{
numBytes = inputStream.read(readBuffer);//count of reading data
data=data+new String(readBuffer,0,numBytes);
data=data.trim();
this.recvdData+=data;
}
System.out.println("data=========="+this.recvdData);
}
catch (Exception e)
{
System.out.println("Exception in serial event-->"+e);
}
break;//break from switch case 1:
}//end of switch
}
Method to read Message
public void sendMessage(String num, String msg) {
try{
System.out.println("Sending Message");
this.recvdData="";
String dq=String.valueOf((char)34);
String mysms="AT+CMGS="+dq+num+dq;
out.write(mysms.getBytes());
out.write(13);
Thread.sleep(500);
mysms=msg;
out.write(mysms.getBytes());
out.write(26);
out.write(13);
Thread.sleep(500);
if(this.recvdData.contains("OK"))
{
return;
}else if(this.recvdData.contains(">")){
out.write(26);
out.write(13);
sendMessage(num,msg);
}else{
sendMessage(num,msg);
}
return;
}catch(Exception e){
System.out.println(e);
}
}
Check these code, i got the output by using this code,

java rxtx SerialWriter issue

I am using RXTX to communicate between JAVA and a microcontroller.
This is the JAVA code for opening a connection, sending and receiving data
package app;
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class SerialCommunication1 {
private static SerialCommunication1 instance = null;
private static boolean coonected = false;
public static SerialCommunication1 getInstance(){
if(instance == null)
instance = new SerialCommunication1();
return instance;
}
private SerialCommunication1() {
super();
try {
connect("COM4");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SerialCommunication1.coonected = true;
}
void connect(String portName) throws Exception {
CommPortIdentifier portIdentifier = CommPortIdentifier
.getPortIdentifier(portName);
if (portIdentifier.isCurrentlyOwned()) {
System.out.println("Error: Port is currently in use");
} else {
CommPort commPort = portIdentifier.open(this.getClass().getName(),
2000);
if (commPort instanceof SerialPort) {
SerialPort serialPort = (SerialPort) commPort;
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8,
SerialPort.STOPBITS_2, SerialPort.PARITY_NONE);
InputStream in = serialPort.getInputStream();
OutputStream out = serialPort.getOutputStream();
(new Thread(new SerialReader(in))).start();
(new Thread(new SerialWriter(out))).start();
} else {
System.out
.println("Error: Only serial ports are handled by this example.");
}
}
}
/** */
public static class SerialReader implements Runnable {
InputStream in;
public SerialReader(InputStream in) {
this.in = in;
}
public void run() {
byte[] buffer = new byte[1024];
int len = -1;
try {
while ((len = this.in.read(buffer)) > -1) {
System.out.print(new String(buffer, 0, len));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/** */
public static class SerialWriter implements Runnable {
OutputStream out;
static String str = null;
public SerialWriter(OutputStream out) {
this.out = out;
}
public void run() {
System.out.println("Will try to execute");
try {
if(str.length() > 0){
this.out.write(str.getBytes());
str = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
And this is the Java code that is calling when an event triggers
SerialCommunication1.getInstance();
if(ledStatus == true) {SerialCommunication1.SerialWriter.str = "4A01";}
else {SerialCommunication1.SerialWriter.str = "4A00";}
stopProcess();
And now the problem. I need to send a command to my microcontroller with the code 4A01 and, after receiving the answer, I need to call it again with the code 4A00. The calls are triggered by a button from my Java interface. The problem is that the second call is not executed (4A00 is not sending). I tried to inverse the command codes and they work well. After the first one (4A01) is executed, my microcontroller reacts and sends the response which is read by java and my interface is updated. When I send the invers command (4A00) it stops exactly at this line SerialCommunication1.SerialWriter.str = "4A00"; and doesn't even enter inside the SerialWriter's run() method.
Do you have any idea why is this happening? From the side of my microcontroller there is no problem, I checked all the possibilities with a tool.
I hope I made myself clear.
Thank you!
LE: I forgot to tel you that it didn't throw any errors or exceptions
I'm not sure because I'm not able to test your code but I think your problem is in SerialWriter class:
public static class SerialWriter implements Runnable {
OutputStream out;
static String str = null; // Here str is initialized to null
public SerialWriter(OutputStream out) {
this.out = out;
}
public void run() {
System.out.println("Will try to execute");
try {
if(str.length() > 0) { // this should throw NPE because str is null
this.out.write(str.getBytes());
str = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Since there is no loop in this method, then the thread created within SerialCommunication1 at this line:
(new Thread(new SerialWriter(out))).start();
most likely finishes its execution after sending the first str.
Honestly I don't understand how does it even send a single string, since str is initialized to null in first place and it should throw NullPointerException at str.length() line.
I would suggest you this approach:
Don't trigger a writer thread when connection is established, just trigger a new one every time a message will be sent.
Use Singleton pattern correctly.
Keep a reference to the serial port in SerialCommunication1 class.
Translated to code it would be something like this:
class SerialWriter implements Runnable {
OutputStream out;
String message;
public SerialWriter(OutputStream out) {
this.out = out;
}
public void setMessage(String msg) {
this.message = msg;
}
public void run() {
try {
if(message != null) {
this.out.write(str.getBytes());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Then in SerialCommunication1 class add this public method:
public void sendMessage(String msg) {
SerialWriter writer = new SerialWriter(serialPort.getOutputStream()); // of course you'll have to keep reference to serialPort when connection is established
writer.setMessage(msg);
(new Thread(writer)).start();
}
And finally call this method in this way:
SerialCommunication1.getInstance().sendMessage("4A01");
tzortzik,
I think tha is a timeout problem. Try to addding a delay to writer :
/** */
public static class SerialWriter implements Runnable {
OutputStream out;
static String str = null;
public SerialWriter(OutputStream out) {
this.out = out;
}
public void run() {
Thread.sleep(500); //<----------- this should be in mainThread before to SerialWriter.start();
System.out.println("Will try to execute");
try {
if(str.length() > 0){
this.out.write(str.getBytes());
str = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
It happens to me many times, "we should learn to wait for a response" (^_^)
Check if you are executing well a secuence like the next:
Send command 4A01
Receive response 4A01 from micro
WAIT FOR RESPONSE BEFORE SEND SECOND COMMAND. Thread.sleep(500); //wait for 500 milis or more
Send command 4A00
Receive response 4A00 from micro
I hope it could help you.

Categories

Resources