Communication Arduino + Java - help me!!!

Hi guys, i'm communicating Arduino with Java by serial.

I can write something in java and read in Arduino, but when i do the opposite a strange error happens: I need to open the serial monitor and then read in java. The problem is that I need to send something when I press a button and it is not possible to open the serial monitor while the program ( java ) is running . Why it's happening?

My Arduino is Leonardo.

My Arduino Code:

int ledPin =  7;
int btn = 2;
int dado; 
String palavra;

void setup(){
  Serial.begin(9600);//frequência da porta serial
   pinMode(ledPin,OUTPUT); 
    pinMode(btn,INPUT);
}
 
void loop(){
  if(Serial.available() > 0){ 
      dado = Serial.read();
      palavra=palavra+dado;
      switch(dado){
        case 'a':
           digitalWrite(ledPin,HIGH); 
        break;
        case 'b':
           digitalWrite(ledPin,LOW); 
         break;
    }
  }
  
  //if (digitalRead(btn)==HIGH){
  Serial.write("oi");
 // }
}

My java code:

package nulltest;

// derived from SUN's examples in the javax.comm package
import java.io.*;
import java.util.*;
//import javax.comm.*; // for SUN's serial/parallel port libraries
import gnu.io.*; // for rxtxSerial library

public class nulltest implements Runnable, SerialPortEventListener {
  static CommPortIdentifier portId;
  static CommPortIdentifier saveportId;
  static Enumeration        portList;
  InputStream           inputStream;
  SerialPort           serialPort;
  Thread           readThread;

  static String        messageString = "a";
  static OutputStream      outputStream;
  static boolean        outputBufferEmptyFlag = false;

  public static void main(String[] args) {
     boolean           portFound = false;
     String           defaultPort;
     
     // determine the name of the serial port on several operating systems
     String osname = System.getProperty("os.name","").toLowerCase();
     if ( osname.startsWith("windows") ) {
        // windows
        defaultPort = "COM7";
     } else if (osname.startsWith("linux")) {
        // linux
       defaultPort = "/dev/ttyUSB0";
     } else if ( osname.startsWith("mac") ) {
        // mac
        defaultPort = "????";
     } else {
        System.out.println("Sorry, your operating system is not supported");
        return;
     }
         
     if (args.length > 0) {
        defaultPort = args[0];
     } 

     System.out.println("Set default port to "+defaultPort);
     
           // parse ports and if the default port is found, initialized the reader
     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;
              // init reader thread
              nulltest reader = new nulltest();
           } 
        } 
        
     } 
     if (!portFound) {
        System.out.println("port " + defaultPort + " not found.");
     } 
     
  } 

  public void initwritetoport() {
     // initwritetoport() assumes that the port has already been opened and
     //    initialized by "public nulltest()"

     try {
        // get the outputstream
        outputStream = serialPort.getOutputStream();
     } catch (IOException e) {}

//      try {
//         // activate the OUTPUT_BUFFER_EMPTY notifier
//         serialPort.notifyOnOutputEmpty(true);
//      } catch (Exception e) {
//         System.out.println("Error setting event notification");
//         System.out.println(e.toString());
//         System.exit(-1);
//      }
     
  }

  public void writetoport() {
     System.out.println("Writing \""+messageString+"\" to "+serialPort.getName());
     try {
        // write string to serial port
        outputStream.write(messageString.getBytes());
     } catch (IOException e) {}
  }

  public nulltest() {
     // initalize serial port
     try {
        serialPort = (SerialPort) portId.open("SimpleReadApp", 2000);
     } catch (PortInUseException e) {}
  
     try {
        inputStream = serialPort.getInputStream();
     } catch (IOException e) {}
  
     try {
        serialPort.addEventListener(this);
     } catch (TooManyListenersException e) {}
     
     // activate the DATA_AVAILABLE notifier
     serialPort.notifyOnDataAvailable(true);
  
     try {
        // set port parameters
        serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, 
                    SerialPort.STOPBITS_1, 
                    SerialPort.PARITY_NONE);
     } catch (UnsupportedCommOperationException e) {}
     
     // start the read thread
     readThread = new Thread(this);
     readThread.start();
     
  }

  public void run() {
     // first thing in the thread, we initialize the write operation
     initwritetoport();
     try {
        while (true) {
           // write string to port, the serialEvent will read it
           writetoport();
           Thread.sleep(1000);
        }
     } catch (InterruptedException 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:
        // we get here if data has been received
        byte[] readBuffer = new byte[20];
        try {
           // read data
           while (inputStream.available() > 0) {
              int numBytes = inputStream.read(readBuffer);
           } 
           // print data
           String result  = new String(readBuffer);
           System.out.println(result);
        } catch (IOException e) {}
  
        break;
     }
  } 

}

Thanks, help me if possible.

The problem is that I need to send something when I press a button and it is not possible to open the serial monitor while the program ( java ) is running . Why it's happening?

Generally speaking on windows machines, only one application can have a specific comport open at a time.

But why the serial monitor needs to be open for the java read the information?

tabs:
But why the serial monitor needs to be open for the java read the information?

Because there is something wrong with your code.

There is no problem establishing bi-directional communication between a Java program and an Arduino.

I'm not good with Java (in the past I used JRuby) but a common problem is not allowing for the fact that the Arduino resets when the PC program opens the serial port. Your PC code should open the serial port and wait for the Arduino to reset and then keep the serial port open.

This Python-Arduino demo illustrates how it can be done. There is a also a JRuby version.

...R

My Arduino is Leonardo.

For the Leonardo, the DTREnable flag needs to be set to true (the default is false) when setting up the serial port properties.

I missed the fact that you are using a Leonardo.

To force a reset of a Leonardo you need to open the serial port at 1200 baud and close it again. Then open it at your desired rate.

...R