Help with JAVA RXTX Connect to COM

Hello everyone,

I recently tried to create an application that can send code via the serial port to my arduino. Sadly the code doesn't work. I have two seperate JAVA classes: one is called "window" it manages the view and adds some sliders and so on. The other one is called "SerialCom" and shall connect to the specified serial port in windows. As said this doesn't work. I put the code together of some samples and since I'm quiet new to JAVA and RXTX and I don't quiet understand what is wrong with it. Can someone please help me out with this. Heres the "SerialCom" code:

package controlSurface;

import gnu.io.*;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.TooManyListenersException;

public class SerialCom implements SerialPortEventListener{
	
	Window window = null;
	
	CommPortIdentifier serialPortId;
	Enumeration enumComm;
	SerialPort serialPort;
	OutputStream outputStream;
	InputStream inputStream;
	Boolean serialPortGeoeffnet = false;
	int baudrate = 9600;
	int dataBits = SerialPort.DATABITS_8;
	int stopBits = SerialPort.STOPBITS_1;
	int parity = SerialPort.PARITY_NONE;
	String portName = "COM5";
	Boolean foundPort = false;
	
	public void searchForPorts()
    {
        enumComm = CommPortIdentifier.getPortIdentifiers();

        while (enumComm.hasMoreElements())
        {
            serialPortId = (CommPortIdentifier)enumComm.nextElement();

            //get only serial ports
            if (portName.contentEquals(serialPortId.getName()))
            {
            	window.setDebug(portName);
            	foundPort = true;
				break;
            }
        }
    }
	
	public void connect(){
		portName = "COM5";
		//window.setDebug(portName);
		if(foundPort != true){
			//window.setDebug("Port not found!\n");
		}else{
			try {
				serialPortId = CommPortIdentifier.getPortIdentifier(portName);
				serialPort = (SerialPort) serialPortId.open("Opening port.", 500);
				serialPort.setSerialPortParams(
					    baudrate,
					    dataBits,
					    stopBits,
					    parity);
				serialPort.setFlowControlMode(
				        SerialPort.FLOWCONTROL_NONE);
				outputStream = serialPort.getOutputStream();
				inputStream = serialPort.getInputStream();
			} catch (NoSuchPortException e1) {
				// TODO Auto-generated catch block
				window.setDebug(e1.toString());
			} catch (PortInUseException e) {
				// TODO Auto-generated catch block
				window.setDebug(e.toString());
			} catch (UnsupportedCommOperationException ex) {
				window.setDebug(ex.toString());;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				window.setDebug(e.toString());
			}
		}
		
	}
	public void disconnect() {
        if (serialPort != null) {
            try {
                // close the i/o streams.
                outputStream.close();
                inputStream.close();
            } catch (IOException ex) {
                // don't care
            }
            // Close the port.
            serialPort.close();
            serialPort = null;
        }
    }
	//Possibly unnecessary
	public InputStream getSerialInputStream() {
        return inputStream;
    }
 
    public OutputStream getSerialOutputStream() {
        return outputStream;
    }
    
    public void initListener()
    {
        try
        {
            serialPort.addEventListener(this);
            serialPort.notifyOnDataAvailable(true);
        }
        catch (TooManyListenersException e)
        {
           window.setDebug(e.toString());
        }
    }
    public void setLED(int r, int g, int b){
    	if(serialPortGeoeffnet == true){
	    	byte[] dataToSend = {(byte)r,(byte)g,(byte)b,(byte)0x0A};
			//remove spurious line endings from color bytes so the serial device doesn't get confused
			for (int i=0; i<dataToSend.length-1; i++){
				if (dataToSend[i] == 0x0A){
						dataToSend[i] = 0x0B;
				}
			}
	    	try {
				outputStream.write(dataToSend);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				window.setDebug(e.toString());
			}
    	}
    }
	@Override
	public void serialEvent(SerialPortEvent arg0) {
		// TODO Auto-generated method stub
		
	}

}

Thanks

Life is too short to wade through Java code ... :slight_smile: (I use JRuby).

I don't see the code that uses your serial class.

There are a couple of common Gotchas ...

Don't disconnect the serial port between uses. Leave it open all the time you want to be able to communicate with the Arduino.

When the serial port is opened it causes the Arduino to reset and it takes the Arduino a few seconds before it is ready to receive or transmit. A good practice is to have the setup() function in the Arduino code send a short message and have the PC program (whatever language) wait until it receives that before getting down to business.

If you have no working Java code a good strategy is to write a simple Arduino sketch that can be controlled from the Arduino Serial Monitor (which proves that the sketch works) and then write a Java program that does exactly what you were doing with the Serial Monitor.

If you feel like switching to JRuby I will be happy to share code.

...R

Robin2:
Life is too short to wade through Java code ... :slight_smile: (I use JRuby).

I don't see the code that uses your serial class.

There are a couple of common Gotchas ...

Don't disconnect the serial port between uses. Leave it open all the time you want to be able to communicate with the Arduino.

When the serial port is opened it causes the Arduino to reset and it takes the Arduino a few seconds before it is ready to receive or transmit. A good practice is to have the setup() function in the Arduino code send a short message and have the PC program (whatever language) wait until it receives that before getting down to business.

If you have no working Java code a good strategy is to write a simple Arduino sketch that can be controlled from the Arduino Serial Monitor (which proves that the sketch works) and then write a Java program that does exactly what you were doing with the Serial Monitor.

If you feel like switching to JRuby I will be happy to share code.

...R

Okay thank you, I will try again and see if it works. I have a Java application that can successfully conncet and send values. The sketch therefore works. The downside is that it's only working with Console input - why? It's a sample application that uses methods that are quiet unhandy to be controlled by a GUI.

I would love to see some sample code that is explained stepp by step than rather finding only finished classes that are nearly impossible to change. If you have any good documentation on that, I would love it....

package controlSurface;

import gnu.io.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Enumeration;
//import java.util.TooManyListenersException;

//import OeffnenUndSenden.serialPortEventListener;



public class SerialTest implements Runnable {
	int r = 0;
	int g = 0;
	int b = 0;

	public static void main(String[] args)
	{
		Runnable runnable = new SerialTest();
		new Thread(runnable).start();
		System.out.println("main finished");
	}	

	CommPortIdentifier serialPortId;
	Enumeration enumComm;
	SerialPort serialPort;
	OutputStream outputStream;
	// InputStream inputStream;
	Boolean serialPortGeoeffnet = false;

	int baudrate = 9600;
	int dataBits = SerialPort.DATABITS_8;
	int stopBits = SerialPort.STOPBITS_1;
	int parity = SerialPort.PARITY_NONE;
	String portName = "COM5";
	
	int secondsRuntime = 1;

	public SerialTest()
	{
		//System.out.println("Konstruktor: EinfachSenden");
	}
	
    public void run()
    {
        Integer secondsRemaining = secondsRuntime;
        if (oeffneSerialPort(portName) != true)
        	return;
        
	while (secondsRemaining > 0) {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.print("Enter R:");
        try{
            r = Integer.parseInt(br.readLine());
            if(r >255){
    			schliesseSerialPort();
    		}
        }catch(NumberFormatException | IOException nfe){
            System.err.println("Invalid Format!");
        }

        System.out.print("Enter G:");
        try{
            g = Integer.parseInt(br.readLine());
        }catch(NumberFormatException | IOException nfe){
            System.err.println("Invalid Format!");
        }
        
        System.out.print("Enter B:");
        try{
            b = Integer.parseInt(br.readLine());
        }catch(NumberFormatException | IOException nfe){
            System.err.println("Invalid Format!");
        }
		sendeSerialPort(r,g,b);
		
	}
}
    
	boolean oeffneSerialPort(String portName)
	{
		Boolean foundPort = false;
		if (serialPortGeoeffnet != false) {
			System.out.println("Serialport bereits geöffnet");
			return false;
		}
		System.out.println("Öffne Serialport");
		enumComm = CommPortIdentifier.getPortIdentifiers();
		while(enumComm.hasMoreElements()) {
			serialPortId = (CommPortIdentifier) enumComm.nextElement();
			if (portName.contentEquals(serialPortId.getName())) {
				foundPort = true;
				break;
			}
		}
		if (foundPort != true) {
			System.out.println("Serialport nicht gefunden: " + portName);
			return false;
		}
		try {
			serialPort = (SerialPort) serialPortId.open("Öffnen und Senden", 500);
		} catch (PortInUseException e) {
			System.out.println("Port belegt");
		}
		try {
			outputStream = serialPort.getOutputStream();
		} catch (IOException e) {
			System.out.println("Keinen Zugriff auf OutputStream");
		}
		try {
			serialPort.setSerialPortParams(baudrate, dataBits, stopBits, parity);
		} catch(UnsupportedCommOperationException e) {
			System.out.println("Konnte Schnittstellen-Paramter nicht setzen");
		}
		
		serialPortGeoeffnet = true;
		return true;
	}

	void schliesseSerialPort()
	{
		if ( serialPortGeoeffnet == true) {
			System.out.println("Schließe Serialport");
			serialPort.close();
			serialPortGeoeffnet = false;
		} else {
			System.out.println("Serialport bereits geschlossen");
		}
	}
	
	void sendeSerialPort(int r, int g, int b)
	{
		byte[] dataToSend = {(byte)r,(byte)g,(byte)b,(byte)0x0A};
		for (int i=0; i<dataToSend.length-1; i++){
			if (dataToSend[i] == 0x0A){
					dataToSend[i] = 0x0B;
			}
		}
		if (serialPortGeoeffnet != true)
			return;
		try {
			outputStream.write(dataToSend);
		} catch (IOException e) {
			System.out.println("Fehler beim Senden");
		}
	}
}

binux:
I would love to see some sample code that is explained stepp by step than rather finding only finished classes that are nearly impossible to change. If you have any good documentation on that, I would love it....

Like I said earlier, I can show you JRuby (which uses the JVM and RXTX) but not Java.

I don't know if the Python code in this Thread might help. The JRuby equivalent is in there as well.

I have a Java application that can successfully conncet and send values. The sketch therefore works. The downside is that it's only working with Console input - why? It's a sample application that uses methods that are quiet unhandy to be controlled by a GUI.

I don't really understand this. What do you mean by it's only working with Console input? And what do you mean be "quite unhandy to be controlled by a GUI?

Maybe you can describe in English the steps that your Java program takes when communicatiing with the Arduino - how it uses the serial class.

...R

I haven't read your code. But if you aren't interested in write java classes to connect Arduino with a serial connection but just to use a ready class, you can use my library.

As far as I am concerned, RXTX doesn't actually work.

Processing is java and connects to serial pretty easily.
You can check out their forum and ask for a pure java solution.

Ardulink:
I haven't read your code. But if you aren't interested in write java classes to connect Arduino with a serial connection but just to use a ready class, you can use my library.
http://www.ardulink.org/

I know your programm. I'm a bit overwhelmed of all your java classes. Whichof them I need that I cann sucessfully conncet and send/receive data?

mistergreen:
Processing is java and connects to serial pretty easily.
You can check out their forum and ask for a pure java solution.

Which forum you suggest?

michinyon:
As far as I am concerned, RXTX doesn't actually work.

Why we have it then? :fearful:

michinyon:
As far as I am concerned, RXTX doesn't actually work.

I have had no problem using RXTX with JRuby.

Recently I have changed to JSSC as the support for RXTX seems to have died. I think JSSC is a bit easier to use - and it comes with its own documentation.

...R

Yes, I know. There are a lot of classes in my library and no time to explain how they works. However there is just a central class. The Link class. This is an "hello word" program that should turn on a led on PIN 13.

		Link link = Link.getDefaultInstance();
		link.connect("COM19"); // If you are on windows and Arduino is connected in this port. See getPortList() method
		link.sendPowerPinSwitch(13, IProtocol.HIGH);

You can see Javadoc here: Ardulink

Ardulink:
Yes, I know. There are a lot of classes in my library and no time to explain how they works. However there is just a central class. The Link class. This is an "hello word" program that should turn on a led on PIN 13.

		Link link = Link.getDefaultInstance();
	link.connect("COM19"); // If you are on windows and Arduino is connected in this port. See getPortList() method
	link.sendPowerPinSwitch(13, IProtocol.HIGH);



You can see Javadoc here: http://www.ardulink.org/javadoc/index.html

Can you point me out how to use your ardulink src in my own application the best way? In your doc I saw that ardulink either sends string or int[] -- I want to send byte[]. Where do I have to modify your src?

Robin2:

michinyon:
As far as I am concerned, RXTX doesn't actually work.

I have had no problem using RXTX with JRuby.

Recently I have changed to JSSC as the support for RXTX seems to have died. I think JSSC is a bit easier to use - and it comes with its own documentation.

...R

You have an example how to implent that lib in eclipse? Do i have to compile the dlls my own?

binux:
Which forum you suggest?

http://forum.processing.org/two/categories/hardware-other-languages

When you use an int[] array, Ardulink sends just the byte[] and use 255 as message divider.

But even if you can use directly Link.writeSerial(int numBytes, int[] message), I suggest to use a Link.sendXXX method. Because delegation to protocol used. You can use the preinstalled ALProtocol (that is a textual protocol) or build and install a protocol you like. You could even develop a class that implements Firmata protocol.

See Link.createInstance(String linkName, String protocolName) and org.zu.ardulink.protocol.ProtocolHandler class.

binux:
You have an example how to implent that lib [JSSC} in eclipse? Do i have to compile the dlls my own?

I don't know. I don't use Eclipse or Windows. There is a lot of info on the JSSC website

I think everything is included in the JAR even for windows.

...R