Serial data RXTX not the same as Arduino Serial Monitor

So I'm trying to write a Java programm that communicates with a arduino uno and turn on or off an led.

Arduino Code:

const short bt0 = 4; //Raum Knopf
const short bt1 = 5; //Haus Knopf
const short bt2 = 6; //fn0
const short bt3 = 7; //fn1
const short led = 3; //Raum Licht

//Status der Bauteile (Knopf gedrückt ode nicht; LED an oder nicht?)
short bt0std = LOW;
short bt1std = LOW;
short bt2std = LOW;
short bt3std = LOW;
short ledstd = LOW;

String incomingString;
short tmp; //tmp var for comparisons
boolean changesMade = false;
//int msgId = 0;

boolean receiveData() {
  if (Serial.available() > 0) {
    incomingString = Serial.readString();
    incomingString = incomingString.substring(0, incomingString.length() - 1);
    Serial.println(incomingString);
    return true;
  }
  return false;
}

//Funktion zum umschalten der LED
void toggleLED() {
  if (ledstd == LOW) {
    digitalWrite(led, HIGH);
    ledstd = HIGH;
    sendData("lhon"); 
  } else {
    digitalWrite(led, LOW);
    ledstd = LOW;
    sendData("lhof");
  }
}
//Funktion zum Senden von Daten (z.Z über den Seriellen Port)
void sendData(String data) {
  String outgoingString = "src-id:1dst-id:0msg-id:1";
  //outgoingString += msgId++;
  outgoingString += "msg:";
  outgoingString += data;
  Serial.println(outgoingString);
}

void setup() {
  Serial.begin(9600); //Serielle verbindung starten
  
  //Funktion der pins festlegen
  pinMode(bt0, INPUT); 
  pinMode(bt1, INPUT);
  pinMode(bt2, INPUT);
  pinMode(bt3, INPUT);
  pinMode(led, OUTPUT);
  
}


void loop() {
  
  if (receiveData()) {
    if (incomingString == "on") {
      if (ledstd == LOW) {
        toggleLED(); 
      } else {
        sendData("lhon");
      }
    } else if (incomingString == "off") {
      if (ledstd == HIGH) {
        toggleLED(); 
      } else {
        sendData("lhof");
      }
    }
  }
  
  changesMade = false;
  
  tmp = digitalRead(bt0);
  if (tmp != bt0std) {
     if (tmp == HIGH) {
       bt0std = HIGH;
       toggleLED();
       changesMade = true;
     } else {
       bt0std = LOW;
       changesMade = true;
     }
  }
  
  tmp = digitalRead(bt1);
  if (tmp != bt1std) {
     if (tmp == HIGH) {
       sendData("home");
       bt1std = HIGH;
       changesMade = true;
     } else {
       bt1std = LOW;
       changesMade = true;
     }
  }
  
  tmp = digitalRead(bt2);
  if (tmp != bt2std) {
     if (tmp == HIGH) {
       sendData("fn0");
       bt2std = HIGH;
       changesMade = true;
     } else {
       bt2std = LOW;
       changesMade = true;
     }
  }
  
  tmp = digitalRead(bt3);
  if (tmp != bt3std) {
     if (tmp == HIGH) {
       sendData("fn1");
       bt3std = HIGH;
       changesMade = true;
     } else {
       bt3std = LOW;
       changesMade = true;
     }
  }
  
  if (changesMade) delay(100);
}

Java code:

import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;

import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class TwoWaySerialComm
{
    public TwoWaySerialComm()
    {
        super();
    }
    
    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_1,SerialPort.PARITY_NONE);
                
                InputStream in = serialPort.getInputStream();
                OutputStream out = serialPort.getOutputStream();
                
                //byte[] b = String.format("on%n").getBytes();
                //out.write(b);
                
                (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;
        
        public SerialWriter ( OutputStream out )
        {
            this.out = out;
        }
       
        public void run ()
        {
            try
            {                
                int c = 0;
                while ( ( c = System.in.read()) > -1 )
                {
                    this.out.write(c);
                }                
            }
            catch ( IOException e )
            {
                e.printStackTrace();
            }            
        }
    }
    
    public static void main ( String[] args )
    {
        try
        {
            (new TwoWaySerialComm()).connect("COM3");
        }
        catch ( Exception e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

It works when I send the data with the arduino serial monitor, but not when I send the commands via my Java programm. The command I am trying so send is "on".

You've commented out the line that writes "on"...

I don't see any calls to flush() so I'd worry nothing was happening.

You trying to use your Java program and the Serial Monitor at the same time?

If you are, that's not gonna work, because only one program can have access to the serial port at a give time. In that case, close the Serial Monitor and then try to use your program.

Besides, the lines

//byte[] b = String.format("on%n").getBytes(); //out.write(b);

are commented out in your JAva program.

Thank you for the fast replys. Sorry for not being clear about what I am doing. I tested a lot of diffrent Stuff in the Java code, so there are some comments left over that did not work. I'm also not using the Serial Monitor and my programm at the same time, I can't even do that, becuase if I try I get an error. I'm trying to send the "on" command typing it into the console and then hitting ENTER, I confirmed that it was send with a programm that replied with just letting the arduino just repeat the message.

I hope it's now more clear waht I have done.

Does your Java program wait for the Arduino to reset after it opens the serial port? And does it keep the serial port open until it has completely finished with the Arduino?

Look at how communication is managed in this Python demo. There is also an example using JRuby which uses the JVM.

You may find that the newer JSSC works better than RxTx

...R

Does your Java program wait for the Arduino to reset after it opens the serial port?

I don't know what you mean. My Java Programm is not resetting the Arduino. I did not write the Java code myself I used an example from the rxtx wiki. But I know that my Arduino is recieving and can send Data over the Serial port!! I testet that with a programm that just send messages back to PC, I tested it with the Arduino Serial Monitor and the Java Application.

And does it keep the serial port open until it has completely finished with the Arduino?

The Java Programm runs forever, SerialReader and SerialWriter are both runnables, that means they are independent threads and that everything in the run() functions runs forever.

I have to stop the programm mannualy, if I don't do that I can not start another test because the Serial Port is blocked.

usbpc102: I don't know what you mean. My Java Programm is not resetting the Arduino.

Oh but it is. Any time you open a Serial line to the Arduino it forces a reset. There are modifications you can make to the board to prevent this.

Oh, I did not learn that, but my Programm just runs forever, so it is not a Problem. But I have an Idea let me test that...

...idea did not work. :(

I moved this

//byte[] b = String.format("on%n").getBytes();
               //out.write(b);

into the serial writer class, to send it over and over again, the class now looks like that:

public static class SerialWriter implements Runnable 
    {
        OutputStream out;
        
        public SerialWriter ( OutputStream out )
        {
            this.out = out;
        }
       
        public void run ()
        {
            try
            {      
              
              byte[] b = String.format("on%n").getBytes();
                this.out.write(b);
                this.out.flush();
                int c = 0;
                while ( ( c = System.in.read()) > -1 )
                {
                    this.out.write(c);
                }                
            }
            catch ( IOException e )
            {
                e.printStackTrace();
            }            
        }
    }
while ( ( c = System.in.read()) > -1 )

I may be way off here, but do you want to use System.in there or should you be using your SerialReader?

I think you are way off, the programm is reading the input from my keyboard that I want to send to the Arduino. So that is just cheking that I wrote something and if I did it sends it over the Serialport to the Arduino.

Okay I finnaly got it working. The Problem was the %n that I used as an new Line Indicator, but for some reason the Arduino did not like it just replaced it with \n worked. After that I just removed incomingString = incomingString.substring(0, incomingString.length() - 1); from the Arduino code it works without sending a new line symbol. Now sending the commands via the arduino serial monitor, because that adds a new line indicator, but i don't mind that.

usbpc102: Okay I finnaly got it working.

I'm glad you have it working. It must be that, accidentally or otherwise, your Java program deals properly (or at least adequately) with the Arduino's idiosyncracies.

A program that runs continuously could also be opening and closing the serial port continuously - that is common practice on PC programs, but it is not suitable with an Arduino.

...R