Interfacing Java and Arduino

Hello Group!

I am having an issue that I believe is simple to fix however I cannot wrap my head around it. I have a java program that connects to an arduino I can issue commands from the java program and the arduino responds accordingly. My issue is when the arduino starts up I believe it is sending a white space to the serial monitor and my java picks that up and is disrupts the program. Arduino code and Java code posted below. Thanks in advance!

void setup() {
//Start the serial port at 9600 baud rate.
Serial.begin(9600);
pinMode(13, OUTPUT);
}

//MAIN LOOP
void loop() {
//Assign the input value to a variable.
char input;

//Read in the characters being sent from Java.
input = Serial.read();

//Turn on the LED.
if(input == '1'){
digitalWrite(13, HIGH);
Serial.print("ON");
}

//Have the LED blink 10 times.
if(input == '2') {
for(int i = 0; i < 10; i++) {
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
delay(100);
Serial.print("OX");
}
//Serial.println("OX");
}

//Turn off the LED.
if(input == '3') {
digitalWrite(13, LOW);
Serial.print("OFF");
}
}

And posted below is the part of the java code that is used to invoke one of the commands to the arduino.

//Listener for the blink button.
		btnBlink.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnOn.setBackground(null);
				btnBlink.setBackground(Color.yellow);
				btnOff.setBackground(null);
				//Turns on the #13 pin LED and flashes it 10 times.
				if(comPort.isOpen() == true) {
					
					InputStream inPut = comPort.getInputStream();
					BufferedReader readBuffer = new BufferedReader(new InputStreamReader(inPut));
					//Send a 2 to the Arduino and update the user.
					System.out.println("STATUS: LED BLINKING!!");
					lblStatus.setText("Status: LED Blinking");
					outPut.flush();
					outPut.print("2");
					outPut.flush();
byte[] buffer = new byte[2];
  try {
    String message = "";
    
        int len = inPut.read(buffer);
        if (len > 0) {
            message = new String(buffer);
            System.out.println(message);
        }
		
        len = 0;
        String messages[];
        messages = message.split("\r\n");
        
            if (message.contains("OX") || message.contains("")) {
                btnBlink.setBackground(Color.yellow);
				outPut.flush();
            } else {
					System.out.println("ERROR!!");
		}
	

} catch (Exception ep) { ep.printStackTrace(); }

} else {
					//Update the status/console if the Arduino hasn't been connected.
					System.out.println("CONNECT ARDUINO");
					lblStatus.setText("Status: Connect Arduino");
				}
				
			}
			
		});

This is a java button that is used to make the LED blink. I've tried using flush and other means to remove the whitespace or something that is causing the arduino to throw.

I can't tell from your Java snippet when your program opens and closes the Serial port. It should open the serial port when it starts and keep it open until it is finished with the Arduino.

When a PC program opens the serial port it causes the Arduino to reset and the PC program must allow time for that before trying to communicate with the Arduino. In my Arduino programs I send a message from setup() such as Serial.println("Arduino is ready"); and my PC program waits to get that before communicating with the Arduino.

You can see how this works in this Python - Arduino demo

...R

Hello Robin,

Below is my java code that initiates connection to the Arduino:

//Listener for connect button.
		btnConnect.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				//Set up the values for the USB port.
				comPort = SerialPort.getCommPort(comPortName);
				comPort.setBaudRate(baudRate);
				btnConnect.setBackground(Color.green);
				btnDisconnect.setBackground(null);
				btnConnect.setText("Connected");
				btnOn.setEnabled(true);
				btnOff.setEnabled(true);
				btnBlink.setEnabled(true);
				btnExit.setEnabled(false);
				//If the port is not closed, open the USB port.
				if(comPort.isOpen() == false) {	
					try {
						//Open the USB port and initialize the PrintWriter.
						comPort.openPort();
						Thread.sleep(3000);
						outPut = new PrintWriter(comPort.getOutputStream());
						inPut = comPort.getInputStream();
					
					} 
					
					catch(Exception c){}
					
					//Update the console and status.
					System.out.println("CONNECTION TO ARDUINO SUCCESSFUL!!");
					lblStatus.setText("Status: Connected");
					
					
				} else {
					//If the port couldn't be opened print out to the console.
					System.out.println("ERROR OPENING PORT!!.");
					lblStatus.setText("Status: Opening USB failed");
				}
				
			}
		});

PilotinControl:
Below is my java code that initiates connection to the Arduino:

I'm only vaguely familiar with Java - it is something to avoid whenever possible.

The point I was trying to make had nothing to do with HOW you open the serial port. The issue is WHEN do you open it and WHEN do you close it. And what is the first thing you do after you open it.

...R

I open the port when the Connect button is pressed and the port is closed when the Disconnect button is pressed...in between it sits and waits for commands to be issued via button presses...button is pressed and as an acknowledgement Arduino sends back: ON/OFF to the serial port and displayed on the java screen. This works fine...its the opening that is messed up. No matter which button is pressed an "empty space" comes before the ON or OFF....if it is pressed again....there are no spaces before the ON or OFF....its like there is a white space that gets sent to the buffer.

Can you print that "white space" in hex? Should be x20. If otherwise, it's not a space.

Paul

So I should put this line Serial.print(x, HEX); under the Serial.begin(); line? and that will show me the hex?

PilotinControl:
So I should put this line Serial.print(x, HEX); under the Serial.begin(); line? and that will show me the hex?

I thought you were seeing it in your JAVA program!

Paul

Yes I am seeing the empty line printed from the arduino into the java console

PilotinControl:
This works fine...its the opening that is messed up.

Have you tried my suggestion of getting the Arduno to send a start-up message?

...R

PilotinControl:
Yes I am seeing the empty line printed from the arduino into the java console

print the hex value of that character

Try trimming the received text i.e. your input, that will remove the first space and any double spaces.

ELSE

an easy fix that i would use for receiving just ascii numbers would be to write

char e = Serial.read();

if (e >= 48 && e <= 57) { // get just numbers - same as; if (e >= '0' && e <= '9') {
Serial.print(F("we received the number: "));
Serial.println(char(e));
}

@Robin2 - Yes. I added this line: Serial.println("TEST MESSAGE"); and in the java console it only printed the first 2 characters "TE" when the Button was pressed. Not what is expected via the code. When the button is pressed the second two characters are printed to the console "ST". So its only capturing 2 of the characters and not flushing the buffer.

an easy fix that i would use for receiving just ascii numbers would be to write

char e = Serial.read();

if (e >= 48 && e <= 57) { // get just numbers
Serial.print(F("we received the number: "));
Serial.println(char(e));
}

An even more understandable version of the code:

char e = Serial.read();

if (e >= '0' && e <= '9') { // get just numbers
    Serial.print(F("we received the number: "));
    Serial.println(e); // Useless cast of char to char removed
}

@PaulS - receiving the numbers from the Java program to the Arduino to invoke the commands is not the issue....its the Arduino sending out on startup invisible data...head scratching.

PilotinControl:
@PaulS - receiving the numbers from the Java program to the Arduino to invoke the commands is not the issue....its the Arduino sending out on startup invisible data...head scratching.

make them visible by printing them as hex codes

PilotinControl:
@PaulS - receiving the numbers from the Java program to the Arduino to invoke the commands is not the issue....its the Arduino sending out on startup invisible data...head scratching.

No reason to scratch your head. Simple enough explanation: Every time JAVA opens the serial file, the Arduino is reset and starts over. The PC/JAVA interprets the electronic connection to the Arduino going away and coming back as something. If you are not willing to identify that something in HEX, that bogus character, then there is no help.

Paul

PilotinControl:
@Robin2 - Yes. I added this line: Serial.println("TEST MESSAGE"); and in the java console it only printed the first 2 characters "TE" when the Button was pressed. Not what is expected via the code. When the button is pressed the second two characters are printed to the console "ST". So its only capturing 2 of the characters and not flushing the buffer.

Then you need to modify your Java program so it does nothing until it has received "TEST MESSAGE". Have you studied my Python example?

PilotinControl:
.its the Arduino sending out on startup invisible data...head scratching.

The Arduino is not sending mystical data. What is probably happening is that the Arduino had started, and was sending data, before your Java program opened the serial port and what you are seeing is the remnants of the data that had already been sent by the Arduino.

If, as I have suggested, your Java program waits to get the startup message (your "TEST MESSAGE") then it will have discarded all those irrelevant characters.

...R

Lets look at your problem from the JAVA end. A quick Google search found there are a multitude of error conditions you can check for after doing a serial data read. Looking at you JAVA code in your first post, you are not checking for any errors. The byte you are processing most likely has a error condition you are ignoring.

Paul

PilotinControl:
@Robin2 - Yes. I added this line: Serial.println("TEST MESSAGE"); and in the java console it only printed the first 2 characters "TE" when the Button was pressed. Not what is expected via the code. When the button is pressed the second two characters are printed to the console "ST". So its only capturing 2 of the characters and not flushing the buffer.

you use BufferedReader which reads all available bytes into a memory buffer.
then you read 2 bytes from it into a buffer with length 2.