Trying to send data to Arduino in java over serial

I've tried various ways with sending data to the arduino over the serial line in Java. The current state of my code is as such...

import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.UnsupportedCommOperationException;

import gnu.io.SerialPort;

import java.io.IOException;
import java.io.InputStream;

import java.io.OutputStream; 

public class UploadThis {

      /**
       * @param args
       */
      
      static AvrdudeUploader blinkUp = new AvrdudeUploader();

       static InputStream input;
       static OutputStream output;
       
      static //The args are going to come with three commands
      //COMMAND BUILD-DIRECTORY HEX-NAME
      //There's two commands - uploadHex, uploadSettings
      UploadThis uploadThis = new UploadThis();
      public static void main(String[] args) {
            
            if(new String(args[0]).equals("justWrite"))
            {
                  System.out.println("Using port: " + "COM3");

                  CommPortIdentifier portId;
                  try {
                        portId = CommPortIdentifier.getPortIdentifier(
                                    "COM3");
                  

                        SerialPort port;
                        try {
                              port = (SerialPort)portId.open("serial madness", 4000);
                        
                          try {
                                    input = port.getInputStream();
                              
                                output = port.getOutputStream();
                                try {
                                      System.out.println("1");
                                          port.setSerialPortParams(
                                                      9600,
                                                      SerialPort.DATABITS_8,
                                                      SerialPort.STOPBITS_1,
                                                      SerialPort.PARITY_NONE);

                                          output.write(12 & 0xff);System.out.println("2");
                                          
                                          output.flush(); System.out.println("3");
                                          output.close(); output = null; System.out.println("4");
                                          input.close(); input = null; System.out.println("5");
                                          port.close(); port = null; System.out.println("6");
                                          
                                } catch (UnsupportedCommOperationException e) {
                                          // TODO Auto-generated catch block
                                          e.printStackTrace();
                                    }
                          } catch (IOException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                              }
                        } catch (PortInUseException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                        }
                  } catch (NoSuchPortException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                  }

It doesn't seem to be sending the data to the arduino. It also doesn't trigger any exceptions indicating...

-The port exists
-The port isn't in use
-And it isn't an unsupported comm operation

I've also verified it's the correct port because I checked in the Arduino IDE. I also checked that the debug rate was 9600. I also got the other values directly from Preferences.txt.

I originally tried setting it up using the original Serial class, but it also didn't seem to work, so I thought I'd try this one.

The arduino is programmed to capture serial data and write it in an EEPROM buffer. It seems to capture things sent from the Arduino IDE just fine and it appears the Arduino IDE simply uses the string version of Serial.write() - my efforts of trying to send a "1" string manually using the string form of Serial.write() seemed to be met with failure.

Any ideas?

Here's the original code I used when trying to borrow directly from the Serial class and using its string version of the write() function.

import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.UnsupportedCommOperationException;

import gnu.io.SerialPort;

import java.io.IOException;
import java.io.InputStream;

import java.io.OutputStream; 

public class UploadThis {

      /**
       * @param args
       */
      
      static AvrdudeUploader blinkUp = new AvrdudeUploader();

       static InputStream input;
       static OutputStream output;
       
      static //The args are going to come with three commands
      //COMMAND BUILD-DIRECTORY HEX-NAME
      //There's two commands - uploadHex, uploadSettings
      UploadThis uploadThis = new UploadThis();
      public static void main(String[] args) {
            
            if(new String(args[0]).equals("justWrite"))
            {
                  
                  Serial port;
                  try {
                        System.out.println("We're here!");
                        port = 
                        new Serial("COM3",9600,'N',8,Float.parseFloat("1"));
                        port.write("1");
                        try {
                              Thread.sleep(1000);
                        } catch (InterruptedException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                        }
                        port.dispose();
                  } catch (SerialException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                  }
                  
            }

I got the Serial port setup parameters directly from the Arduino program and here’s what it used:

“Port name: COM3 irate: 9600 iparity: N idatabits: 8 istopbits: 1.0”

Which is basically what I have.

I think I might be missing a crucial file somewhere since it seems my code is pretty functionally identical to the IDE’s code.

Just curious...

Are RXTXcomm.jar and rxtxSerial.dll where your app being developed can find them?

I think so. I pasted the rxtx files all over the place (Including where they belong, in the jre folder under bin and lib) and it seems to have the same problem.

Interestingly, I tried out the java program here that the original poster copied from javacomm's website and is apparently working for him: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1206094086

It's like the java programs all seem to work but somehow the arduino board isn't capturing the data, but yet it'll capture data originating from the arduino IDE's serial interface. So, this would seem to suggest some file is missing...

I think the next logical troubleshooting step would be to copy and paste the entire arduino distribution everywhere, and then if that works, it's only a matter of deletion deduction. :smiley:

Ok, just copied the program into various folders in the class-path and it didn't change anything. I modified Serial.java a little bit, so I'm now going to compare that with the original to determine if anything important might've been accidentally edited out.

http://alumni.media.mit.edu/~benres/simpleserial/

It seems this guy's Java serial port program works and he even includes source code and instructions on how to use it. That should be MUCH easier than following Arduino's source code.

It doesn't seem like the code is working with Eclipse so I decided to try to compile it manually. It turns out "javac" didn't register with command prompt and I found out I don't even have the JDK. Hahaha... I should get that on here.

EDIT: Ok, I installed the JDK and put it in the appropriate class. It doesn't seem even this library will work after I compiled it and executed it. Is there something that Java doesn't like about my computer? It turns out that Eclipse thought that the JavaComm libraries weren't installed and it seemed like JavaComm wasn't available to Windows Systems online. But, yet, that terminal program that came with SimpleSerial worked... Hmm. It seems java.comm was withdrawn so now only rxtx is available. Now I just to need to find a "simple serial" implementation of RxTx. ::slight_smile:

Ok, so I went about uninstalling all of my various Java directories and starting from scratch. I then plastered Arduino's rxtx dealios in the various folders and then followed special eclipse rxtx instructions I found on rxtx's wiki to include the rxtxcomm library. I then ran the "nulltest" program(Link aboe) which repeated the tranmission every second and it repeated about 6 times. I then checked the EEPROM and it apparently received the message twice. Ok, so somehow it's receiving the IDE's transmission perfectly and that Simple Serial program perfectly, but this program it's not. Methinks it has something to do with the program.

Anyways, it's good I'm finally getting somewhere! In this worst case scenario, I can imagine just repeating the transmission until I hear confirmation of the data being received. That'd be space-consuming, though!

EDIT: It seems to be pretty hit and miss now. Any recommendations on what kind of timing delays there should be in the arduino program and the transmission program? And, oh yeah, I can now use "Super simple"! I just simply replaced the javax.comm import library with gnu.io.*;

For some reason, the following piece of code seems to be 100% reliable in sending the data over.

       Thread.sleep(1500);
             
            outputStream.write("hh".getBytes());

            Thread.sleep(1000);

            nputStream.close();
            inputStream=null;
            
            outputStream.close();
            outputStream=null;
            
                serialPort.close();
                serialPort=null;
         //}

I've deleted the eclipse-autogenerated exception catching as it's distracting.

I tried decreasing the first of the two thread.sleep's to 1000 ms but it never worked - 1500 always works. I tried getting rid of the second thread.sleep before it closes the input and output ports, but that didn't work. So, as long as the transmission string is between these two sleep methods, it seems to work. Now, I have to wonder what kind of timing delays might be required between transmissions. I think it should be none as it all goes straight to the Serial buffer, right? I also wonder how the above two timing requirements might change as the transmission data increases.

On the arduino, there's a 1 ms delay between reading each bit in the Serial buffer. I don't know how long it takes the arduino to execute a write command but... hey! I think I know, there's two eeprom writes per serial thing (And those take somewhere between 3-4 ms). Give 1 ms for the other variables, that adds upto about 10 ms per byte (It's probably more like 15 ms, but I don't care that much about precision).

So, I'm going to guess that as the transmission data sizes increases, I might have to increase the bottom timing requirement to give it time to process the data before shutting down the outputStream and closing the port.

EDIT: Ok, I just added more transmitted strings in between the two sleeps and a timing delay wasn't required between them. For sufficiently long data, though, I suspect I'll need to increase the bottom.

Ok, I think I've now formed a pseudo theory.

Whenever I went to send information over the serial in the Arduino IDE, it had Serial set up as soon as I pressed the "serial button" and there was sufficient time between this "setup" and the pressing of the serial send button(writing to the serial port) that it always worked. Also, it didn't dispose of the serial port until I clicked on the "serial button" which was always at least a few seconds after I sent data over the serial, so there was an "inherent" timing delay just by my ordinary usage. The same idea behind the SimpleSerial success but my apparent compilation failure.

I've also noticed something strange. Whenever I made a serial connection, for some reason, it seemed like the arduino's global variables reset as if the program had resetted - this is one reason why I resorted to writing important global variables to the eeprom so I could actually keep a history of the captured serial data. I think that the arduino resets whenever a serial connection is made and I think that's why it requires at least a second before you can send data over as the program has to have time to set up. As far as the second timing delay, I think that might not actually be needed and flushing the output stream (OutputStream.flush()) might be sufficient (I think it forces the serial buffer to empty its data out over the serial line instead of waiting for the serial buffer to empty itself), but I haven't tested that out.

Anyways, it seems I have pretty generous delays to ensure almost 100% transmission success. Like, there's a 20 ms delay between each Serial.read() operation on the arduino.

Hi swbluto, I just started with arduino and I have problems sending data to the arduino within java (data reading is no problem).
I would like to send specific data or a command to the arduino within a java prog in order to have a measurement/regulation cycle.

Easy example in arduino software:

int ledPin = 13;             
void setup()
{
  pinMode(ledPin, OUTPUT);      
}

void loop()
{
  digitalWrite(ledPin, HIGH);   
  delay(1000);                  
  digitalWrite(ledPin, LOW);    
  delay(variable????);               
}

So far I understand...
But is it possible to load the program to the board and change the delay time for example later with a JAVA program? Or change High to low?

I want to measure the temperature and read the data with a Java appl. (thats no problem) then the java application calculates some stuff and decides to heat or cool for example.
How can I manage that a JAVA prog. gives the command to arduino to start the PMW at pin XY? do I have to create special variables in the arduino software? I´m a little bit confused...

Thank you very much for any ideas! Hondo