Arduino and Java communication help can Write but not Read

Hi,

I have been trying to work this out for hours now and getting no where so im hoping some one can help! I have jumped through all the hoops of installing the RXTX .jar etc and have RXTX 2.1-7 running on my macbook pro (mavericks). This is working through the eclipse IDE.

I have my Arduino UNO connected via usb cable, and can make it turn an LED on when it sees a specific character. I can't seem to get the Arduino to send a conformation message back to my laptop and appear in my java terminal window. The RXTX wiki has been down since ive started this project so ive had to use help from else where.

This is the java code

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;

/**
 * @author ericjbruno
 */
public class SerialTest implements SerialPortEventListener {
    SerialPort serialPort = null;

    private static final String PORT_NAMES[] = { 
        "/dev/tty.usbmodem", // Mac OS X

    };
    
    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
                //
                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
            serialPort.addEventListener(this);
            serialPort.notifyOnDataAvailable(true);

            // Give the Arduino some time
            try { Thread.sleep(2000); } catch (InterruptedException ie) {}
            
            return true;
        }
        catch ( Exception e ) { 
            e.printStackTrace();
        }
        return false;
    }
    
    private void sendData(String data) {
        try {
            System.out.println("Sending data: '" + data +"'");
            
            // open the streams and send the "y" character
            output = serialPort.getOutputStream();
            output.write( data.getBytes() );
        } 
        catch (Exception e) {
            System.err.println(e.toString());
            System.exit(0);
        }
    }

    //
    // This should be called when you stop using the port
    //
    public synchronized void close() {
        if ( serialPort != null ) {
            serialPort.removeEventListener();
            serialPort.close();
        }
    }

    //
    // Handle serial port event
    //
    public synchronized void serialEvent(SerialPortEvent oEvent) {
        //System.out.println("Event received: " + oEvent.toString());
        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.err.println(e.toString());
        }
    }

   
    public static void main(String[] args) throws Exception {
        SerialTest test = new SerialTest();
        if ( test.initialize() ) {
            test.sendData("y");
           
            
            test.close();
        }

        // Wait 5 seconds then shutdown
        try { Thread.sleep(2000); } catch (InterruptedException ie) {}
    }
}

This is the console output when run:

Stable Library
=========================================
Native lib Version = RXTX-2.1-7
Java lib Version   = RXTX-2.1-7
Trying:
   port/dev/tty.Bluetooth-Incoming-Port
   port/dev/cu.Bluetooth-Incoming-Port
   port/dev/tty.Bluetooth-Modem
   port/dev/cu.Bluetooth-Modem
   port/dev/tty.laurensipod-WirelessiAP
   port/dev/cu.laurensipod-WirelessiAP
   port/dev/tty.usbmodemfd121
Connected on port/dev/tty.usbmodemfd121
Sending data: 'y'
Experimental:  JNI_OnLoad called.

And here is the code on my uno.

int led =6; // LED connected to digital pin 13

int recv = 0; // byte received on the serial port

void setup() {
  // initialize onboard LED (led), Powertail (pts) and serial port
  pinMode(led, OUTPUT);

  Serial.begin(9600);
}

void loop()
{
  // if serial port is available, read incoming bytes
  if (Serial.available() > 0) {
    recv = Serial.read();

    // if 'y' (decimal 121) is received, turn LED/Powertail on
    // anything other than 121 is received, turn LED/Powertail off
    if (recv == 121){
      digitalWrite(led, HIGH);

    } else {
      digitalWrite(led, LOW);
     
    }
     
    // confirm values received in serial monitor window
    Serial.print("--Arduino received: ");
    Serial.write("recv /n");
    
}
}

Ive tried both serial print and serial write but neither the java event listener seems to notice.

Any ideas

Thanks Paul :)

I use JRuby (which uses the JVM and RXTX) to communicate between my PC and my Arduinos. I know a little about Java programming.

I can't relate your code to the symptoms you describe.

Can you describe step by step what is supposed to happen when you run the Java program.

And am I correct to assume the Arduino is running all the time waiting for the PC to do something?

...R

I had nothing but headaches trying to get rxtx to work in my java application. When I switched to https://code.google.com/p/java-simple-serial-connector/ things worked without hassle.

Here is some code that I wrote a while back. Ignore the JSON stuff - JSON was used as the protocol between the Arduino and the PC, but the rest of the code may be useful. https://github.com/MrYsLab/CodeShield_Scratch_Extension/blob/master/javaFiles/src/codeShieldForScratch/SerialManager.java

The Arduino code I used is here: https://github.com/MrYsLab/CodeShield_Scratch_Extension/blob/master/arduinoFiles/CodeShieldJSONClient/CodeShieldJSONClient.ino

The read_char function will be most useful and again ignore the JSON stuff.

I hope this helps.

        SerialTest test = new SerialTest();
        if ( test.initialize() ) {
            test.sendData("y");
           
            
            test.close();

Send some data. Close the port (resetting the Arduino). Expect a reply on that port. What's wrong with this picture.

I think the error is in arduino code. Check this line:

Serial.write("recv /n");

may be

Serial.write("recv ****n");

or even better

Serial.println("recv ");

In your java code you read an whole line with input.readLine(); maybe it blocks until a \n arrives. However you could use my java open source library www.ardulink.org to have a rapid development with java.

I'll put my money on @PaulS's discovery. Full marks for ploughing through tedious Java code.

...R