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.
Related
I am trying to execute the program on Linux , raspberry pi and getting error
Could not find or load main class SerialTestGET.
the program:
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;
import java.net.HttpURLConnection;
import java.net.URL;
public class SerialTestGET implements SerialPortEventListener {
SerialPort serialPort;
static int sensorValue = 0;
/** The port we're normally going to use. */
private static final String PORT_NAMES[] = {
"/dev/tty.usbserial-A9007UX1",
// Mac OS X
"/dev/ttyACM0",
// Raspberry Pi
"/dev/ttyUSB0",
// Linux
"COM3",
// Windows
};
/**
* A BufferedReader which will be fed by a InputStreamReader
* converting the bytes into characters
* making the displayed results codepage independent
*/
private BufferedReader input;
/** The output stream to the port */
private OutputStream output;
/** Milliseconds to block while waiting for port open */
private static final int TIME_OUT = 2000;
/** Default bits per second for COM port. */
private static final int DATA_RATE = 9600;
public void initialize() {
// the next line is for Raspberry Pi and
// gets us into the while loop and was suggested here was suggested
//http://www.raspberrypi.org/phpBB3/viewtopic.php?f=81&t=32186
System.setProperty("gnu.io.rxtx.SerialPorts", "/dev/ttyACM0");
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 = serialPort.getOutputStream();
// add event listeners
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
} catch(Exception e) {
System.err.println(e.toString());
}
}
/**
* This should be called when you stop using the port.
* This will prevent port locking on platforms like Linux.
*/
public synchronized void close() {
if (serialPort != null) {
serialPort.removeEventListener();
serialPort.close();
}
}
/**
* Handle an event on the serial port. Read the data and print it.
*/
public synchronized void serialEvent(SerialPortEvent oEvent) {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
String inputLine = input.readLine();
//System.out.println(inputLine);
sendGet(inputLine);
} catch(Exception e) {
System.err.println(e.toString());
serialPort.removeEventListener();
serialPort.close();
}
}
// Ignore all the other eventTypes, but you should consider the other ones.
}
// HTTP GET request
public void sendGet(String inputLine) throws Exception {
try {
//if difference is more than 3 then send data to SAP HANA
if (inputLine != null && inputLine.length() > 0 && Math.abs(sensorValue - Integer.parseInt(inputLine)) > 3) {
sensorValue = Integer.parseInt(inputLine);
//Considering that A001 sensor is connection with this raspberry pie for now
//we can even pass this with command line but for simplicityhardcoding it
//Replace with your HANA server URL and port number
String url = " ";
url = url + inputLine;
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// optional default is GET
con.setRequestMethod("GET");
//add request header
//con.setRequestProperty("User-Agent", USER_AGENT);
int responseCode = con.getResponseCode();
if (responseCode == 200) {
System.out.println("OK value:" + inputLine);
} else {
System.out.println("Error: Response code " + responseCode);
}
}
System.out.println("OK value: Less than 3");
} catch(Exception e) {
System.err.println(e.toString());
serialPort.removeEventListener();
serialPort.close();
}
}
public static void main(String[] args)
throws Exception {
SerialTestGET main = new SerialTestGET();
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");
}
}
all files are placed in the required folder
I am running the file from the path java file is located.
What I wish to do:
Read Serial.println from my Arduino(COM3) without majoy delay in time
What my situation is:
This Java program delays roughly 20 seconds in Serial input.
This has been achieved by the Arduino IDE Serial monitor. I wanted to embed the serial monitor code into my Java application.
Following attaches useful code (This program is supposed to be ran on a computer receiving Serial.):
package arduino;
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[] = {"COM3"};
/**
* A BufferedReader which will be fed by a InputStreamReader
* converting the bytes into characters
* making the displayed results codepage independent
*/
private BufferedReader input;
/** The output stream to the port */
private OutputStream output;
/** Milliseconds to block while waiting for port open */
private static final int TIME_OUT = 2000;
/** Default bits per second for COM port. */
private static final int DATA_RATE = 50000;
public void initialize() {
// the next line is for Raspberry Pi and
// gets us into the while loop and was suggested here was suggested http://www.raspberrypi.org/phpBB3/viewtopic.php?f=81&t=32186
//System.setProperty("gnu.io.rxtx.SerialPorts", "/dev/ttyACM0");
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 = serialPort.getOutputStream();
// add event listeners
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
} catch (Exception e) {
System.err.println(e.toString());
}
}
/**
* This should be called when you stop using the port.
* This will prevent port locking on platforms like Linux.
*/
public synchronized void close() {
if (serialPort != null) {
serialPort.removeEventListener();
serialPort.close();
}
}
/**
* Handle an event on the serial port. Read the data and print it.
*/
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");
}
}
Following attaches useful code supposed to ran on Arduino, involves using arcade joystick. I tested it without problems in Serial Monitor, just thought I would attach it in.
/*
The Joystick Adapter to Snake Display
Joystick connected to DIGITAL port 5 - 2
*/
//Define pins
const int joyA = 5;
const int joyB = 4;
const int joyC = 3;
const int joyD = 2;
//Begin.
void setup(){
pinMode(joyA,INPUT);
pinMode(joyB,INPUT);
pinMode(joyC,INPUT);
pinMode(joyD,INPUT);
Serial.begin(9600);
}
void loop(){
boolean a = isaxisPressed(joyA);
boolean b = isaxisPressed(joyB);
boolean c = isaxisPressed(joyC);
boolean d = isaxisPressed(joyD);
if(a){
Serial.println("A");
}else if(b){
Serial.println("B");
}else if(c){
Serial.println("C");
}else if(d){
Serial.println("D");
}else{
Serial.println("Z");
}
}
boolean isaxisPressed(int port){
pinMode(port,OUTPUT);
digitalWrite(port,HIGH);
pinMode(port,INPUT);
return !digitalRead(port);
}
I am trying to connect to my serial port "COM6", but now I cannot connect to it. I tried printing out the list of serial ports available using portId.getName(). It shows a list of serial ports available but COM6 is not showing there.
This is my Java code:
portList = CommPortIdentifier.getPortIdentifiers();
while (portList.hasMoreElements()) {
portId = (CommPortIdentifier) portList.nextElement();
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
if (portId.getName().equals("COM6")) {
//if (portId.getName().equals("/dev/term/a")) {
try {
serialPort = (SerialPort)
portId.open("Arduino", 2000);
} catch (PortInUseException e) {
System.out.println("Error1 is "+ e);
}
try {
outputStream = serialPort.getOutputStream();
} catch (IOException e) {
System.out.println("Error2 is "+ e);
}
try {
serialPort.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException e) {
System.out.println("Error3 is "+ e);
}
try{
byte data1 = 1;
outputStream.write(data1);
System.out.println("helo");
System.out.println(data1);
}catch(IOException e){
System.out.println("Error 3: " + e);
}
}
}
}
serialPort.close();
I have checked the COM6 in my device manager. It shows available. If I run the same com port in vb it works perfectly. Can anyone help me with this problem. Thank you.
I guess you are trying to communicate with an Arduino? If so, you have to install the Arduino IDE - there is also the RXTX library included, which is very similar to the Java Communication API.
Then you can try this code, which is very similar to yours:
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/ttyACM0", // Raspberry Pi
"/dev/ttyUSB0", // Linux
"COM3", // Windows
};
/**
* A BufferedReader which will be fed by a InputStreamReader
* converting the bytes into characters
* making the displayed results codepage independent
*/
private BufferedReader input;
/** The output stream to the port */
private OutputStream output;
/** Milliseconds to block while waiting for port open */
private static final int TIME_OUT = 2000;
/** Default bits per second for COM port. */
private static final int DATA_RATE = 9600;
public void initialize() {
// the next line is for Raspberry Pi and
// gets us into the while loop and was suggested here was suggested http://www.raspberrypi.org/phpBB3/viewtopic.php?f=81&t=32186
System.setProperty("gnu.io.rxtx.SerialPorts", "/dev/ttyACM0");
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 = serialPort.getOutputStream();
// add event listeners
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
} catch (Exception e) {
System.err.println(e.toString());
}
}
/**
* This should be called when you stop using the port.
* This will prevent port locking on platforms like Linux.
*/
public synchronized void close() {
if (serialPort != null) {
serialPort.removeEventListener();
serialPort.close();
}
}
/**
* Handle an event on the serial port. Read the data and print it.
*/
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());
}
}
// 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");
}
}
The code comes from the Arduino Playground, I'm not able to try it out now, but I connected an Arduino two or three months ago with this code (Windows 8, 64Bit). There are also other methods described in the post, as well as all necessary requirements (e.g. classpath variables) - check them out in your system setting.
Hope it helps.
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();
}
}
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.